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 }