zoukankan      html  css  js  c++  java
  • Java实战之02Hibernate05检索策略、检索方式

    十一、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()

     
  • 相关阅读:
    最近发现一个网站
    2017-0206 委托封装的方法的参数类型
    迈向Angular 2
    趣学CCNA 路由与交换
    HCNA 2017年01月26日
    在linux中使用phpize安装php扩展模块
    接口和抽象类
    C:Program Files (x86)MSBuildMicrosoft.Cppv4.0V110Microsoft.CppCommon.targets(611,5): error MSB
    抽象类和抽象方法
    java数组与内存控制
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5608999.html
Copyright © 2011-2022 走看看