导入相关包
包名 | 解释 |
---|---|
hibernate-core | Hibernate 核心包 |
antlr | 用于实现从 HQL 到 SQL 的转换 |
dom4j | 解析 XML 配置文件和 XML 映射文件 |
hibernate-commons-annotations | Hibernate 注解包 |
hibernate-jpa-2.1-api | JPA2.1 接口库 |
jandex | 用来索引 Annotation |
javassist | Hibernate 用来实现 PO 字节码的动态生成 |
jboss-logging | 日志服务通用库 |
jboss-logging-annotations | 实现带注释的接口的具体类 |
jboss-transaction-api_1.2_spec | JTA 规范包 |
创建 Hibernate XML 配置文件
创建 Hibernate XML 配置文件:
org.hibernate.dialect.MySQL5InnoDBDialect
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/tang_poetry?characterEncoding=utf-8
root
123456
org.hibernate.connection.C3P0ConnectionProvider
10
5
5000
10
true
true
创建 bean 和对应的 XML 映射文件
Hibernate 持久化类的要求:
- 提供无参数构造器
- 提供一个标识属性——映射数据库表的主键字段
- 每个属性提供 getter setter 方法
- 使用非 final 类
- 重写 equals() 和 hashCode() 方法——对应需要把持久化类放在 Set 中的情况
<-- class 生成策略,有:increment / identity / sequence / hilo / seqhilo / uuid / guid / native / assigned / select / foreign -->
持久化对象属性的类型与 Hibernate 映射类型与 SQL 类型对应表
创建 log4j 日志配置文件 log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=warn, stdout
#log4j.logger.org.hibernate=info
log4j.logger.org.hibernate=debug
### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
#log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug
### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug
### log cache activity ###
#log4j.logger.org.hibernate.cache=debug
### log transaction activity
#log4j.logger.org.hibernate.transaction=debug
### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug
### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
创建表
- 在 Hibernate 的配置文件中,在
的子元素下添加update - 创建表代码
Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); se.create(true, true);
从 XML 配置文件中构建 SessionFactory
// 默认读取 classpath 目录下的 hibernate.cfg.xml 文件
Configuration config = new Configuration().configure();
ServiceRegistry service = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
SessionFactory factory = config.buildSessionFactory(service);
- SessionFactory 是单个数据库映射关系经过编译后的内存镜像
- SessionFactory 的生命周期一般同应用程序的生命周期
- 线程安全
- SessionFactory 是生成 Session 的工厂
- 可以在线程或集群的级别上,为事务之间可以重用的数据提供可选的二级缓存
从 SessionFactory 中获取 Session
Session session = null;
Transaction tx = null;
try {
session = factory.openSession();
tx = session.beginTransaction();
...
tx.commit();
} catch(Exception e) {
tx.rollback();
} finally {
session.close();
}
- Session 是程序与持久层之间交互操作的一个单线程对象
- 只有处于 Session 管理下的 POJO 才有持久化操作能力
Session 对象的常用方法:
方法 | 解释 |
---|---|
save | |
persist | |
get | |
load | |
delete | |
update | |
updateOrSave | |
merge | |
flush | |
setFlushMode | |
evict | 清除指定对象 |
clear |
基本使用:
// 增
Student stu=new Student();
stu.setName("zhangsan");
stu.setAge(20);
session.save(stu);
// 改
Student stu=(Student)session.get(Student.class, 1);
stu.setName("zhaoliu");
stu.setAge(50);
session.update(stu);
// 删
Student stu=(Student)session.get(Student.class, 2);
session.delete(stu);
// 查
Student stu=(Student)session.get(Student.class, 1);
-
Session 对象的 save 和 persist 方法的区别:
- save 方法返回主键,persist 没有返回
- save 方法会立即将持久化对象对应的数据插入数据库
- persist 方法当在一个事务外被调用时,并不立即转化成 insert 语句
-
Session 对象的 load 和 get 方法区别:
- 在延迟加载时,load 返回一个未初始化的代理对象,直到程序调用代理对象的方法时,才访问数据库
- get 立即访问数据库
- 没有对应数据时,load 返回 HibernateException 异常,get 返回 null
- load 或 get 方法都可指定“锁模式”参数(READ / UPGRADE)来代表共享、修改锁
-
Session 对象的 update 、updateOrSave 、merge 方法区别:
- update 可保存脱管对象所做的修改
- 当不知道对象是否曾经持久化过,可使用 updateOrSave
- merge 方法不会持久化给定对象,当 Session 存在同持久化表示的持久化对象时,merge 提供的对象将覆盖;没有时,则尝试从数据库加载,或创建新的持久化对象,并返回该对象
Session 有一个必选的一级缓存,称为一级缓存
-
Session 缓存原理
- 当程序调用Session 的 CRUD 方法时,如果在 Session 的缓存中不存在相应的对象,Hibernate 会把对象加到一级缓存
- 当清理缓存时,Hibernate 会根据缓存中对象状态的变化来同步更新缓存
-
Session缓存的作用
- 减少访问数据库的频率
- 保证缓存中的对象与数据库中的数据同步
- 当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循环,以及由死循环引起的JVM堆栈溢出异常
当调用 Transaction 的 commit 方法时,会清理缓存,再向服务器提交事务
当显式调用 Session 的 flush 方法时,通过 Session 的 setFlushMode 方法来设定清理缓存的时间点( ALWAYS / AUTO / COMMIT / MANUAL )
Session 的 evict 方法能将占用大量内存的对象或集合属性从一级缓存中剔除出去。contains 方法可判断某个对象是否在缓存中,clear 方法清除所有缓存
-
持久化对象的状态:持久化、瞬态、托管
- 瞬态:刚 new 出来
- 持久化
持久化实例在数据库中有对应的记录,并拥有一个持久化标识(一般为主键)
持久化对象必须与指定的 Session 关联
-
Hibernate 会检测持久化对象的改动,在当前操作完成时将对象数据写回数据库,不需要手动执行 update
``` Student stu=new Student(); stu.setName("zhangsan"); stu.setAge(20); session.save(stu); // 此时 stu 是持久化对象,修改会保存到数据库 stu.setAge(30); ```
- 脱管
- Session 关闭或 clear 则对象变成脱管
- 让脱管对象重新与某个 Session 关联,则重新转变为持久化,脱管期间的改动也不会丢失,也可写入数据库
- 瞬态 -> 持久化
- save()、saveOrUpdate()
- get()、load()、find()
- 持久化 -> 瞬态
- delete()
- 持久化 -> 脱管
- evict()
- close()
- clear()
- 脱管 -> 持久化
- save()、saveOrUpdate()
- lock()