资源描述
单击鼠标编辑标题文的格式,单击鼠标编辑大纲正文格式,第二个大纲级,第三个大纲级,第四个大纲级,第五个大纲级,第六个大纲级,第七个大纲级,第八个大纲级,第九个大纲级,单击鼠标编辑标题文的格式,单击鼠标编辑大纲正文格式,第二个大纲级,第三个大纲级,第四个大纲级,第五个大纲级,第六个大纲级,第七个大纲级,第八个大纲级,第九个大纲级,加载策略,课 程 目标,对象在,Hibernate,中的状态,加载策略介绍,lazy=”false”,与,fetch=“join”,的区别,inverse=”true”,insert=”false” update=”false”,对象在,Hibernate,中的状态,临时状态,普通的,Java,对象,只是一个携带信息的载体,没与,session,实例关联,,没与数据库中记录关联,持久状态,持久实例在数据库中,有对应的记录,,并拥有持久化标识,,持久实例可能是刚刚被保存,,或刚刚被加载的数据,脱管状态,持久对象关联的,Session,关闭后,,对象变为脱管,saveOrUpdate(),临时状态,持久状态,脱管状态,get(),load(),find(),iterator(),save(),update(),delete(),close(),clear(),update(),evict(),delete(),举例说明对象状态,Session session = sessionFactory.openSession(); /,开启连接,tx = session.beginTransaction(); /,开启事务,Employee emp = session.get(Employee.class, 123); /,根据主键加载,emp.setEmpName(“QQ”);/,对持久对象进行更改,不需要更新,session.update(emp);/,更新,此句没有必要,mit();,session.close();,emp.setEmpName(“QQ1”);,/,对脱管对象进行更改,Session session2 = sessionFactory.openSession(); /,开启连接,tx = session2.beginTransaction(); /,开启事务,session2.update(emp);,.,pubic class EmpDAO,public static Employee getEmployeeById(Integer id),Session session = sessionFactory.openSession(); /,开启连接,tx = session.beginTransaction(); /,开启事务,Employee emp = (Employee)session.get(Employee.class, id); /,根据主键加载,mit();,session.close();,.,忽略了异常处理,return emp;,Employee emp = EmpDAO.getEmployeeById(10011) ;,/,此时,emp,是什么状态?,emp.setEmpName(“AA”);,/,数据库中,empName,值是什么?,加载策略介绍,我们知道,,Hiberante,是一个,ORM,工具,它使得我们能够直接去操纵对象而不是数据库中表。,Hibernate,的数据检索策略也是给予对对象的操作的。数据检索策略主要包括一下几种:立即加载,延迟加载,预先抓取和批量加载。其中前三个是统一级别的,三个当中智能选择其中一个,而批量加载则可以很好的整合前面三个,还有就是预先抓取和批量加载都是为了优化前面两种方式而形成的。同时对于配置文件中的某个属性一旦设为预先抓取,则其它的数据检索方式都对这个属性失效。 下面分别进行讨论:,1,立即检索,:立即检索的时候需要在配置文件添加属性,lazy=false.,当,Hibernate,在从数据库中取得字段值组装好一个对象后,会立即再组装此对象所关联的对象,如果这个对象还有关联对象,再组装这个关联对象;对于一对一和多对一的多的这段默认是采用立即加载,所以不需要配置;多对多和一对多就要配置,lazy= false,。,2,延迟加载,:延迟加载不同,当组装完一个对象后,不立即组装和它关联的对象。 多对多和一对多默认采用延迟加载,一对一和多对一想实现延迟加载得配置,lazy= true,。,3,预先抓取,:,Hibernate 2.x,版本:,outer-join=true Hibernate 3.x,版本:,fetch=join,。和立即检索相比,预先抓取可以减少,SQL,语句的条数,提高查询速度。,4,批量加载,:批量加载总是和立即加载或者延迟加载联系在一起的,分别为批量立即加载和批量延迟加载。,Hibernate,加载策略,为了提高效率,节省资源,提供了多种数据检索策略,立即加载,延迟加载,预先抓取,批量加载,同时使用,同时使用,立即加载,从数据库取得字段值组装好一个对象后,会立即从数据库取出关联的附属对象,脱离,Session,后仍可以使用这些附属对象,立即加载的适用情况:,加载对象时,马上就要用到附属对象的数据,一对一、多对一被关联对象是”一”这端的,立即加载的配置为,lazy=“false”,一对一、多对一默认就是立即加载,所以只有一对多、多对多的立即加载需要在,元素中指定,lazy=“false”,延迟加载,从数据库取得字段值组装好一个对象后,并不会立即取出附属对象。这样做通常是为了节约内存资源,因为一对多、多对多关系如果设置为立即加载,将有可能会加载很多的附属对象而占据大量内存,因此这种情况常设置为延迟加载,多对一、一对一设置延迟加载只需在,标签中设置,lazy=“true”,加载策略举例,一对一默认立即加载、一般不改动,一对多默认延迟加载,通过设置,lazy=”false”,、或,fetch=”join”,实现立即加载,但一般一对多尽量设成,lazy=”true”,,当要实现立即加载时通过,HQL,语句的预先抓取,join fetch,实现,多对一默认延迟加载,通过设置,lazy=”false”,或,fetch=”join”,实现立即加载,下面以部门加载员工(一对多)为例:,部门对员工的加载策略配置如下:,false:,加载部门时立即加载员工,true:,加载部门时不加载员工,/,根据部门,OID,查找部门,public Department getDeptById(Integer oid),Session session = HibernateSessionFactory.,getSession,();,Transaction tx = session.beginTransaction();,Department dept = (Department)session.get(Depaertment.class, oid);,Set emps = dept.getEmployees();/,不过采用何种加载方式,这里没有错误,mit();,session,.close();,return dept;,Set emps = dept.getEmployees();/,如果,lazy=“true”,,这里将出错,显示部门详细信息,如果部门对员工采用的是延迟加载,那么这里将会出错,lazy=”false”,与,fetch=“join”,的区别,1,、,lazy=”false”,,立即加载,一次只查一个表。产生语句过多,如果数据多的话查询效率较低,2,、,fetch=”join”,使用连接查询,减少查询次数,提交查询效率,下面通过例子说明:,lazy=”false”,部门对员工采用,lazy=”false”,立即加载员工的配置及代码:, ,public static void main(String args)Session session = HibernateSessionFactory.,getSession,();,Transaction tx = session.beginTransaction();Department dept = (Department)session.get(Department.class, 51);mit();session.close();System.out.println(,部门名称:,+dept.getDeptName();Set emps = dept.getEmployees();for (Iterator iter = emps.iterator(); iter.hasNext();) Employee emp = (Employee) iter.next();System.out.println(,员工名字:,+emp.getEmpName();,lazy=”false”,执行,main,方法,得到控制台信息:,fetch=join,部门对员工采用,fetch=join,预先抓取员工的配置及代码:, ,public static void main(String args)Session session = HibernateSessionFactory.,getSession,();,Transaction tx = session.beginTransaction();Department dept = (Department)session.get(Department.class, 51);mit();session.close();System.out.println(,部门名称:,+dept.getDeptName();Set emps = dept.getEmployees();for (Iterator iter = emps.iterator(); iter.hasNext();) Employee emp = (Employee) iter.next();System.out.println(,员工名字:,+emp.getEmpName();,fetch=join,执行,main,方法,得到控制台信息:,我们可以很明显的看出,查询同样的数据,采用,fetch=“join”,比用,lazy=“false”,少了两条语句,提高了查询效率;当然,数据量越多,减少的,sql,语句就越多,这里还得注意,如果你使用了,fetch=“join”,,那么,HQL,语句会忽略配置文件中的立即加载(当部门对员工,fetch=”join”,并且使用,HQL,语句”,from Department”,不会取出员工)。,inverse,属性,inverse,属性表示将关系转由对方维护,session =,HibernateSessionFactory.,getSession,();,/,开启连接,tx = session.beginTransaction(); /,开启事务,Department dept =(Department) session.get(Departemt.class,oid);,dept.getEmployees.add(emp);/inverse=false,mit();,session =,HibernateSessionFactory.,getSession,();,/,开启连接,tx = session.beginTransaction(); /,开启事务,Department dept=(Department ) session.get(Department.class,oid);,emp.setDepartment(dept);,empdao.saveObject(emp); /inverse=true,mit();,insert into Employee values(?,?,?),update Employee set deptId=?,insert into Employee values(?,?,?),总结,加载策略介绍,lazy=”false”,与,fetch=“join”,的区别,inverse=”true”,insert=”false” update=”false”,
展开阅读全文