您的位置:首页 > 其它

Hibernate延迟加载

2017-10-10 14:05 369 查看
 延迟加载:是在真实需要数据才执行SQL语句进行查询,避免无谓的性能开销。

   类级可选:立即检索,延迟检索,默认为延迟检索

                     立即检索:立即加载对指定的对象,立即发送SQL

                     延迟检索:延迟加载指定检索的属性,才发送SQL

   无论<class>元素的lazy的属性是true或false , session的get( )方法及Query( )方法在类级别总是立即检索策略

   简单来说就是,get( )或list( ),lazy无效

   lazy:决定关联对象初始化时机

   Fetch:决定SQL语句构建形式

   proxy(默认) 延迟加载          no-proxy:无法代理延迟加载            false:立即加载

   No-Session的场景构建:在Session关闭了dao层的会话对象,在Ui层使用的时候,发现代理对象而非真实的对象,获取属性上网时候,想走别的,但是走不了。。。

   NO-Session 的解决方案:  

             (1)将dao中的load( )方法改成get( )            

/*第一种解决 no Session 的方法*/
Object result= HibernateUtil.getSession().get(clazz,id);


             (2)在biz中加入                   

/*第二种解决 no Session 的方案*/
    if (!Hibernate.isInitialized(obj)){
Hibernate.initialize(obj);
}


             (3)改变小配置        

<!--第三种解决 no Session 的方案  在<class> 中加入 lazy="false" 如下所示-->
<class name="Emp" table="Emp"  lazy="false" schema="happyy2165">


             (4)先在biz层读取信息,不得已方案                    

/*第四种解决方法,不得已方案*/
Emp emp= (Emp) obj;
emp.getEname();


             (5)OpenSessionInview (javaweb中使用) :在用户的每一次请求过程始终保持一个Session对象打开看。

                     
public class OpenSessionInviewFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//请求达到时,打开Session并启动事务
Transaction tx=null;
try {
tx= HibernateUtil.getSession().beginTransaction();
filterChain.doFilter(servletRequest,servletResponse);//执行  找xxxServlet 或 index.jsp
tx.commit();
}catch (Exception ex){
ex.printStackTrace();
tx.rollback();
}finally {
HibernateUtil.closeSession();
}
}

public void destroy() {
}
}

web.xml

<filter>
<filter-name>OpenSessionInviewFilter</filter-name>
<filter-class>cn.happy.Session.filter.OpenSessionInviewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInviewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
----------------------------------
biz层:
public class HibernateBiz {
HibernateDAo dAo=new HibernateDAo();
public  Object get(Class clazz, Serializable id){
Transaction tx= HibernateUtil.getSession().beginTransaction();
Object obj=dAo.get(clazz,id);

/*第四种解决方法,不得已方案*//*
/*  Emp emp= (Emp) obj;
emp.getEname();*/

/*第二种解决 no Session 的方案*/
/* if (!Hibernate.isInitialized(obj)){
Hibernate.initialize(obj);
}*/
tx.commit();
HibernateUtil.closeSession();
System.out.println("========");
/*obj:代理对象. 不走数据库,根据原始对象的模板,将属性copy一遍。*/
return obj;
}
}
dao层:
public class HibernateDAo {
public   Object  get(Class clazz, Serializable id){
/*第一种解决 no Session 的方法*/
/* Object result= HibernateUtil.getSession().get(clazz,id);*/
Object result= HibernateUtil.getSession().load(clazz,id);
return  result;
}
}
在Dapt中写上属性,并将其进行封装,并使用Set将emp植入进来
private Integer pid;

    private String pname;
    private Set<Emp> emps=new HashSet<Emp>();
 Dapt.hbm.xml  
<?xml version="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.happy.Session">
<class name="Dapt" table="Dapt"  lazy="false" schema="happyy2165">
<id name="pid" column="pid">
<generator class="native"></generator>
</id>
<property name="pname"/>
<set name="emps" cascade="save-update" inverse="true" lazy="false" fetch="join" order-by="pid">
<!--一对多-->
<key column="pid"></key>
<one-to-many class="cn.happy.Session.Emp"></one-to-many>
</set>
</class>
</hibernate-mapping>
创建Emp类,写上属性值,并将其进行封装    
     private Integer eid;
     private String ename;
     private Dapt dapt=new Dapt();


        Emp.hbm.xml       

<?xml version="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.happy.Session">
<!--第三种解决 no Session 的方案  在<class> 中加入 lazy="false" 如下所示-->
<!--  <class name="Emp" table="Emp"  lazy="false" schema="happyy2165">-->

<class name="Emp" table="Emp"  schema="happyy2165">
<id name="eid" column="eid">
<generator class="native"></generator>
</id>
<property name="ename"/>
<!--多对一
name:Emp中植入的一方过的属性名称
column:数据库中的外键列的名称
-->
<many-to-one name="dapt" column="pid"  lazy="proxy"  class="Dapt"></many-to-one>
</class>
</hibernate-mapping>

测试类:

public class SessionTest {
@Test
public void loadGetTest(){
HibernateBiz  biz=new HibernateBiz();
//获取单个员工对象
Emp emp= (Emp) biz.get(Emp.class,1);
//获取员工实体中员工姓名
System.out.println(emp.getEname());
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: