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、类级别的检索策略

只影响Sessionload()方法

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 joinObject[]

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 joinObject[]

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()

 

 
posted @ 2016-06-22 23:30  铭昊Coder  阅读(345)  评论(0编辑  收藏  举报