Hibernate延迟加载

来源:互联网 发布:java snmp 流量监控 编辑:程序博客网 时间:2024/06/05 18:14

 延迟加载:是在真实需要数据才执行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());     }}
原创粉丝点击