Hibernate延迟加载

   延迟加载:是在真实需要数据才执行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"?>
        <!DOCTYPE hibernate-mapping PUBLIC
                "-//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"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//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());
     }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值