Hibernate 检索策略

Hibernate 检索策略

1.       类级别检索策略

1.1          立即检索

1.2          延迟检索

2.       一对多和多对多关联的检索策略

21 批量延迟和批量立即检索

21 迫切左外连接检索

3.多对一和一对多关联的检索策略。

31 迫切左外连接检索

32延迟检索

33立即检索

34批量延迟检索和批量立即检索

 

 

类级别检索策略

     类级别可选的检索策略包括立即检索和延迟检索,默认为立即检索 . 如果<class>元素的 lazy 属性为 true ,标识采用延迟检索; 如果lazy 属性为 false ,表示采用立即检索. Lazy 属性的默认值为 false.

以下示例演示了 lazy = true lazy = false 的区别

<class name="com.test.pojo.Person" table="person" schema="dbo"                          catalog="studyHibernate" lazy="false">

Person person  = (Person)session.load(Person.class, new Integer(47));

以上代码立即检索. 执行 select 查询语句.

更改:  lazy="true" 

当执行:   person.getPersonName(); 时才执行 select 语句.

不管 Session get() 方法和 createQuery() 方法在类级别中总是使用立即检索.

 

一对多和多对多关联的检索策略.

    在映射文件中,<set>元素来配置一对多关联以及多对多关联关系.

   <set>  元素有 lazy outer-join 属性

    一对多关联默认的检索策略为立即检索.

    对于 <set> 元素应该优先考虑使用延迟检索策略.

    <set name = “adds” inverse=”true” lazy=”true”>

 

    以下代码演示了<set>元素中的 lazy 属性的用法.

       Person person  = (Person)session.load(Person.class, new Integer(47));

       person.getPersonName();

       // Iterator ite = person.getAdds().iterator();

 

 

       <set name="adds" cascade="all" lazy="true" >

           <key column="personId"/>

           <one-to-many class="com.test.pojo.Adds"/>

        </set>

 

如果把 lazy = “true” 时表示延时检索 只执行一条 SQL语句

如果把 lazy = “false” 时表示立即检索 ,执行两条 SQL语句

 

批量延迟检索和批量立即检索

<set> 元素有一个 batch-size 属性,用于为延迟检索或立即检索策略设定批量检索的数据.批量检索能减少 select 语句的数目,提高延迟检索或者立即检索的性能.

以下代码检索所有的 person 对象(以下代码属于批量立即检索.):

<set name="adds" cascade="all" lazy="false" batch-size="6" >

List list = session.createQuery

                         ("from Person as person").list();

Iterator ite = list.iterator();

 

以下代码实现批量延迟检索:

<set name="adds" cascade="all" lazy="true" batch-size="6" >

 

List list = session.createQuery

                       ("from Person as person").list();

Iterator ite = list.iterator();

while(ite.hasNext()){

     Person person = (Person)ite.next();

     Iterator ite1 = person.getAdds().iterator();

     while(ite1.hasNext()){

          Adds adds = (Adds)ite1.next();

          System.out.println(adds.getAddName());

      }

}

 

多对一和一对多关联的检索策略

在映射文件中,<many-to-one><one-to-one> 元素分别用来设置多对以和一对一关联关系.

       <many-to-one name=”” column=”” class=””/>

<many-to-one> 元素的 outer-join属性有三个可选值得:

1.  auto:默认值,如果 person.hbm.xml <class>元素的 lazy 属性为 true,那么对与 Adds 关联的 Person 对象采用延迟检索策略;否则采用迫切左外连接检索策略.

2.   

 

 

 

 

以下代码演示立即检索 

<class name="com.test.pojo.Person" table="person" schema="dbo"                          catalog="studyHibernate" lazy="false">

 

<many-to-one name="person" column="personId"                                      class="com.test.pojo.Person" outer-join="false"/>

 

Adds adds = (Adds)session.get(Adds.class, new Integer(43));

Person person = adds.getPerson();

 

如果把 class lazy 属性值改为:lazy = “true” 为延迟检索.

<class name="com.test.pojo.Person" table="person" schema="dbo"                          catalog="studyHibernate" lazy="false">

 

 

以下代码批量延迟检索:

<class name="com.test.pojo.Person" table="person" schema="dbo" catalog="studyHibernate" lazy="true" batch-size="3">

 

// lazy="false"      批量立即检索

 

<many-to-one name="person" column="personId"                                      class="com.test.pojo.Person" outer-join="false"/>

 

List list  = session.createQuery("from Adds a").list();

      for(int i=0;i<list.size();i++){

        Adds adds = (Adds)list.get(i);

        Person person = adds.getPerson();

        person.getPersonName();

      }

   

 

 

 

 

 

 

 

 

 

Hql查询方式:

以下代码通过查询条件显示数据:

   List list = session.createQuery(

   "from Person p where p.personName = :personName")

   .setString("personName", "scott").list();

 

Hql  like 查询

   List list = session.createQuery(

      "from Person p where p.personName like :personName ")

      .setString("personName", "%a%").list();

 

查询指定范围值:

List list = session.createQuery("from Person p where p.id     > :pid and p.id < :nid")

   .setInteger("pid", new Integer(60))

   .setInteger("nid",new Integer(70))

   .list();

 

for(int i=0;i<list.size();i++){

   Person person = (Person)list.get(i);

   System.out.println("--- id ="+person.getPersonid());

   System.out.println("--- name="+person.getPersonName());

}

在映射文件中定义命名查询语句

Person.hbm.xml 定义如下:

    <query name="findPersonByname">

       <![CDATA[ from Person p where p.personName like :name]]>

</query>

 

程序代码如下:

List list = session.getNamedQuery("findPersonByname")

           .setString("name","%a%").list();

Hql  翻页查询:

   setFirstResult(int firsResult):设定从哪个对象开始检索,参数表示这个对象在查询结果中的索引位置,索引起始值为 0.

   setmaxResult(int maxResult):设定一次最多检索出的对象数目.

以下示例演示了翻页操作 :

      List list = session.createQuery("from Person               p").setFirstResult(5)

           .setMaxResults(5).list();

 

HQL 投影查询:

投影查询是指查询结果仅包括部分实体或者实体的部分属性. 投影是通过 select 关键字来实现的.

 

Hql 投影查询中使用 聚合函数:

 

Query query = session

           .createQuery(

                 "select  max(id) as max,min(id) as min ,sum(id) as sum ,personName from Person group by personName order by personName desc");

List list = query.list();

for (int i = 0; i < list.size(); i++) {

   Object[] object = (Object[]) list.get(i);

   Integer maxid = (Integer) object[0];

   Integer minid = (Integer) object[1];

   Integer sumid = (Integer) object[2];

   String personName = (String)object[3];

   System.out.println("----- maxid =" + maxid);

   System.out.println("----- minid =" + minid);

   System.out.println("----- sumid=" + sumid);

   System.out.println("----- personName ="+personName);

}

 

 

也可以返回类实例:

Query query = session.createQuery("select new com.test.pojo.MyPerson(p.personid,p.personName,p.email) from Person p where p.personName like :personName")

           .setString("personName", "%a%");

      List list = query.list();

      Iterator ite = list.iterator();

      while(ite.hasNext()){

        MyPerson myperson = (MyPerson)ite.next();

}

 

 

 

在运行 session.load()方法时,Hibernate 不会执行任何select 语句,仅仅返回 Customer 类的代理类实例,它的OID 为:100 ,由 load() 方法的第二个参数决定,当程序调用 customer.getName() 方法时,Hibernate 会初始化 Customer 代理类实例。

       Session session = HibernateSessionFactory.getSession();

       Transaction transaction = session.beginTransaction();

           Employee employee =

       (Employee) session.load(Employee.class, new   Integer(100));

           System.out.println("--- employee id ="+employee.getId());

           Employee.getName();

       transaction.commit();

       session.close();

 

 

以下代码试图在关闭session 后访问 Customer 游离对象。

    Session session = HibernateSessionFactory.getSession();

       Transaction transaction = session.beginTransaction();

       Employee employee =

           (Employee) session.load(Employee.class, new Integer(40));

       transaction.commit();

       session.close();

       System.out.println("---- employee name ="+employee.getName());

以上代码在Session 范围内始终没有被初始化,在执行employee.getName() 时会抛出异常。必须在 session 范围内要初始化对象。

    Transaction transaction = session.beginTransaction();

       Employee employee =

                            (Employee) session.load(Employee.class, new Integer(40));

              if(!Hibernate.isInitialized(employee)){

                     Hibernate.initialize(employee);

              }

       transaction.commit();

       session.close();

 

当应用程序访问代理类实例的 getId() 方法时,不会触发 Hibernate 初始化代理类实例的行为。

    Transaction transaction = session.beginTransaction();

        Employee employee =

                            (Employee) session.load(Employee.class, new Integer(40));

          Employee.getId();

        transaction.commit();

        session.close();

 

 

 

不管 xml文件中的<class>元素的 lazy 属性是 true 还是 false, session get()方法总是使用立即检索策略.

 

 批量延迟检索:

  例如:

      <set  name=”     inverse=”true”  lazy = “true”  bach-size=5>

 

批量立即检索:

例如:

      <set  name=”     inverse=”true”  bach-size=5>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值