【hibernate】赵雅智_hibernate 2 (基本概念和CURD)
基本概念和CURD
- 开发流程
- 由Domain object -> mapping->db。(官方推荐)
- 由DB开始,用工具生成mapping和Domain object。(使用较多)
- 由映射文件开始。
一把情况下使用第二种
第二种从数据库开始,先做数据库然后映射文件
- Domain Object限制
- 默认的构造方法(必须的)。
- 有无意义的标示符id(主键)(可选)
- 非final的,对懒加载有影响(可选)
对象关系映射文件:
把面向对象中的实体类对象映射到数据库中的实体(表的记录),把实体类之间的关联关系也映射到数据库中多个表之间的相互关系中。
这样,在Hibernate中对这些实体对象的操作就直接转换为对数据库表的记录的操作。
xx.hbm.xml 取名<?xml version="1.0"?>
<hibernate-mapping package=“cn.itcast.domain">
<class name="User" table="user"> 类名,table属性可以没有,默认为全部小写的表名,当类名正好是sql下的关键字必须加table
<id name="id"> 属性
<generator class="native"/> 主键生成器
</id>
<property name="name"/>属性
<property name="birthday”/>属性
</class>
</hibernate-mapping>
在hibernate.cfg.xml中加入mapping resource属性
type:hibernate里的类型,作用:通过hibernate的某个类型知道把java里的类型映射到数据库里的类型
基本映射类型可以大致分为
- integer, long, short, float, double, character, byte, boolean, yes_no, true_false
- 这些类型都对应Java的原始类型或者其封装类,来符合(特定厂商的)SQL 字段类型。
-
boolean, yes_no
和true_false
都是Java 中boolean
或者java.lang.Boolean
的另外说法。
- string
- 从
java.lang.String
到VARCHAR
(或者 Oracle的VARCHAR2
)的映射。
- 从
- date, time, timestamp
- 从
java.util.Date
和其子类到SQL类型DATE
,TIME
和TIMESTAMP(默认)
(或等价类型)的映射。
- 从
- calendar, calendar_date
- 从
java.util.Calendar
到SQL 类型TIMESTAMP
和DATE
(或等价类型)的映射。
- 从
- big_decimal, big_integer
- 从
java.math.BigDecimal
和java.math.BigInteger
到NUMERIC
(或者 Oracle 的NUMBER
类型)的映射。
- 从
- locale, timezone, currency
- 从
java.util.Locale
,java.util.TimeZone
和java.util.Currency
到VARCHAR
(或者 Oracle 的VARCHAR2
类型)的映射.Locale
和Currency
的实例被映射为它们的ISO代码。TimeZone
的实例被影射为它的ID
。
- 从
- class
- 从
java.lang.Class
到VARCHAR
(或者 Oracle 的VARCHAR2
类型)的映射。Class
被映射为它的全限定名。
- 从
- binary
- 把字节数组(byte arrays)映射为对应的 SQL二进制类型。
- text
- 把长Java字符串映射为SQL的
CLOB
或者TEXT
类型。
- 把长Java字符串映射为SQL的
- serializable
- 把可序列化的Java类型映射到对应的SQL二进制类型。你也可以为一个并非默认为基本类型的可序列化Java类或者接口指定Hibernate类型
serializable
。
- 把可序列化的Java类型映射到对应的SQL二进制类型。你也可以为一个并非默认为基本类型的可序列化Java类或者接口指定Hibernate类型
- clob, blob
- JDBC 类
java.sql.Clob
和java.sql.Blob
的映射。某些程序可能不适合使用这个类型,因为blob和clob对象可能在一个事务之外是无法重用的。(而且, 驱动程序对这种类型的支持充满着补丁和前后矛盾。)
- JDBC 类
- imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date, imm_serializable, imm_binary
- 一般来说,映射类型被假定为是可变的Java类型,只有对不可变Java类型,Hibernate会采取特定的优化措施,应用程序会把这些对象作为不可变对象处理。比如,你不应该对作为
imm_timestamp
映射的Date执行Date.setTime()
。要改变属性的值,并且保存这一改变,应用程序必须对这一属性重新设置一个新的(不一样的)对象。
- 一般来说,映射类型被假定为是可变的Java类型,只有对不可变Java类型,Hibernate会采取特定的优化措施,应用程序会把这些对象作为不可变对象处理。比如,你不应该对作为
实体及其集合的唯一标识可以是除了binary
、 blob
和clob
之外的任何基础类型。(联合标识也是允许的,后面会说到。)
在org.hibernate.Hibernate
中,定义了基础类型对应的Type
常量。比如,Hibernate.STRING
代表string
类型。
【实例】date类型映射
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="www.hbsi.com.domain">
<!-- 主键 -->
<class name="User" >
<id name="id">
<generator class="increment" />
</id>
<!-- 属性 -->
<property name="name" />
<!-- type属性为通过hibernate的某个类型知道把java里的类型映射到数据库里的类型
date类型默认为TIMESTAMP,有时间也有日期
如果想要只有日期的就要设置一下
-->
<property name="birthday" type="date"/>
</class>
</hibernate-mapping>
Demo1.java
package www.hbsi.com.demo;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import www.hbsi.com.domain.User;
public class Demo1 {
public static void main(String args[]) throws ParseException{
User user = new User();
user.setName("Tom");
//user.setBirthday(new Date());
user.setBirthday(DateFormat.getDateInstance().parse("1992-10-21"));
//新建一个配置对象
Configuration cfg = new Configuration();
//加载hibernate.cfg.xml信息
cfg.configure();
//创建session工厂
SessionFactory sessionFactory = cfg.buildSessionFactory();
//得到session对象
Session session = sessionFactory.openSession();
//hibernate下要开启事务进行保存
session.beginTransaction();
//保存
session.save(user);
//提交事务
session.getTransaction().commit();
//关闭事务
session.close();
}
}
测试类执行过程
在测试文件中的一些类
- Configuration类
- 是Hibernate的入口,它负责配置并启动Hibernate。
- Hibernate通过Configuration的实例加载配置文件信息,然后读取指定对象关系映射文件的内容并创建SessionFactory实例。
- SessionFactory接口
- 负责初始化Hibernate。
- 一个SessionFactory实例对应一个数据库。应用程序从SessionFactory中获得Session实例。
- Session接口
- Session被称为持久化管理器
- 负责管理与持久化相关的操作:存储、更新、删除和加载对象。
- Transaction接口
- 是Hibernate框架的事务接口。
- 它对底层的事务接口做了封装。包括:JDBC API和JTA。
Session的缓存 (一级缓存)
Session的CRUD方法以及调用查询接口的list(),iterate()方法时
怎么寻找:
- 如果session缓存中不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中
- 如果session缓存中已经存在这个对象,就不需在去数据库加载,而直接使用缓存中的对象。
session的缓存一般交由hibernate框架自动管理。
- flush: 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务,;
- commit:先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。
【实例】增删改查
新建一个工具类:HibernateUtil.java
package www.hbsi.com.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Session session;
static {
//加载配置文件
Configuration config = new Configuration().configure();
//session工厂
SessionFactory sf = config.buildSessionFactory();
session = sf.openSession();
}
public static Session getSession() {
return session;
}
}
编写增删改查:crud.java
package www.hbsi.com.demo;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import www.hbsi.com.domain.User;
import www.hbsi.com.utils.HibernateUtil;
public class curd {
Transaction tx = null;
Session session = null;
/*
* 增加用户
*/
@Test
public void addUser() {
User user = new User();
user.setName("Linda");
user.setBirthday(new Date());
// 获取session
try {
session = HibernateUtil.getSession();
session.beginTransaction();
// 增加
session.save(user);
session.getTransaction().commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
// throw new RuntimeException(e);//扔出异常
e.printStackTrace();// 打印轨迹,打印异常
} finally {
if (session != null)
session.close();
}
}
/*
* 根据id查找用户
*/
@Test
public void findUser() {
Session session = HibernateUtil.getSession();
User user = (User) session.get(User.class, 1);
System.out.println(user.getName() + "---" + user.getBirthday());
session.close();
}
/*
* load方式查找用户
* 和get方法区别,load属于懒加载
* 如果没有输出语句,get运行时控制台输出sql语句,load运行不输出sql语句
* load在调用的时候才加载sql语句
*/
@Test
public void loadFindTest() {
Session session = HibernateUtil.getSession();
User user = (User) session.load(User.class, 2); // 懒加载,延迟加载
System.out.println(user.getName()+"---"+user.getBirthday());
session.close();
}
/*
* 根据id删除用户
*/
@Test
public void deleteUser() {
/*找到之后删除
Session session = HibernateUtil.getSession();
session.beginTransaction();
User user = (User)session.get(User.class, 3);
session.delete(user);
session.getTransaction().commit();
session.close();
*/
//直接删除
Session session = HibernateUtil.getSession();
session.beginTransaction();
User user = new User();
user.setId(1);
session.delete(user);
session.getTransaction().commit();
session.close();
}
/*
* 修改用户
*/
@Test
public void updateUser() {
//找到修改
/* Session session = HibernateUtil.getSession();
session.beginTransaction();
User user = (User) session.get(User.class,1);
user.setName("Tom");
session.update(user);
session.getTransaction().commit(); session.close();
*/
//直接修改
//如果不给birthday复制,birthday值为空
Session session = HibernateUtil.getSession();
session.beginTransaction();
User user = new User();
user.setId(1);
user.setName("Tom");
session.update(user);
session.getTransaction().commit();
session.close();
}
/*
* 查找所有
*/
@Test
public void getAll() {
Session session = HibernateUtil.getSession();
Query query = session.createQuery("from User"); // HQL;针对实体类
List<User> users = query.list();
for (User user : users) {
System.out.println(user.getId() + ":" + user.getName() + ":"
+ user.getBirthday());
}
}
}
查找
根据id删除
直接删除
修改,直接修改
修改,查找后修改
查询所有
load方式查询
Session的几个主要方法
- save:保存数据
- delete:删除对象
- update:更新对象,如果数据库中没有记录,会出现异常。
- get:根据ID查,会立刻访问数据库。
- Load:根据ID查,(返回的是代理,不会立即访问数据库)。
- saveOrUpdate: (根据ID和version的值来确定是save或update
主键生成机制
native最常用