Hibernate深入浅出(二十五)-----读深入浅出hibernate有感

Hibernate深入浅出(二十五)-----读深入浅出hibernate有感
package  com.hibernate.higherApplication;

import  java.util.Iterator;
import  java.util.List;
import  java.util.Set;

import  junit.framework.TestCase;

import  org.hibernate.Criteria;
import  org.hibernate.Hibernate;
import  org.hibernate.HibernateException;
import  org.hibernate.Query;
import  org.hibernate.Session;
import  org.hibernate.SessionFactory;
import  org.hibernate.cfg.Configuration;
import  org.hibernate.criterion.Expression;

public   class  DurationOperator  extends  TestCase {
    
private  SessionFactory sessionFactory  =   null ;
    
private  Session session  =   null ;
    
/**
     * 初始化资源
     
*/
    
protected   void  setUp()  throws  Exception {
        
try  {
            
// 加载类路径下的hibernate.cfg.xml文件
            Configuration config  =   new  Configuration().configure();
            
// 创建sessionFactory对象
            sessionFactory  =  config.buildSessionFactory();
            
// 创建session
            session  =  sessionFactory.openSession();
        } 
catch  (HibernateException e) {
            e.printStackTrace();
        }
    }
    
/**
     * load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。
     * 区别在于:
     * 1、如果未发现符合条件的记录,get方法返回null,而load方法抛出一个ObjectNotFoundException
     * 2、load方法可以返回实体的代理类实例,而get方法永远直接返回实体类。
     * 3、load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如果
     * 没有发现数据,将越过二级缓存,直接调用SQL完成数据读取。
     *
     
*/
    
public   void  loadOrGetData(){
        TUser user 
=  (TUser)session.load(TUser. class , new  Integer( 1 ));
    }
    
/**
     * 查询性能往往是一系统性能表现的一个重要方面。
     * query.list方法通过一条select SQL实现了查询操作,而iterate方法,则执行了3次selectSQL,第一次获取了所有符合条件的记录
     * 的id,之后,在根据各个id从库表中读取对应的哦记录,这是一个典型的N+1次查询问题。
     * 
     * 我们进行query.list数据查询时,即使缓存中已经有一些符合条件的实体对象存在,我们也无法保证这些数据就是库表中所有符合条件的数据。假设
     * 第一次查询条件是age>25,随即缓存中就包括了所有age>25的user数据;第二次查询条件为age>20,此时缓存中虽然包含了满足age>25d的
     * 数据,但这些并不是满足条件age>20的全部数据
     * 因此,query.list方法还是需要执行一次select sql以保证查询结果的完整性(iterate方法通过首先查询获取所有符合条件记录的id,以此保证
     * 查询结果的完整性)。
     * 因此,query.list方法实际上无法利用缓存,它对缓存只写不读。而iterate方法则可以充分发挥缓存带来的优势,如果目标数据只读或者读取相对
     * 较为频繁,通过这种机制可以大大减少性能上的损耗。
     
*/
    
public   void  queryForList(){
        String hql 
=   " from TUser where age>? " ;
        Query query 
=  session.createQuery(hql);
        query.setInteger(
1 , 1 );
        
        List list 
=  query.list();
        
        
for ( int  i = 0 ;i < list.size();i ++ ){
            TUser user 
=  (TUser)list.get(i);
            System.out.println(
" User age: " + user.getAge());
        }
    }
    
public   void  queryForIterate(){
        String hql 
=   " from TUser where age>? " ;
        Query query 
=  session.createQuery(hql);
        query.setInteger(
1 , 1 );
        
        Iterator it 
=  query.iterate();
        
        
while (it.hasNext()){
            TUser user 
=  (TUser)it.next();
            System.out.println(
" User age: " + user.getAge());
        }
    }
    
/**
     * 大数据量的批量读取(10W条)
     * 解决方案:结合iterate方法和evict方法逐条对记录进行处理,将内存消耗保持在可以接受的范围之内。
     * 在实际开发中,对于大批量数据处理,还是推荐采用SQL或存储过程实现,以获得较高的性能,并保证系统平滑运行。
     
*/
    
public   void  bigDataRead(){
        String hql 
=   " from TUser where age>? " ;
        Query query 
=  session.createQuery(hql);
        query.setInteger(
" age " 1 );
        Iterator it 
=  query.iterate();
        
        
while (it.hasNext()){
            TUser user 
=  (TUser)it.next();
            
// 将对象从一级缓存中移除
            session.evict(user);
            
// 二级缓存可以设定最大数据缓存数量,达到峰值时会自动对缓存中的较老数据进行废除,但是我们这里还是通过
            
// 编码指定将对象从二级缓存中移除,这有助保持缓存的数据有效性。
            sessionFactory.evict(TUser. class ,user.getId());
        }
    }
    
/**
     * Query Cache弥补了find方法的不足,QueryCache中缓存的SQL及其结果及并非永远存在,当Hibernate发现此SQL对应的库表发生变动,
     * 会自动将Query Cache中对应表的SQL缓存废除。因此Query Cache只在特定的情况下产生作用:
     * 1、完全相同的select SQL重复执行。
     * 2、在2次查询之间,此select SQL对应的库表没有发生过改变。
     
*/
    
public   void  queryForQueryCache(){
        String hql 
=   " from TUser where age>? " ;
        Query query 
=  session.createQuery(hql);
        query.setInteger(
1 1 );
        
// 除了在这里设置QueryCache外,还要在hibernate.cfg.xml中进行设置
        
// <property name="hibernate.cache.use_query_cache">true</property>
        query.setCacheable( true );
        List userList 
=  query.list();
    }
    
/**
     * 所谓延迟加载,就是在需要数据的时候,才真正执行数据加载操作。
     * 延迟加载实现主要针对:
     * 1、实体对象:通过class的lazy属性,我们可以打开实体对象的延迟加载功能。
     * 2、集合
     
*/
    
public   void  queryForEntityLazy(){
        Criteria criteria 
=  session.createCriteria(TUser. class );
        criteria.add(Expression.eq(
" name " , " Erica " ));
        
        List userList 
=  criteria.list();
        TUser user 
=  (TUser)userList.get( 0 );
        
// 虽然使用了延迟加载,但是我们可以通过hibernate的初始化方法进行强制加载,这样即使session关闭之后,关联的对象仍让可以使用
        Hibernate.initialize(user.getAddresses());
        
        System.out.println(
" User name=> " + user.getAge());
        
        Set hset 
= user.getAddresses();
        TAddresses addr 
=  (TAddresses)hset.toArray()[ 0 ];
        System.out.println(addr.getAddress());
        
        session.close();
    }
    
/**
     * 关闭资源
     
*/
    
protected   void  tearDown()  throws  Exception {
        
try {
            session.close();
        }
catch (HibernateException e){
            e.printStackTrace();
        }
    }

}

你可能感兴趣的:(Hibernate深入浅出(二十五)-----读深入浅出hibernate有感)