Hibernate 加载类型,缓存,锁

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.xmlsrc目录下:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

 

    <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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值