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 }
