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

     
  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5608999.html
Copyright © 2011-2022 走看看