首页 > 技术文章 > Hibernate 迫切连接和普通连接的区别

JamelAr 2017-03-05 13:25 原文

  1 package com.baidu.test;
  2 
  3 import java.util.ArrayList;
  4 import java.util.LinkedHashSet;
  5 import java.util.List;
  6 
  7 import org.hibernate.Query;
  8 import org.hibernate.Session;
  9 import org.hibernate.SessionFactory;
 10 import org.hibernate.Transaction;
 11 import org.hibernate.cfg.Configuration;
 12 import org.hibernate.service.ServiceRegistry;
 13 import org.hibernate.service.ServiceRegistryBuilder;
 14 import org.junit.After;
 15 import org.junit.Before;
 16 import org.junit.Test;
 17 
 18 import com.baidu.leftJoin.Department;
 19 import com.baidu.leftJoin.Employee;
 20 
 21 public class TestHQL_LeftJoin {
 22     
 23     private SessionFactory sessionFactory;
 24     private Session session;
 25     private Transaction transaction;
 26     
 27     
 28     @Before
 29     public void init(){
 30         Configuration configuration = new Configuration().configure();
 31         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
 32                                         .applySettings(configuration.getProperties())
 33                                         .buildServiceRegistry();
 34         
 35         sessionFactory = configuration.buildSessionFactory(serviceRegistry);
 36         
 37         session = sessionFactory.openSession();
 38         transaction = session.beginTransaction();
 39     }
 40     @After
 41     public void destroy(){
 42         transaction.commit();
 43         session.close();
 44         sessionFactory.close();
 45         
 46     }
 47     
 48 //  ~~~~~~~~~~~~~~~~~~~~~~~~~~下面的例子是 从 1 对  多   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 49     
 50     /**
 51      *
 52      * 迫切左外连接: 特点是:如果左表有不满足条件的,也返回左表不满足条件
 53      *        1. LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
 54      *        2. list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化,
 55      *             存放所有关联的 Employee 的实体对象.
 56      *        3. 查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
 57      *
 58      *         去重:
 59      *             方法一:使用 distinct
 60      *                 String hql  = "SELECT DISTINCT d FROM  Department d LEFT JOIN FETCH d.emps ";
 61      *                Query query = session.createQuery(hql);
 62      *
 63      *                List<Department> depts = query.list();
 64      *                System.out.println(depts.size());
 65      *             
 66      *             方法二
 67      *                  String hql  = "FROM  Department d LEFT JOIN FETCH d.emps ";
 68      *                Query query = session.createQuery(hql);
 69      *
 70      *                List<Department> depts = query.list();
 71      *
 72      *                depts = new ArrayList<>(new LinkedHashSet(depts));
 73      *                System.out.println(depts.size());
 74      *                
 75      *                for(Department dept:depts){
 76      *                    System.out.println(dept.getName() + "--" + dept.getEmps().size() );
 77      *                }
 78      *
 79      *
 80      */
 81     @Test
 82     public void testLeftJoinFetch(){
 83 //        String hql  = "SELECT DISTINCT d FROM  Department d LEFT JOIN FETCH d.emps ";
 84 //        Query query = session.createQuery(hql);
 85 //        
 86 //        List<Department> depts = query.list();
 87 //        System.out.println(depts.size());
 88 //        
 89         
 90         
 91         String hql  = "FROM  Department d LEFT JOIN FETCH d.emps ";
 92         Query query = session.createQuery(hql);
 93         
 94         
 95         List<Department> depts = query.list();
 96         System.out.println(depts.size());
 97         
 98         depts = new ArrayList<>(new LinkedHashSet(depts));
 99         System.out.println(depts.size());
100         
101         for(Department dept:depts){
102             System.out.println(dept.getName() + "--" + dept.getEmps().size() );
103         }
104     }
105     
106     
107     /**
108      * 左外连接:
109      *        1. LEFT JOIN 关键字表示左外连接查询.
110      *        2. list() 方法返回的集合中存放的是对象数组类型
111      *        3. 根据配置文件来决定 Employee 集合的检索策略.
112      *        4. 如果希望 list() 方法返回的集合中仅包含 Department 对象,
113      *            可以在HQL 查询语句中使用 SELECT 关键字
114      *        
115      *        这样的语句查询的结果有重复:
116      *            String hql = "FROM Department d LEFT JOIN d.emps";
117      *            Query query = session.createQuery(hql);
118      *        
119      *            List<Object[]> results = query.list();
120      *            System.out.println(results.size());
121      *    
122      *         去重:
123      *             仅能使用  distinct 的方法去除重复
124      *     
125      *             String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
126      *             Query query = session.createQuery(hql);
127      *
128      *             List<Department> depts = query.list();
129      *             System.out.println(depts.size());
130      *                 
131      *             for(Department dept:depts){
132      *                 System.out.println(dept.getName() + dept.getEmps().size());
133      *             }
134      *
135      */
136     @Test
137     public void testLeftJoin(){
138         String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
139         Query query = session.createQuery(hql);
140         
141         List<Department> depts = query.list();
142         System.out.println(depts.size());
143         
144         for(Department dept:depts){
145             System.out.println(dept.getName() + dept.getEmps().size());
146         }        
147         
148     }
149     
150     /**
151      * 迫切内连接: 特点是:不返回左表不满足条件
152      *        INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
153      *        list() 方法返回的集合中存放 Department 对象的引用, 每个 Department
154      *                对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
155      *
156      * 内连接:
157      *        INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
158      *        list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型
159      *        如果希望 list() 方法的返回的集合仅包含 Department  对象, 可以在 HQL 查询语句中使用 SELECT 关键字
160      *
161      *
162      *
163      */
164     @Test
165     public void testInnerJoinFetch(){
166         //String hql  = "SELECT DISTINCT d FROM  Department d LEFT JOIN FETCH d.emps ";
167         String hql  = "FROM  Department d INNER JOIN FETCH  d.emps ";
168         Query query = session.createQuery(hql);
169         
170         
171         List<Department> depts = query.list();
172         depts = new ArrayList<>(new LinkedHashSet(depts));
173         System.out.println(depts.size());
174         
175         for(Department dept:depts){
176             System.out.println(dept.getName() + "--" + dept.getEmps().size() );
177         }
178     }
179     
180     
181 //  ~~~~~~~~~~~~~~~~~~~~~~~~~~下面的例子是 从多 对  1   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182     
183     @Test
184     public void testLeftJoinFetch2(){
185         String hql = "FROM Employee e LEFT JOIN FETCH e.dept";
186         Query query = session.createQuery(hql);
187         
188         List<Employee> emps = query.list();
189         System.out.println(emps.size());
190         
191         for(Employee emp:emps){
192             System.out.println(emp + " -- " + emp.getDept());
193         }
194         
195     }
196 }

 

推荐阅读