延迟加载:是在真实需要数据才执行SQL语句进行查询,避免无谓的性能开销。
类级可选:立即检索,延迟检索,默认为延迟检索
立即检索:立即加载对指定的对象,立即发送SQL
延迟检索:延迟加载指定检索的属性,才发送SQL
无论
简单来说就是,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)改变小配置
<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>OpenSessionInviewFilterfilter-name> <filter-class>cn.happy.Session.filter.OpenSessionInviewFilterfilter-class> filter> <filter-mapping> <filter-name>OpenSessionInviewFilterfilter-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 SetDapt.hbm.xmlemps=new HashSet ();
xml version="1.0"?> 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"?> 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="Emp" table="Emp" schema="happyy2165"> <id name="eid" column="eid"> <generator class="native">generator> id> <property name="ename"/> <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()); } }