Hibernatelab--检索策略

    技术2022-05-20  71

    类级别的检索策略 立即检索 延迟检索一对多和多对多关联的检索策略 立即检索 延迟检索  迫切左外连接检索 <Set>元素的lazy和outer-join属性:  lazy属性  outer-join属性  false  false   采用立即检索策略,这是默认的检索策略  false  true   采用迫切左外连接  true  false   采用延迟检索策略,这是有限考虑使用的检索策略  true  true   没有任何意义  多对一个关联的检索策略 立即检索 延迟检索  迫切左外连接检索 在应用程序中显示指定迫切左外连接策略 应用程序中设置的检索策略是固定的,Hibernate允许在应用程序中覆盖映射文件中设定的检索策略,由应用程序在运行时决定检索的深度   总结: 检索类型      优点       缺点 立即检索    不管对象处理持久化状态还是  select语句多      游离状态,可以方便地从一个对  加载应用程序不需要      象导航到关联的另一个对象   访问的对象浪费内存-------------------------------------------------------------------------- 延迟检索    由应用程序决定需要加载哪些对  应用程序如果需要访问      象,避免执行过多SQL语句以及避  游离状态的代理类实例,      免加载应用程序不需要访问的对  必须保证它在持久化状      象,提高检索性能,节省内存   态时已经被初始化-------------------------------------------------------------------------- 迫切左外    不管对象处于持久化状态还是游  可能会加载应用程序不需要     连接     离状态,应用程序都可以方便地从  访问的对象浪费内存      一个对象导航到管理的另一个对象 复杂的表连接影响检索性能      同时使用外连接减少了SQL语句

     

    ---------------------------------------------------------------------------------------------------------------------------------------------------

     

    package org.niit.ormlab.example4; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class Depart implements Serializable { private Integer did; private String dname; private String ddesc; private Set<Emp> emps = new HashSet<Emp>();//为了提高程序健壮性我们实例化这个属性避免产生空指针异常 public Depart(String dname, String ddesc, Set<Emp> emps) { super(); this.dname = dname; this.ddesc = ddesc; this.emps = emps; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } public Depart() { } public Depart(String dname, String ddesc) { super(); this.dname = dname; this.ddesc = ddesc; } public Depart(Integer did, String dname, String ddesc) { super(); this.did = did; this.dname = dname; this.ddesc = ddesc; } public Integer getDid() { return did; } public void setDid(Integer did) { this.did = did; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getDdesc() { return ddesc; } public void setDdesc(String ddesc) { this.ddesc = ddesc; } }

     

    package org.niit.ormlab.example4; import java.io.Serializable; import java.util.*; public class Emp implements Serializable { private int eid; private String ename; private String esex; private String eaddr; private String etel; private Depart depart;//many to one private Set<Role> roles = new HashSet<Role>();//多对多 public Emp() { // TODO Auto-generated constructor stub } public Emp(String ename, String esex, String eaddr, String etel, Depart depart, Set<Role> roles) { super(); this.ename = ename; this.esex = esex; this.eaddr = eaddr; this.etel = etel; this.depart = depart; this.roles = roles; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } public Emp(int eid, String ename, String esex, String eaddr, String etel, Depart depart, Set<Role> roles) { super(); this.eid = eid; this.ename = ename; this.esex = esex; this.eaddr = eaddr; this.etel = etel; this.depart = depart; this.roles = roles; } public Emp(String ename, String esex, String eaddr, String etel, Depart depart) { super(); this.ename = ename; this.esex = esex; this.eaddr = eaddr; this.etel = etel; this.depart = depart; } public Emp(int eid, String ename, String esex, String eaddr, String etel, Depart depart) { super(); this.eid = eid; this.ename = ename; this.esex = esex; this.eaddr = eaddr; this.etel = etel; this.depart = depart; } public int getEid() { return eid; } public void setEid(int eid) { this.eid = eid; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getEsex() { return esex; } public void setEsex(String esex) { this.esex = esex; } public String getEaddr() { return eaddr; } public void setEaddr(String eaddr) { this.eaddr = eaddr; } public String getEtel() { return etel; } public void setEtel(String etel) { this.etel = etel; } public Depart getDepart() { return depart; } public void setDepart(Depart depart) { this.depart = depart; } }

     

    package org.niit.ormlab.example4; import java.io.Serializable; import java.util.*; public class Role implements Serializable { private int rid; private String rname; private String rdesc; private Set<Emp> emps = new HashSet<Emp>();//many to many public Role(String rname, String rdesc) { super(); this.rname = rname; this.rdesc = rdesc; } public Role(String rname, String rdesc, Set<Emp> emps) { super(); this.rname = rname; this.rdesc = rdesc; this.emps = emps; } public Role() { super(); } public Role(int rid, String rname, String rdesc, Set<Emp> emps) { super(); this.rid = rid; this.rname = rname; this.rdesc = rdesc; this.emps = emps; } public int getRid() { return rid; } public void setRid(int rid) { this.rid = rid; } public String getRname() { return rname; } public void setRname(String rname) { this.rname = rname; } public String getRdesc() { return rdesc; } public void setRdesc(String rdesc) { this.rdesc = rdesc; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } }

     

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping package="org.niit.ormlab.example4"> <!-- 多对一的【一方】 --> <class name="Depart" table="`Depart`"> <id name="did" column="did" type="integer"> <generator class="identity" /> </id> <property name="dname" column="dname" type="string" /> <property name="ddesc" column="ddesc" type="string" /> <!-- 级联保存更新 --> <set name="emps" table="`Emp`" cascade="save-update,delete" lazy="false" outer-join="true"> <!-- 外键信息 --> <key column="did"></key> <!-- 属性对应的类信息 --> <one-to-many class="Emp"/> </set> </class> </hibernate-mapping>

     

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping package="org.niit.ormlab.example4"> <!-- 多对一的【多方】 --> <class name="Emp" table="`Emp`"> <id name="eid" column="eid" type="integer"> <generator class="identity" /> </id> <property name="ename" column="ename" type="string" /> <property name="esex" column="esex" type="string" /> <property name="etel" column="`etel`" type="string"/> <property name="eaddr" column="eaddr" type="string" /> <!-- many-to-one建立depart属性和外键did之间的映射 name=待映射的持久化类的属性名【Emp类的depart属性】 class=持久化类名 cascade=级联行为 not-null=是否允许为空,影响Hibernate的保存时行为 --> <many-to-one name="depart" class="Depart" column="did" cascade="save-update" not-null="true"/> <set name="roles" cascade="save-update" table="`roleemp`" lazy="true" inverse="true" > <key column="eid" not-null="true"></key> <many-to-many class="Role" column="rid"/> </set> </class> </hibernate-mapping>

     

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping package="org.niit.ormlab.example4"> <!-- 多对一的【多方】 --> <class name="Role" table="`Role`"> <id name="rid" column="rid" type="integer"> <generator class="identity" /> </id> <property name="rname"></property> <property name="rdesc"></property> <set name="emps" cascade="save-update" lazy="true" table="roleemp" > <key column="rid" not-null="true"></key> <many-to-many class="Emp" column="eid" /> </set> </class> </hibernate-mapping>

     

    测试一:

    package org.niit.ormlab.example4; import java.util.List; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Restrictions; /** * 类级别的检索策略 立即检索 延迟检索【将检索的时期推迟到使用对象的时候,检索前得到的是拥有OID值的代理对象,真正 检索时使用这个OID去查询】 * */ public class Client1 { /** * Depart类默认为延迟检索【lazy="true"】,因此以下查询首次并不会执行查询,但是当使用这个对象的时候立即执行查询 * */ public void getDepart1(){ Session session = SessionFactory.getSession(); //由于采用延迟检索,以下语句并不会执行sql查询[观察输出结果] System.out.println("---------查询这个对象的时候-------------------------"); Depart d = (Depart)session.load(Depart.class, 19); System.out.println("代理对象的OID值是:"+d.getDid()); System.out.println("---------使用这个对象的时候------------"); System.out.println(d.getDid()+"/t"+d.getDname()); } /** * Depart类默认为延迟检索【lazy="true"】,我们将其设置为lazy="false",因此以下查询并会立即执行查询 * */ public void getDepart2(){ Session session = SessionFactory.getSession(); //由于采用延迟检索,以下语句并不会执行sql查询[观察输出结果] Depart d = (Depart)session.load(Depart.class, 19); } /** * 任何情况下使用get()方法和gind()方法在类级别总是执行立即检索 * */ public void getDepart3(){ Session session = SessionFactory.getSession(); Depart d = (Depart)session.get(Depart.class, 19); } /** * 如何主动初始化延迟检索前得到的代理对象 * */ public void getDepart4(){ Session session = SessionFactory.getSession(); Depart d = (Depart)session.load(Depart.class, 19); session.close();//关闭Session System.out.println(d.getDid());//访问代理对象的OID不会有任何错误 System.out.println(d.getDname());//访问代理对象的其它属性会引起”初始化代理对象“,但是这个代理对象拥有的Session已经关闭,因此该句将抛出异常 } /** * 如何主动初始化延迟检索前得到的代理对象 * */ public void getDepart5(){ Session session = SessionFactory.getSession(); Depart d = (Depart)session.load(Depart.class, 19); if (!Hibernate.isInitialized(d)){ Hibernate.initialize(d);//如果没有初始化代理对象则主动初始化它 } session.close();//关闭Session System.out.println(d.getDid());//访问代理对象的OID不会有任何错误 System.out.println(d.getDname());//访问代理对象的其它属性不会引起”初始化代理对象“,虽然这个代理对象拥有的Session已经关闭,但关闭前已经被初始化 } public static void main(String[] args) { Client1 c = new Client1(); //c.getDepart1(); //c.getDepart4(); c.getDepart5(); } }

     

    测试二:

    package org.niit.ormlab.example4; import org.hibernate.Session; /** * 一对多和多对多关联的检索策略 立即检索 延迟检索 迫切左外连接检索 <Set>元素的lazy和outer-join属性: lazy属性 outer-join属性 false false 采用立即检索策略,这是默认的检索策略 false true 采用迫切左外连接 true false 采用延迟检索策略,这是有限考虑使用的检索策略 true true 没有任何意义 * */ public class Client2 { /** * 立即检索示范(lazy="false",outer-join="false") * */ public void getDepart1(){ Session session = SessionFactory.getSession(); try { Depart d = (Depart)session.get(Depart.class,19);//执行对Depart和管理的Emp的检索 } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { session.close(); } } /** * 延迟检索示范(lazy="true",outer-join="false") * */ public void getDepart2(){ Session session = SessionFactory.getSession(); try { Depart d = (Depart)session.get(Depart.class,19);//只执行对Depart的检索 } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { session.close(); } } /**没有采用迫切左外连接检索(lazy="false" outer-join="false"),对Depart和Emp执行两次查询*/ public void getDepart3(){ Session session = SessionFactory.getSession(); try { Depart d = (Depart)session.get(Depart.class,19);//只执行对Depart的检索 } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { session.close(); } } /**采用迫切左外连接检索(lazy="false" outer-join="true"),对Depart和Emp执行一次左外连接查询 * 但是session.find()会忽略outer-join这个属性而总是采用立即检索策略*/ public void getDepart4(){ Session session = SessionFactory.getSession(); try { Depart d = (Depart)session.get(Depart.class,19);//只执行对Depart的检索 for (Emp e : d.getEmps()) { System.out.println(e.getEname()); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { session.close(); } } /** * 在应用程序显示指定迫切左外连接策略,将覆盖映射文件中的检索策略 * :检索部门编号为18的部门信息及其员工信息 * */ public void getDepart5(){ Session session = SessionFactory.getSession(); try { Depart d = (Depart)session .createQuery("from Depart as d left join fetch d.emps where d.did=18") .uniqueResult(); //由于已经检索处部门信息及其员工信息,因此我们可以关闭Session后使用这个信息 session.close(); System.out.println(d.getDid()+"/t"+d.getDname()); for (Emp e : d.getEmps()) { System.out.println("/t"+e.getEid()+"/t"+e.getEname()+"/t"+e.getEsex()); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { if (session.isOpen()) session.close(); } } public static void main(String[] args) { Client2 c = new Client2(); //c.getDepart4(); c.getDepart5(); } }


    最新回复(0)