1. cascade和懒加载
级联操作(关联关系的增删改操作)
@ManyToOne(cascade={CascadeType.ALL})
publicGroup getGroup() {
returngroup;
}
抓取策略(关联关系的select操作)
@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
多方fetch默认为LAZY,1方默认为EAGER
2. 主键生成策略
Nativeidentity sequence uuid
3. list/iterate
iterate先取id,当使用具体对象时,再去select
同一个session,用2遍list,会执行2次,iterate只发出一次,第二次从session缓存取数据
list不读session缓存,每次list的结果有区别,无法使用缓存
4. 继承映射,3种表结构
5. 3种状态Transient Persistent detached
有无id
Hibernate 缓存有无数据
数据库有无持久化对象
6. openSession/getCurrentSession
a. openSession 从字面上可以看得出来,是打开一个新的session对象,而且每次使用都是打开一个新的session,假如连续使用多次,则获得的session不是同一个对象,并且使用完需要调用close方法关闭session。
b. getCurrentSession ,从字面上可以看得出来,是获取当前上下文一个session对象,当第一次使用此方法时,会自动产生一个session对象,并且连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一,简单而言,getCurrentSession 就是:如果有已经使用的,用旧的,如果没有,建新的。
注意:在实际开发中,往往使用getCurrentSession多,因为一般是处理同一个事务(即是使用一个数据库的情况),所以在一般情况下比较少使用openSession或者说openSession是比较老旧的一套接口了;
对于getCurrentSession来说,有以下一些特点:
1.用途,界定事务边界
2.事务提交会自动close,不需要像openSession一样自己调用close方法关闭session
3.上下文配置(即在hibernate.cfg.xml)中,需要配置:
<propertyname="current_session_context_class">thread</property>
(需要注意,这里的current_session_context_class属性有几个属性值:jta 、 thread 常用 , custom、managed 少用 )
a).thread使用connection单数据库连接管理事务
b).jta (java transaction api) Java 分布式事务管理 (多数据库访问),jta 由中间件提供(JBoss WebLogic 等, 但是tomcat 不支持)
7. 一级缓存/二级缓存/查询缓存
- 一级缓存(session级别),二级缓存(sessionfactory级别)[需要使用第三方框架EHCache],三级缓存(查询缓存)[相同的list不需要多次查询]
- Hibernate.cfg.xml
二级缓存配置
<propertyname="cache.use_second_level_cache">true</property>
<propertyname="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
(hibernate.4.x配置)
<propertyname="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
查询缓存配置
<propertyname="cache.use_query_cache">true</property>
- Ehcache.xml配置
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="1200"
overflowToDisk="true"
/>
- 实体类配置
@Entity
@Cache(usage= CacheConcurrencyStrategy.READ_WRITE)
publicclass Category {
- curd使用查询缓存
List<Category>categories = (List<Category>)session.createQuery("fromCategory").setCacheable(true).list();
- load,iterate使用2级缓存;list默认给缓存加数据,list相同查询可以使用查询缓存。
- 缓存算法
- 先进先出
- 最后使用时间
- 使用次数
- 那些实体适合做缓存?
- 数据量小,不频繁更新
9. 性能问题
- 1+N
- 描叙:manyToOne fetchType=eager时,用HQL取多方,同时会将1方取出来,此时hibernate发送的sql语句是1+N条。
- 将fetchType=lazy(只取多方,1方用到才取)
- batchsize设置(1方设置),减少sql
- HQL采用left join,1条sql搞定(一次性取出)
- criteria查询
- 脏读:读其他事物未提交的数据
- 不可重复读:受其他事物提交影响(update),2次读取的数据不一致
- 幻读:受其他事物提交影响(insert,delete),2次读取数据不一致
- 事物隔离机制:级别越高,效率越低
- Read-uncommitted:不能限制
- Read-committed:限制脏读
- Repeatable-read:读出来的数据加锁
- serializable:给事物上锁
- Hibernate.connectino.isolation设置,(不设置,依赖数据库设置)
- 悲观锁,乐观锁
- 在数据库设置为read-committed时,解决不可重复读的问题。
- 悲观锁,依赖于数据库实现,在数据库表上加锁
Sessionsession = sf.openSession();
session.beginTransaction();
Accounta = (Account)session.load(Account.class, 1, LockMode.UPGRADE);
intbalance = a.getBalance();
//dosome caculation
balance= balance - 10;
a.setBalance(balance);
session.getTransaction().commit();
session.close();
- 乐观锁,数据做version标记,每次update时version++,判断version变更