Hibernate开发步骤搭建
- 1、导入相关jar包(Hibernate压缩包 > lib包 > required包下所有的jar,外加log4j.jar和数据库驱动包)
-
2、编写映射文件描述类与数据库表之间的关系
- 引入dtd约束(Hibernate压缩包 > project > etc文件下有)
- 映射文件推荐命名规则:类名.hbm.xml
-
3、编写核心配置文件(位置在src下,名字叫做 hibernate.cfg.xml)
- 引入核心配置文件dtd约束
- 配置数据库连接信息
com.mysql.jdbc.Driver jdbc:mysql:///db_hibernate?useUnicode=true&characterEncoding=utf-8 root - 配置数据库方言(方言同时设置数据的存储引擎,指定引擎为InnoDB,不指定外键不能用)
org.hibernate.dialect.MySQLInnoDBDialect - 配置其他选配信息
true true update - 引入映射文件
配置映射文件
配置实体类与数据表的联系
``` xml
类与表的描述信息
```
配置主键(hibernate要求实体类里面有一个属性作为唯一值,对应主键,主键可以有不同的生成策略)
``` xml
```
注意:主键生成策略(generator标签):native(根据本地数据库支持主键生成方式)、uuid(根据uuid算法生成一个32位16进制的字符串,推荐使用)
配置实体类属性与数据表字段的对应关系
- 实体类属性与数据表字段可以使用标签进行配置
``` xml
```
- 列名可以不写,默认和实体类名字段一样
``` xml
```
- type可以不写,默认和实体字段属性一致
``` xml
```
- length设置数据表中对应字段的长度,默认进行设置
``` xml
```
- 普通方式配置实体类属性与数据表字段的关系
``` xml
```
使用Hibernate API操作
操作的主体流程
// 创建Configuration(hibernate包下)对象
Configuration configuration = new Configuration();
// 加载配置文件
configuration.configure();
// 得到SessionFactory对象
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 得到session对象
Session session = sessionFactory.openSession();
// 开启事务
Transaction transaction = session.beginTransaction();
try {
/*进行crud操作*/
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
// 回滚事务
transaction.rollback();
}
e.printStackTrace();
} finally {
// 释放session
session.close();
sessionFactory.close();
}
实体类的三种状态
1、瞬时态:缓存中不存在,数据库中也不存在(不含有id与session无关)
2、持久态:缓存中存在,数据库中也存在(含有id,与session有关)
3、游离态(托管态):缓存中不存在,数据库中存在(含有id,与session无关)
hibernate缓存
-
hibernate缓存的作用
1、数据存放到数据库里面,数据库本身是文件系统,使用流的方式操作文件效率不高
2、把数据放入缓存中,不需要使用流的方式,可以直接读取数据
3、再次使用相同语句进行查询时,先在缓存中查找,提高了查询效率
-
hibernate一级缓存
1、存储的是数据而不是对象(通过id进行辨别)
2、一级缓存使用范围是session(hibernate的session对象)
3、默认进行开启
特性:session一级缓存中有一个快照区,快照区保存原始的数据库信息,因此持久态实体类对象,改变对象的数据关闭缓存时自动进行更新(可以不调用update()方法)
增删改查API
- get()是立即查询,查询出的对象是持久态
// 向数据库中查询数据
// 结论:get方法,立即查询(查询出的对象为持久态)
User user = session.get(User.class, 7);
- load()延迟查询
// 向数据库中查询数据
// 结论:load方法,延迟加载(查询出的对象为持久态),只有在使用查询出的对象时才进行查询,其它方面与get一样
User user = session.load(User.class, 6);
- save()添加
// 向数据库中插入一条数据,返回值为插入数据的主键(save方法会把瞬时态对象变成持久态对象)
Serializable serializable = session.save(user);
- saveOrUpdate()添加或修改
// 向数据库中插入一条数据,或对数据进行修改
// 结论1:saveOrUpdate方法,如果添加的对象不含有主键属性,则与save方法执行相同(把瞬时态对象变为持久态对象)
// 结论2:saveOrUpdate方法,如果添加的对象含有主键属性,会把对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,添加的对象进入持久态),
// 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(不管与数据库数据是否相同,都会进行修改)
session.saveOrUpdate(user);
- marge()添加或修改,该方法的返回值是一个持久化对象
// 向数据库中插入一条数据,或对数据进行修改
// 结论1:merge方法,如果添加的对象不含有主键属性,则与save方法执行相同(但是不会把瞬时态对象变为持久态对象)
// 结论2:merge方法,如果添加的对象含有主键属性,先查询对象把对象数据放入快照区会,把传入的对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,对象不会进入持久状态),
// 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(两者相同不会进行修改)
session.merge(user);
- update()修改数据
// 向数据库中修改数据
// 结论:update方法,把传入的对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,对象进入持久状态),
// 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(两者相同不会进行修改)
session.update(user);
- delete()删除数据
// 向数据库中删除数据
// 结论:delete方法,删除一级缓存中的相应数据(不清除快照区的数据),并阻止这个对象的操作,
// 清除缓冲区时通过缓冲区和快照区的对比进行删除
session.delete(user);
hibernate绑定session
hibernate帮我们实现了与本地线程的绑定(底层还是ThreadLocal)
在主配置文件中进行配置,通过sessionFactory.getCurrentSession();得到与线程绑定的session
thread