1. 懒加载(只有load支持):
Lazy
Eg:
<class name="com.etc.entity.singleface.Person" table="t_lazy_person" lazy="true" >
默认情况下是lazy=”true”:
//LAZY="TRUE"
Person person1 = (Person)session.load(Person.class, "2c9282db421b85c201421b85c3940003");//不会发送查询sql
System.out.println("person.name:"+person1.getName());//会发送查询person表sql
System.out.println("dept.name:"+person1.getDept().getDeptname());//会发送查询dept表sql
//LAZY="false"
Person person1 = (Person)session.load(Person.class, "2c9282db421b85c201421b85c3940003");//会发送查询sql
System.out.println("person.name:"+person1.getName());//不会发送查询person表sql
System.out.println("dept.name:"+person1.getDept().getDeptname());//会发送查询dept表sql
2. 抓取策略:
<class name="com.etc.entity.singleface.Person" table="t_fetch_person" lazy="true" >
<id name="pno">
<generator class="uuid"/>
</id>
<property name="name" />
<property name="address"/>
<property name="age"/>
<many-to-one name=" dept " column="deptid" cascade="save-update" fetch ="join" ></many-to-one>
</class>
Fetch=“select”:会单独发送sql查询dept;
fetch ="join":查询Person时发送一条sql将dept一起查询出来
3. 一级缓存(session级别缓存:同一个session共享实体)get()和load()都会使用一级缓存。*只有在同一个session获取相同实体才共享(get或者load),不同session获取相同实体时不共享。
Eg1:
//LAZY="false"
Person person1 = (Person)session.get(Person.class, "2c9282db421bc40301421bc405ee0003"); //发送sql
System.out.println(person1.getName());//不发sql
Person person2 = (Person)session.load(Person.class, "2c9282db421bc40301421bc405ee0003");//不发sql
System.out.println(person2.getName());//不发sql
Eg2:
//LAZY="false"
Person person1 = (Person)session.get(Person.class, "2c9282db421bc40301421bc405ee0003"); //发送sql
System.out.println(person1.getName());//不发sql
Session session2 = HibernateUtil.getHibeSess();//获取会话
Person person2 = (Person)session2.load(Person.class, "2c9282db421bc40301421bc405ee0003");//发sql
System.out.println(person2.getName());//不发sql
4. 二级缓存:
开启二级缓存:
hibernate.cfg.xml
<property name="hibernate.cache.use_second_level_cache">true</property>
配置二级缓存的提供商:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
配置那些实体使用二级缓存:
方式一:配置在hibernate.cfg.xml
Eg:
<class-cache usage="read-write" class="com.etc.entity.singleface.Person" />
方式二:配置在实体的映射文件中:
Eg:
<class name="com.etc.entity.singleface.Person" table="t_secondcache_person" lazy="false" >
<cache usage="read-write"/>
<id name="pno">
<generator class="uuid"/>
</id>
<property name="name" />
<property name="address"/>
<property name="age"/>
<many-to-one name="dept" column="deptid" cascade="save-update" fetch="join" ></many-to-one>
</class>
拷贝 \hibernate-3.2\etc\ehcache.xml到src目录下:
<ehcache xmlns:xsi="http://www.w
<diskStore path="java.io.tmpdir"/>
<!--
Mandatory Default Cache configuration. These settings will be applied to caches
created programmtically using CacheManager.add(String cacheName)
-->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
5. 查询缓存(结合二级缓存一起使用):
开启查询缓存:
hibernate.cfg.xml
<property name="hibernate.cache.use_query_cache">true</property><!-- 开启查询缓存 -->
使用:
public void testget(){
Session session = HibernateUtil.getHibeSess();//获取会话
Transaction ts = session.beginTransaction();//开启事务
//使用查询缓存
Query query = session.createQuery("from Person");
query.setCacheable(true);//设置使用查询缓存
List<Person> ps = query.list();//发送sql
for(Person p :ps ){
System.out.println("name:"+p.getName());//不发
}
Query query1 = session.createQuery("from Person ");//前后查询语句一致情况下才使用查询缓存
query1.setCacheable(true);//设置使用查询缓存
List<Person> ps1 = query1.list();//不发送sql
for(Person p :ps1 ){
System.out.println("name:"+p.getName());//不发
}
}
6. 锁:
Oracle:
悲观锁:
A事务:
public void testlock1(){
Session session = HibernateUtil.getHibeSess();//获取会话
Transaction ts = session.beginTransaction();
Person p1 = (Person)session.get(Person.class, "2c9282db421ca31501421ca3165d0001",LockMode.UPGRADE_NOWAIT);
//UPGRADE_NOWAIT:其他事务不能获取该资源,并且抛出LockAcquisitionException异常
//UPGRADE:其他事务等待当前事务释放资源
System.out.println(p1.getName());
p1.setName("张一");
session.saveOrUpdate(p1);//假设断点停到此代码处
ts.commit();
HibernateUtil.closeHibeSess(session);
}
B事务:
public void testlock2(){
Session session = HibernateUtil.getHibeSess();//获取会话
Transaction ts = session.beginTransaction();
Person p1 = (Person)session.get(Person.class, "2c9282db421ca31501421ca3165d0001",LockMode.UPGRADE_NOWAIT);//去拿资源时会抛出LockAcquisitionException异常
System.out.println(p1.getName());
p1.setName("张二");
session.saveOrUpdate(p1);
ts.commit();
HibernateUtil.closeHibeSess(session);
}
悲观锁:
A事务:
public void testlock1(){
Session session = HibernateUtil.getHibeSess();//获取会话
Transaction ts = session.beginTransaction();
Person p1 = (Person)session.get(Person.class, "2c9282db421ca31501421ca3165d0001",LockMode.UPGRADE);
//UPGRADE:其他事务等待当前事务释放资源
System.out.println(p1.getName());
p1.setName("张一");
session.saveOrUpdate(p1);//假设断点停到此代码处
ts.commit();
HibernateUtil.closeHibeSess(session);
}
B事务:
public void testlock2(){
Session session = HibernateUtil.getHibeSess();//获取会话
Transaction ts = session.beginTransaction();
Person p1 = (Person)session.get(Person.class, "2c9282db421ca31501421ca3165d0001",LockMode.UPGRADE);//去拿资源时,会一直等待A事务释放资源。
System.out.println(p1.getName());
p1.setName("张二");
session.saveOrUpdate(p1);
ts.commit();
HibernateUtil.closeHibeSess(session);
}
乐观锁:
Person.java
public class Person implements Serializable{
private String pno;
private String name;
private String address;
private DepartmentEntity dept;
private int age;
private int bbkz;//版本控制 必须为int 且不能为空
}
Person.hbm.xml:
<hibernate-mapping >
<class name="com.etc.entity.singleface.Person" table="t_happylock_person"
lazy="false" optimistic-lock="version" ><!-- 指定此实体采用版本号进行锁 -->
<id name="pno">
<generator class="uuid"/>
</id>
<version name="bbkz"></version><!-- 指定版本号存放列 -->
<property name="name" />
<property name="address"/>
<property name="age"/>
<many-to-one name="dept" column="deptid" cascade="save-update" fetch="join" ></many-to-one>
</class>
</hibernate-mapping>