4、Hibernate缓存
Session缓存(一级缓存,没法禁用的,属于事务级缓存)的作用:
减少访问数据库的频率;保证缓存中的对象与数据库中的相关记录保持同步(当缓存中持久化对象的状态发生了变化,session并不会立即执行相关的sql语句,这使得session能够把几条相关的sql合并成一条进行执行,减少访问数据库的频率,提供程序性能。)
Session清理缓存的时间点:
Transaction tx = session.beginTransaction();
tx.commit();
1):调用了commit()方法会先清空session缓存,然后去提交事务;
2):session.flush();强制性的情况缓存。
SessionFactory缓存(二级缓存,可配置,属于进程级缓存)。可由第三方实现提供.
如:EhCache使用了一个内存存储和磁盘存储。对应的jar:ehcache-1.2.3.jar
要使用二级缓存,首先需要先开启二级缓存(在hibernate.cfg.xml)中进行配置
<!-- 开启二级缓存 --> <property name="hibernate.cache.use_second_level_cache"> true </property> <!-- 指定那个类来实现二级缓存 --> <property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property>
在关联关系map set list中,如果想保存多的那一方数据,
需要在该元素下配置<cache name = "?"/>,只是设置cache只会保存OID,而不是整个数据对象。
而且还需要在多的一方配置<cache name = "?"/>
其中?存在四个值:
read-only:
read-write:使用了<timestamp>机制来维护事务隔离级别
nonstrict-read-write:二级缓存与数据库中的信息可能会出现不一致的情况
在使用这种策略时,可以使用缓存过期时间来定期与数据库进行缓存数据与
数据库数据进行同步。
transactional:
还需要配置一个二级缓存自身的文件
ehcache.xml文件(该文件在src目录下)
该文件的内容为: <?xml version="1.0" encoding = "utf-8"?> <ehcache> <!-指定磁盘存储地址--> <diskStore path = "c:/ehcache"/> <!--设定默认的存储配置--> <defaultCache maxElementsInMemory = "200" eternal = "false" timeToIdleSeconds = "50" timeToLiveSeconds = "60" overflowToDisk = "true"/> <!--可以对每一个模型类进行存储配置--> <cache name = "com.liusheng.models.Student9" maxElementsInMemory = "200" eternal = "false" timeToIdleSeconds = "50" timeToLiveSeconds = "60" overflowToDisk = "true"/> </ehcache>
同时需要添加两个jar包支持
asm-3.1.jar ; commons-logging-1.1.1.jar
Hibernate一级缓存(session缓存) ------------>Hibernate二级缓存(sessionFactory缓存,为可配置缓存
public class Student implements Serializabe{ pivate Long id; private String name; prvate String pass; ...setter/getter... }
<?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> <class name = "Student" table="student_" > <!-- 配置缓存 --> <cache usage="read-write"/> <!-- 配置一对一关联关系进行主键关联 --> <id name = "id" column = "id" type="long"> <generator class="increment"></generator> </id> <property name="name" column = "name" type = "string"></property> <property name="pass" column = "pass" type = "string"></property> </class> </hibernate-mapping>
查询所有的列表时,进行第二次查询也会发出sql,查询单独的会从缓存中获取。
//读取数据 Session session = sessionFactory.openSession(); Query query = session.createQuery("from Student"); //此处调用直接从数据库中获取 List<Student>list = (List<Student>)query.list(); //再次查询数据,直接从二级缓存中获取数据,不在查询数据库 Session s = sessionFacory.openSession(); Student ss = (Student)s.get(Student.class,new Long(1));
5、Hibernate 对象的状态
1):临时状态(transient):刚被new出来的对象,还没有被持久化,不处于session的缓存中,不具备OID
2): 持久化状态:已经被持久化,加入到了session缓存中,具备OID.
3):游离状态:已经被持久化,但是不再处于session缓存中,具备OID.
Hibernate对象状态的变化条件:
new -------> 临时状态 -------save();saveOrUpdate();----> 持久化状态 -----close();clear();evict();--->游离状态 ----save();saveOrUpdate();lock();--->持久化状态 ---delete();--->临时状态
持久化状态 ---delete();----> 临时状态
Hibernate使用连接池直接配置接口(略..)