Java实战之02Hibernate-05检索策略、检索方式

十一、Hibernate的检索策略

1、概述:

查询的时机:什么时候去查?

 1 /**
 2  * 一张表的检索策略我们称之为:
 3  *     类级别的检索策略。
 4  *  注意:只要是说类级别的检索策略,就一定不涉及关联对象。
 5  *
 6  * 类级别检索策略解决的问题:
 7  * 1、查询的时机:
 8  *         分为两种情况
 9  *             立即加载:不管用不用,都马上查询出来
10  *             延迟加载:什么时候用,什么时候去查询。(懒加载,惰性加载)
11
12  *
13  *常用方法:
14  *    get:
15  *        永远都是立即加载。返回的当前实体类的对象。
16  *    load
17  *      默认情况下是延迟加载。返回的当前实体类的代理对象。
18  *      它可以改为立即加载。
19  *      在对应的映射文件中,class元素使用lazy属性,把值改为false
20  *      lazy取值:true 延迟加载(默认值)。false是立即加载。
21  *      例如:
22  *      <class name="Customer" table="T_CUSTOMERS" lazy="false">
23  * query的list方法:
24  *         永远都是立即加载。
25  *
26  * @author zhy
27  *
28  */
29 public class HibernateDemo1 {
30
31     /*
32      * 不管用不用,都立即查询出一个客户的所有字段数据
33      */
34     @Test
35     public void test1(){
36         Session s = HibernateUtil.getSession();
37         Transaction tx = s.beginTransaction();
38         //查询id为1的客户
39         Customer c1 = s.get(Customer.class, 1);
40         System.out.println(c1);
41         tx.commit();
42         s.close();
43
44     }
45     /*
46      * 什么时候用什么时候真正去查询
47      */
48     @Test
49     public void test2(){
50         Session s = HibernateUtil.getSession();
51         Transaction tx = s.beginTransaction();
52         //查询id为1的客户
53         Customer c1 = s.load(Customer.class, 1);
54         System.out.println(c1);
55         tx.commit();
56         s.close();
57
58     }
59 }

2、类级别的检索策略

只影响Session的load()方法

Session.get()方法:永远都是立即加载。

 1 /*
 2      * 不管用不用,都立即查询出一个客户的所有字段数据
 3      */
 4     @Test
 5     public void test1(){
 6         Session s = HibernateUtil.getSession();
 7         Transaction tx = s.beginTransaction();
 8         //查询id为1的客户
 9         Customer c1 = s.get(Customer.class, 1);
10         System.out.println(c1);
11         tx.commit();
12         s.close();
13
14     }

Query.list()方法:立即检索。

Session.load()方法:默认是延迟加载。(load可以改为立即加载,lazy="false")

 1 @Test
 2     public void test2(){
 3         Session s = HibernateUtil.getSession();
 4         Transaction tx = s.beginTransaction();
 5         //查询所有客户
 6         Query query = s.createQuery("from Customer");
 7         List<Customer> cs = query.list();
 8         //获取每个客户的所有订单
 9         for(Customer c : cs){
10             System.out.println(c);
11             System.out.println(c.getOrders());
12         }
13         tx.commit();
14         s.close();
15     }
 1 /*
 2      * 什么时候用什么时候真正去查询
 3      */
 4     @Test
 5     public void test2(){
 6         Session s = HibernateUtil.getSession();
 7         Transaction tx = s.beginTransaction();
 8         //查询id为1的客户
 9         Customer c1 = s.load(Customer.class, 1);
10         System.out.println(c1);
11         tx.commit();
12         s.close();
13
14     }

3、关联级别的检索策略

概念:比如查询客户(类级别),所关联的订单的查询(关联级别)。

3.1、检索关联多的一方

应用场景:

一对多:根据客户查询订单

多对多:根据老师查询学生

配置:

 1 <hibernate-mapping package="cn.itcast.domain">
 2     <class name="Customer" table="T_CUSTOMERS">
 3         <id name="id" column="id">
 4             <generator class="native"></generator>
 5         </id>
 6         <property name="name" column="NAME"></property>
 7         <property name="age" column="AGE"></property>
 8         <!-- 一对多关系映射:
 9             set元素:
10                 作用:映射集合元素
11                 属性:
12                     name:映射实体类中的集合属性
13                     table:指定对应的表
14             key元素:它是set的子元素
15                 作用:就是用于指定外键的
16                 属性:
17                     column:指定外键字段的名称
18             one-to-many元素:它是set的子元素
19                 作用:描述当前实体映射文件和set中指定属性之间的关系。
20                 属性:
21                     class:指定是从表的实体类名称
22         -->
23         <set name="orders" table="T_ORDERS" lazy="true" fetch="join">
24             <key column="CUSTOMER_ID"></key>
25             <one-to-many class="Order"/>
26         </set>
27     </class>
28 </hibernate-mapping>

lazy:查询的时机(何时真正去查)。取值如下:

true:延迟加载

false:立即加载

fetch:查询的语句的形式。取值如下:

select:多条查询语句。

subselect:子查询。推荐

join:左外连接查询

说明:(必须搞明白)


序号


lazy的取值


fetch的取值


说明(都是以客户订单的一对多关系为例)


1


true(默认值)


select(默认值)


时机:用时才真正去查询订单。

语句形式:有1条查询客户的和多条查询订单的select语句。

Batch-size:设置批量检索的深度。(建议3~10之间)


2


false


select(默认值)


时机:不管用不用订单,查询客户时都立即查询订单。

语句形式:有1条查询客户的和多条查询订单的select语句。

Batch-size:设置批量检索的深度。(建议3~10之间)


3


extra


select(默认值)


时机:用什么信息,查什么信息。只查询必要的。

语句形式:有1条查询客户的和多条查询订单的select语句。

batch-size:设置批量检索的深度。(建议3~10之间)


4


true


subselect


时机:用时才真正去查询订单。

语句形式:子查询

batch-size:无效


5


false


subselect


时机:不管用不用订单,查询客户时都立即查询订单。

语句形式:子查询

batch-size:无效


6


extra


subselect


时机:用什么信息,查什么信息。只查询必要的。

语句形式:子查询

batch-size:无效


7


true|false|extra


join(当join有效时,根本不看lazy属性)


时机:无效。因为连接查询,一次就是两张表及以上。

语句:left outer join

batch-size:无效

注意:Query查询会忽略join的存在。当join无效时,lazy就有效了。

  1 /**
  2  * 关联级别的检索策略
  3  * 注意:
  4  *      它永远说的是查询当前实体类时,要不要查询那个关联的对象。
  5  *     涉及的是:一对多,多对一,多对多和一对一。
  6  *     举例:
  7  *       一对多和多对一
  8  *         查询客户的时候要不要查询订单:一对多的情况
  9  *         查询订单的时候要不要查询客户:多对一的情况
 10  *   多对多
 11  *       查询教师的时候要不要查询学生:多对多的情况
 12  *   一对一
 13  *       查询人员的时候要不要查询身份证号:一对一的情况
 14  *
 15  * 解决的问题:
 16  *     1、查询的时机
 17  *         立即加载:不管用不用,都马上查询出来
 18  *         延迟加载:什么时候用,什么时候真正去查询
 19  *  2、查询的方式(怎么查)
 20  *      多条SQL语句
 21  *      子查询
 22  *      表连接
 23  * 关于关联级别的检索策略,有如下配置
 24  *     明确:是有少的一方,根据少的一方,去检索多的一方
 25  *     举例说明:
 26  *         我们有客户,根据客户获取订单。/ 我们有一个教师,根据这个教师获取学生
 27  * 配置涉及的属性:
 28  *     lazy:加载的时机
 29  *         true:延迟加载(默认值)
 30  *         false:立即加载
 31  *         extra:极懒加载 (用什么查什么,不用的都不查)
 32  *     fetch:检索的方式
 33  *         select:多条SQL语句(默认值)
 34  *         subselect:子查询
 35  *         join:左外连接
 36  *
 37  * 我们现在是在映射文件的set元素上配置!
 38  *
 39  * @author zhy
 40  *
 41  * 第四种情况:lazy="true" fetch="subselect"
 42  * <set name="orders" table="T_ORDERS" lazy="true" fetch="subselect">
 43  *
 44  */
 45 public class HibernateDemo5 {
 46
 47     /*
 48      * 需求:
 49      *     查询所有客户,获取每个客户的所有订单
 50      * 查询的时机:
 51      *     延迟加载
 52      * 查询的方式:
 53      *     子查询
 54      *      select * from T_ORDERS  where CUSTOMER_ID in (select id from T_CUSTOMERS )
 55      * 注意:
 56      *     当使用了子查询之后,batch-size属性就失效了。
 57      *
 58      */
 59     @Test
 60     public void test2(){
 61         Session s = HibernateUtil.getSession();
 62         Transaction tx = s.beginTransaction();
 63         //查询所有客户
 64         Query query = s.createQuery("from Customer");
 65         List<Customer> cs = query.list();
 66         //获取每个客户的所有订单
 67         for(Customer c : cs){
 68             System.out.println(c);
 69             System.out.println(c.getOrders());
 70         }
 71         tx.commit();
 72         s.close();
 73     }
 74
 75
 76     /*当我们的fetch属性是subselect时,查询一个客户,并且获取该客户的订单,和取默认值没有区别。
 77      * 因为:
 78      *     select * from t_orders where customer_id = 1;
 79         select * from t_orders where customer_id in (1);
 80            是一回事。
 81      *
 82      *
 83      * 需求:
 84      *     查询一个客户,获取该客户的所有订单
 85      * 查询的时机:
 86      * 查询的方式:
 87     */
 88     @Test
 89     public void test1(){
 90         Session s = HibernateUtil.getSession();
 91         Transaction tx = s.beginTransaction();
 92         //查询一个客户
 93         Customer c1 = s.get(Customer.class, 1);//客户说的是类级别的检索策略
 94         System.out.println(c1);
 95         //获取当前客户的所有订单
 96         System.out.println(c1.getOrders());
 97         tx.commit();
 98         s.close();
 99     }
100 }
 1 /**
 2  * 关联级别的检索策略
 3  * 注意:
 4  *      它永远说的是查询当前实体类时,要不要查询那个关联的对象。
 5  *     涉及的是:一对多,多对一,多对多和一对一。
 6  *     举例:
 7  *       一对多和多对一
 8  *         查询客户的时候要不要查询订单:一对多的情况
 9  *         查询订单的时候要不要查询客户:多对一的情况
10  *   多对多
11  *       查询教师的时候要不要查询学生:多对多的情况
12  *   一对一
13  *       查询人员的时候要不要查询身份证号:一对一的情况
14  *
15  * 明确: 有多的一方要不要查询少的一方
16  * 举例说明:
17  *         有订单,要不要查询客户/有人员,要不要查询身份证号。
18  * 解决的问题:
19  *     1、查询的时机
20  *         立即加载:不管用不用,都马上查询出来
21  *         延迟加载:什么时候用,什么时候真正去查询
22  *  2、查询的方式(怎么查)
23  *      多条SQL语句
24  *      表连接
25  * 关于关联级别的检索策略,有如下配置
26  * 配置涉及的属性:
27  *     lazy:加载的时机
28  *         false:立即加载。不管对方类级别的检索策略
29  *         proxy:不确定。原因是要看对方类级别的检索策略。
30  *                   如果对方类级别检索策略是延迟加载,则proxy就是延迟加载。
31  *                   如果对方类级别检索策略是立即记载,则proxy就是立即加载。
32  *     fetch:检索的方式
33  *         select:多条SQL语句
34  *         join:左外连接
35  *
36  * 我们以多对一为例:配置都是在many-to-one上!
37  * @author zhy
38  *
39  * 第二种情况:lazy=proxy fetch=join
40  * <many-to-one name="customer" class="Customer" column="CUSTOMER_ID" lazy="proxy" fetch="join"/>
41  *
42  */
43 public class HibernateDemo11 {
44
45
46     /* 当fetch取值是join时,一下就查询2张表。就不管lazy属性如何配置。
47      *
48      * 需求:
49      *     查询一个订单,根据订单获取该订单的客户
50      * 查询的时机:
51      *         lazy属性失效
52      * 查询的方式:
53      *         左外连接
54      *
55      */
56     @Test
57     public void test1(){
58         Session s = HibernateUtil.getSession();
59         Transaction tx = s.beginTransaction();
60         //查询订单
61         Order o1 = s.get(Order.class, 1);
62         System.out.println(o1);
63         //根据订单,获取客户信息
64         System.out.println(o1.getCustomer());
65         tx.commit();
66         s.close();
67     }
68 }

3.2、检索关联少的一方

应用场景:(开发经验,少的一方,查出来就得了)

多对一:根据订单查询客户

一对一:根据人查询身份证

配置:

 1 <hibernate-mapping package="cn.itcast.domain">
 2     <class name="Order" table="T_ORDERS">
 3         <id name="id" column="id">
 4             <generator class="native"></generator>
 5         </id>
 6         <property name="ordernum" column="ORDERNUM"></property>
 7         <property name="money" column="MONEY"></property>
 8
 9         <!-- 多对一关系映射
10             使用的元素:many-to-one
11             属性:
12                 name:指定的是在实体类中要映射的属性
13                 class:指定该属性所对应的类
14                 column:指定外键字段。
15         -->
16         <many-to-one name="customer" class="Customer" column="CUSTOMER_ID" lazy="proxy" fetch="join"/>
17     </class>
18 </hibernate-mapping>

二、检索方式

1、检索方式概述

a) 对象导航方式:通过对象间的引用关系例如:customer.getOrder();

b) OID的检索方式:通过OID获取对象get和load

c) HQL检索方式:使用面向对象的HQL查询语言。

HQL:Hibernate Query Language 类似SQL。表明换类名

d) QBC检索方式:Query By Criteria,更加面向对象。了解。

e) 本地SQL检索方式:原生态的JDBC+SQL语句。了解。

2、单表各种查询(HQL条件,QBC条件,QBC特例,原始SQL,多态,排序,具名,命名,分页)

  1 /**
  2  * hibernate中提供的查询方式
  3  * @author zhy
  4  *
  5  */
  6 public class HibernateDemo1 {
  7
  8     /*
  9      * 对象导航查询
 10      *
 11      * 明确:
 12      *     思想的转变。我们在需要某些数据时,是否还要单独去写一个方法来实现。
 13      *
 14      * 对象导航的思想
 15      */
 16     @Test
 17     public void test17(){
 18         Session s = HibernateUtil.getSession();
 19         Transaction tx = s.beginTransaction();
 20         Order o1 = s.get(Order.class, 1);
 21         Customer c = o1.getCustomer();//对象导航的方式
 22         System.out.println(c);
 23         tx.commit();
 24         s.close();
 25     }
 26     @Test
 27     public void test15(){
 28         Session s = HibernateUtil.getSession();
 29         Transaction tx = s.beginTransaction();
 30         Customer c1 = s.get(Customer.class, 1);
 31         Set<Order> orders = c1.getOrders();//对象导航的方式
 32         System.out.println(orders);
 33         tx.commit();
 34         s.close();
 35     }
 36     /*原来JDBC时,留下的思想
 37     @Test
 38     public void test16(){
 39         List<Order> orders = findOrderByCustomerid(1);
 40         System.out.println(orders);
 41     }
 42
 43     public List<Order> findOrderByCustomerid(int customerid){
 44         Session s = HibernateUtil.getSession();
 45         Transaction tx = s.beginTransaction();
 46         //select * from t_orders where customer_id = ?;
 47         Query query = s.createQuery("from Order o where o.customer.id = ?");
 48         query.setInteger(0, customerid);
 49         List<Order> orders = query.list();
 50         tx.commit();
 51         s.close();
 52         return orders;
 53     }
 54     */
 55
 56     /*
 57      * 原生SQL查询
 58      *     使用的是session的createSQLQuery方法
 59      *     它的执行list结果是一个由Object数组组成的集合。
 60      *
 61      * 在实际开发中,我们一般不会使用Object数组来操作。
 62      * 而是在执行list()方法之前,调用addEntity方法,给sqlquery添加一个实体,
 63      * 从而得到的就是实体对象的集合
 64
 65     select
 66     sum(
 67         case when score between 0 and 59 then 1 else 0 end
 68     )  as E,
 69     sum(
 70         case when score between 60 and 69 then 1 else 0 end
 71     ) as D,
 72     sum(
 73         case when score between 70 and 79 then 1 else 0 end
 74     ) as C,
 75     sum(
 76         case when score between 80 and 89 then 1 else 0 end
 77     ) as B,
 78     sum(
 79         case when score between 90 and 99 then 1 else 0 end
 80     ) as A
 81  from t_students
 82
 83      */
 84     @Test
 85     public void test14(){
 86         Session s = HibernateUtil.getSession();
 87         Transaction tx = s.beginTransaction();
 88         SQLQuery sqlquery = s.createSQLQuery("select * from t_customers");//参数就是SQL语句
 89         //给SQLQuery添加一个实体
 90         sqlquery.addEntity(Customer.class);
 91         List list = sqlquery.list();
 92         tx.commit();
 93         s.close();
 94         for(Object o : list){
 95             System.out.println(o);
 96         }
 97
 98     }
 99     /*
100      * 分页查询
101      *     mysql中的分页查询:
102      *         使用的关键字:limit
103      *         关键字中的必要条件:firstResult(开始记录索引),maxResults(最大的结果集数)
104      * sql语句:select * from t_orders limit firstResult,maxResults;
105      *
106      * HQL语句:from Order
107      *
108      * 在hibernate中分页只有
109      *     setFirstResult
110      *     setMaxResults
111      * 不管使用什么数据库都是这两个方法
112      */
113     @Test
114     public void test9(){
115         List<Order> orders = findAllOrder(4,2);
116         for(Order o : orders){
117             System.out.println(o);
118         }
119     }
120     //QBC
121     public List<Order> findAllOrder2(int firstResult,int maxResults){
122         Session s = HibernateUtil.getSession();
123         Transaction tx = s.beginTransaction();
124         Criteria criteria = s.createCriteria(Order.class);
125         criteria.setFirstResult(firstResult);//开始记录的索引
126         criteria.setMaxResults(maxResults);//每页要查询的条数
127         List<Order> list = criteria.list();
128         tx.commit();
129         s.close();
130         return list;
131     }
132     //HQL
133     public List<Order> findAllOrder(int firstResult,int maxResults){
134         Session s = HibernateUtil.getSession();
135         Transaction tx = s.beginTransaction();
136         Query query = s.createQuery("from Order");//select * from t_orders
137         //hibernate提供的方法:
138         query.setFirstResult(firstResult);//开始记录的索引
139         query.setMaxResults(maxResults);//每页要查询的条数
140         List<Order> orders = query.list();
141         tx.commit();
142         s.close();
143         return orders;
144     }
145     /*
146      * 命名查询
147      *     把sql或者HQL在映射文件中配置起来。提供一个名称。
148      *     名称和语句之间是键值对的对应关系。
149      *  在程序使用根据名称获取语句的方法,叫做命名查询
150      */
151     @Test
152     public void test8(){
153         Session s = HibernateUtil.getSession();
154         Transaction tx = s.beginTransaction();
155         Query  query = s.getNamedQuery("findCustomerByCondition");
156         //给条件赋值
157         query.setString("name", "testD");
158         query.setInteger("age", 28);
159         List list = query.list();
160         tx.commit();
161         s.close();
162         for(Object o : list){
163             System.out.println(o);
164         }
165     }
166     /*
167      * 具名查询
168      *     具名其实就是给查询的参数占位符提供一个名称,使我们在查询时,使用名称而不是索引来给参数赋值
169      * 书写规范:
170      *         必须用 :名称
171      */
172     @Test
173     public void test7(){
174         Session s = HibernateUtil.getSession();
175         Transaction tx = s.beginTransaction();
176         Query  query = s.createQuery("from Customer where age > :age and name=:name");
177         //给条件赋值
178         query.setString("name", "testD");
179         query.setInteger("age", 28);
180         List list = query.list();
181         tx.commit();
182         s.close();
183         for(Object o : list){
184             System.out.println(o);
185         }
186     }
187     //多态查询:了解一下
188     @Test
189     public void test6(){
190         Session s = HibernateUtil.getSession();
191         Transaction tx = s.beginTransaction();
192         Query  query = s.createQuery("from java.io.Serializable ");
193         List list = query.list();
194         tx.commit();
195         s.close();
196         for(Object o : list){
197             System.out.println(o);
198         }
199     }
200     /*
201      * 排序查询
202      *     关键字和SQL是一样的。
203      *     order by
204      *     asc
205      *  desc
206      */
207     @Test
208     public void test5(){
209         Session s = HibernateUtil.getSession();
210         Transaction tx = s.beginTransaction();
211         Query  query = s.createQuery("from Customer order by age desc ");
212         List list = query.list();
213         tx.commit();
214         s.close();
215         for(Object o : list){
216             System.out.println(o);
217         }
218     }
219     /*
220      * QBC特例查询
221      *     特例:
222      *         用实体对象创建一个例子,查询语句的条件就会根据实体对象中提供的例子进行条件的拼装。
223      *    注意:
224      *        1、条件只会用等于
225      *        2、在拼装条件时,它只涉及不为null的字段,同时不会把OID作为条件。
226      */
227     @Test
228     public void test4(){
229         //我的例子
230         Customer c = new Customer();
231         c.setAge(28);
232         c.setName("testA");
233         Session s = HibernateUtil.getSession();
234         Transaction tx = s.beginTransaction();
235         //创建查询对象。参数是要查询的实体
236         Criteria criteria = s.createCriteria(Customer.class);
237         //添加条件
238         criteria.add(Example.create(c));//select * from t_customes where age = 28
239
240         List list = criteria.list();
241         tx.commit();
242         s.close();
243         for(Object o : list){
244             System.out.println(o);
245         }
246     }
247     //QBC带条件查询
248     @Test
249     public void test3(){
250         Session s = HibernateUtil.getSession();
251         Transaction tx = s.beginTransaction();
252         //创建查询对象。参数是要查询的实体
253         Criteria criteria = s.createCriteria(Customer.class);
254         //添加条件
255         criteria.add(Restrictions.gt("age", 28));
256
257         List list = criteria.list();
258         tx.commit();
259         s.close();
260         for(Object o : list){
261             System.out.println(o);
262         }
263     }
264     /*
265      * QBC查询
266      *     QBC:query by criteria
267      *  QBC能实现的HQL都能实现。反之亦然。
268      * 它更加面向对象
269      */
270     @Test
271     public void test2(){
272         Session s = HibernateUtil.getSession();
273         Transaction tx = s.beginTransaction();
274         //创建查询对象。参数是要查询的实体
275         Criteria criteria = s.createCriteria(Customer.class);
276         List list = criteria.list();
277         tx.commit();
278         s.close();
279         for(Object o : list){
280             System.out.println(o);
281         }
282     }
283     /*
284      * HQL带条件查询
285      *      hiberante中HQL使用条件,也是where关键字。
286      *      条件的参数占位符也是用的问号
287      * 注意事项:
288      *     hibernate中查询语句的参数占位符索引是从0开始的。
289      */
290     @Test
291     public void test1(){
292         Session s = HibernateUtil.getSession();
293         Transaction tx = s.beginTransaction();
294         Query  query = s.createQuery("from Customer where age > ?");
295         //给条件赋值
296         query.setInteger(0, 28);
297         List list = query.list();
298         tx.commit();
299         s.close();
300         for(Object o : list){
301             System.out.println(o);
302         }
303     }
304 }

3、多表查询

3.1、交叉连接(cross join)

显示交叉连接:

 select  t1.*, t2.*  from  tabel1 t1 cross join table t2

隐式交叉连接:

select  t1.*, t2.*  from  tabel1 t1, table t2

返回结果:两张表的笛卡尔积

3.2、内连接(inner join)

显示内连接:SQL写法

select  *  from  tabel1 t1  inner  join  table t2 on  t1.primary_key = t2.foregin_key

隐式内连接:SQL写法

select  *  from  tabel1 t1, table t2where t1.primary_key = t2.foregin_key

返回结果:是在笛卡尔积的基础上,返回符合条件的结果。

HQL写法:select  *  from  Customer t1  inner  join  c.orders;

HQL写法:select  *  from  Customer t1  inner  join  fetch  c.orders;

返回结果:

inner join:Object[]

inner join fetch:实体对象

3.3、外连接(outer join 左外和右外其实是一样的)

左外连接: left outer join

select  *  from customers c  left  outer  join  orders o  on  c.id=o.customer_id;

返回结果:除了满足条件的记录外,左外连接还会返回左表剩余记录。

右外连接: right outer join

select  *  from customers c  right  outer  join  orders o  on  c.id=o.customer_id;

返回结果:除了满足条件的记录外,右外连接还会返回右表剩余记录。

HQL写法:select  *  from  Customer t1  inner  join  c.orders;

HQL写法:select  *  from  Customer t1  inner  join  fetch  c.orders;

返回结果:

inner join:Object[]

inner join fetch:实体对象

全外连接:(MySQL不支持) full outer join。返回结果了解一下:除了满足条件的之外,还会返回左表和右表不满足条件的记录。

 1     /*
 2      * 迫切左外连接查询
 3      *
 4      * 返回的是一个集合,集合中的每个元素都是左表实体对象。
 5      * 有可能重复。重复的原因是看迫切左外连接查询的条件。
 6      */
 7     @Test
 8     public void test11(){
 9         Session s = HibernateUtil.getSession();
10         Transaction tx = s.beginTransaction();
11         Query query = s.createQuery("from Customer c left outer join fetch c.orders ");
12         List list = query.list();
13         tx.commit();
14         s.close();
15         for(Object o : list){
16             System.out.println(o);
17         }
18     }
19
20     /*
21      * 左外连接查询
22      *
23      * 返回值是一个集合,集合的每个元素是Object数组。
24      * 数组中包含2个Object对象。
25      * 其中一个左表对象和一个右表对象。
26      * 左表对象有可能重复,右表对象不会重复
27      */
28     @Test
29     public void test10(){
30         Session s = HibernateUtil.getSession();
31         Transaction tx = s.beginTransaction();
32         Query query = s.createQuery("from Customer c left outer join c.orders ");
33         List<Object[]> list = query.list();
34         tx.commit();
35         s.close();
36         for(Object[] os : list){
37             System.out.println("----------------------");
38             for(Object o : os){
39                 System.out.println(o);
40             }
41         }
42     }

3.4、投影查询

 1 /*
 2      * 投影查询
 3      *     就想实现
 4      *         查询客户时,只有客户的id和name
 5      *         查询订单时,只有订单id和money
 6      * 投影查询就是:
 7      *     在实际开发中,我们只需要一个实体类中的某个或者某些字段,当查询完成后还想使用该实体对象来操作。
 8      *     需要把查询的某个或某些字段投射到实体类上,这种查询方式叫投影查询。
 9      * 在使用投影查询时的要求:
10      *     实体类必须提供对应参数列表的构造函数。
11      *  在写HQL语句时,需要使用new关键字
12      *
13      * 注意事项:
14      *     在使用投影查询时,如果直接写类名,需要确定该类在工程中唯一。
15      *     如果不唯一的话,需要些类全名。包名.类名
16      */
17     @Test
18     public void test13(){
19         Session s = HibernateUtil.getSession();
20         Transaction tx = s.beginTransaction();
21         Query query = s.createQuery("select new cn.itcast.domain.Order(o.id,o.money) from Order o");
22         List list = query.list();
23         tx.commit();
24         s.close();
25         for(Object o : list){
26             System.out.println(o);
27         }
28     }
29     @Test
30     public void test12(){
31         Session s = HibernateUtil.getSession();
32         Transaction tx = s.beginTransaction();
33         Query query = s.createQuery("select new Customer(c.id,c.name) from Customer c");
34         List list = query.list();
35         tx.commit();
36         s.close();
37         for(Object o : list){
38             System.out.println(o);
39         }
40     }

三、附录:QBC自定义条件


短语 


含义 


Restrictions.eq


等于=


Restrictions.allEq


使用Map,使用key/value进行多个等于的判断


Restrictions.gt


大于>


Restrictions.ge


大于等于>=


Restrictions.lt


小于<


Restrictions.le


小于等于<=


Restrictions.between


对应sql的between子句


Restrictions.like


对应sql的like子句


Restrictions.in


对应sql的in子句


Restrictions.and


and 关系


Restrictions.or


or关系


Restrictions.sqlRestriction


Sql限定查询


Restrictions.asc()


根据传入的字段进行升序排序


Restrictions.desc()


根据传入的字段进行降序排序


运算类型


HQL运算符


QBC运算方法


比较运算


=


Restrictions.eq()


<>


Restrictions.not(Restrictions.eq())


>=


Restrictions.ge()


<


Restrictions.lt()


<=


Restrictions.le()


is null


Restrictions.isNull()


is not null


Restrictions.isNotNull()


范围运算符


in


Restrictions.in()


not in


Restrictions.not(Restrictions.in())


between


Restrictions.between()


not between


Restrictions.not(Restrictions.between())


运算类型


HQL运算符


QBC运算方法


字符串模式匹配


like


Restrictions.like()


逻辑


and


Restrictions.and()|

Restrictions.conjunction()


or


Restrictions.or()|

Restrictions.disjunction()


not


Restrictions.not()

 
时间: 2024-08-08 05:37:51

Java实战之02Hibernate-05检索策略、检索方式的相关文章

Hibernate&lt;六&gt; Hibernate的检索策略

一.Hibernate检索策略 1.Hibernate提供了三种检索策略:立即检索策略.延迟检索策略(懒加载机制).迫切左外连接检索策略.Hibernate在3.x以前lazy属性默认为false,Session的get()方法.load()方法默认都使用的是立即检索策略.从3.x以后,lazy属性为true,get()方法使用的是立即检索策略,load()方法默认使用的延迟检索策略. 以前默认的立即检索策略存在两大不足: ①.select语句的数据太多,需要频繁的访问数据库,会影响检索性能.如

框架 day33 Hibernate,组件映射,继承映射,抓取(检索)策略-优化,检索方式总结

组件(组成)映射 例1: public class Person { private Integer pid; //OID 值 private String name; //第一种方案 private String homeAddr; private String homeTel; private String companyAddr; private String companyTel; ↑一般项目都都采用此方案() *通过面向对象角度,使用设计模式(组件|组合),将数据都抽取到一个对象中.将

[原创]java WEB学习笔记88:Hibernate学习之路-- -Hibernate检索策略(立即检索,延迟检索,迫切左外连接检索)

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

HBase 实战(2)--时间序列检索和面检索的应用场景实战

前言: 作为Hadoop生态系统中重要的一员, HBase作为分布式列式存储, 在线实时处理的特性, 备受瞩目, 将来能在很多应用场景, 取代传统关系型数据库的江湖地位. 本篇主要讲述面向时间序列/面检索的应用场景时, 如何利用HBase的特性去处理和优化. 构造应用场景 某气象局对各个站点的信息进行采集和汇总, 这些信息包括站点id, 时间点, 采集要素(要素特别多). 然后对这些采集的数据, 提出如下检索需求: 1). 时间序列检索(检索出该站点的在某个时间范围内的全要素信息) 2). 面检

Hibernate检索策略与检索方式

hibernate的Session在加载Java对象时,一般都会把鱼这个对象相关联的其他Java对象也都加载到缓存中,以方便程序的调用.但很多情况下,我们不需要加载太多无用的对象到缓存中,一来会占用大量的内存,二来会增加数据库的访问次数,使得程序的运行效率降低.为了合理的使用缓存,Hibernate提供了不同的检索策略来解决这些问题. 作用域 在说检索策略之前,先了解一下检索策略的作用域,它分为:类级别和关联级别.类级别的作用域在检索数据时,检索的数据只包含一个类对象,不涉及与该类关联的其他对象

(九)Hibernate 检索策略

所有项目导入对应的hibernate的jar包.mysql的jar包和添加每次都需要用到的HibernateUtil.java 这里的hibernate.cfg.xml配置信息我就不再写了 第一节:检索策略属性Lazy Lazy:true (默认) 延迟检索:set 端一对多 Lazy:false 立即检索:set 端一对多 Lazy:extra 增强延迟检索: set 端一对多 Lazy:proxy(默认) 延迟检索:many-to-one 多对一 Lazy:no-proxy 无代理延迟检索:

Hibernate学习9—检索策略

本章,采用Class和Student     --  1 对 多的关系: Student.java: package com.cy.model; public class Student { private int id; private String name; private Class c; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName(

Hibernate的检索策略

hibernate 的中的session依照load()和get()按照参数的制定OID(ObjctID)去加载一个持久化对象.另外Query.list()方法则按照HQL语句去加载持久化的对象. 以上的几个方式都可以实现hibernate的持久化对象的加载.如果有不懂hibernate对象的"临时状态"."游离态"."持久态"."删除状态"的小伙伴,自己先去了解下. 对于hibernate的以上的几种检索策略,我们先来了解下

hibernate(八) Hibernate检索策略(类级别,关联级别,批量检索)详解

序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要想想,你花费的也就那么一点时间,别人花你这么多时间也能够学到你所学到的东西,所以还是要继续努力.既然不是天才,唯有靠勤奋来弥补. --WH 一.概述 检索策略分三大块,类级别检索策略和关联级别检测策略. 类级别检索策略:get.load. 关联级别检索策略:order.getCustomer().g