Hibernate 迫切连接和普通连接的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 迫切连接和普通连接的区别相关的知识,希望对你有一定的参考价值。
package com.baidu.test;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.baidu.leftJoin.Department;
import com.baidu.leftJoin.Employee;
public class TestHQL_LeftJoin {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
session = sessionFactory.openSession();
transaction = session.beginTransaction();
}
@After
public void destroy(){
transaction.commit();
session.close();
sessionFactory.close();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~下面的例子是 从 1 对 多 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
*
* 迫切左外连接: 特点是:如果左表有不满足条件的,也返回左表不满足条件
* 1. LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
* 2. list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化,
* 存放所有关联的 Employee 的实体对象.
* 3. 查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
*
* 去重:
* 方法一:使用 distinct
* String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
* Query query = session.createQuery(hql);
*
* List<Department> depts = query.list();
* System.out.println(depts.size());
*
* 方法二
* String hql = "FROM Department d LEFT JOIN FETCH d.emps ";
* Query query = session.createQuery(hql);
*
* List<Department> depts = query.list();
*
* depts = new ArrayList<>(new LinkedHashSet(depts));
* System.out.println(depts.size());
*
* for(Department dept:depts){
* System.out.println(dept.getName() + "--" + dept.getEmps().size() );
* }
*
*
*/
@Test
public void testLeftJoinFetch(){
// String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
// Query query = session.createQuery(hql);
//
// List<Department> depts = query.list();
// System.out.println(depts.size());
//
String hql = "FROM Department d LEFT JOIN FETCH d.emps ";
Query query = session.createQuery(hql);
List<Department> depts = query.list();
System.out.println(depts.size());
depts = new ArrayList<>(new LinkedHashSet(depts));
System.out.println(depts.size());
for(Department dept:depts){
System.out.println(dept.getName() + "--" + dept.getEmps().size() );
}
}
/**
* 左外连接:
* 1. LEFT JOIN 关键字表示左外连接查询.
* 2. list() 方法返回的集合中存放的是对象数组类型
* 3. 根据配置文件来决定 Employee 集合的检索策略.
* 4. 如果希望 list() 方法返回的集合中仅包含 Department 对象,
* 可以在HQL 查询语句中使用 SELECT 关键字
*
* 这样的语句查询的结果有重复:
* String hql = "FROM Department d LEFT JOIN d.emps";
* Query query = session.createQuery(hql);
*
* List<Object[]> results = query.list();
* System.out.println(results.size());
*
* 去重:
* 仅能使用 distinct 的方法去除重复
*
* String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
* Query query = session.createQuery(hql);
*
* List<Department> depts = query.list();
* System.out.println(depts.size());
*
* for(Department dept:depts){
* System.out.println(dept.getName() + dept.getEmps().size());
* }
*
*/
@Test
public void testLeftJoin(){
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);
List<Department> depts = query.list();
System.out.println(depts.size());
for(Department dept:depts){
System.out.println(dept.getName() + dept.getEmps().size());
}
}
/**
* 迫切内连接: 特点是:不返回左表不满足条件
* INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
* list() 方法返回的集合中存放 Department 对象的引用, 每个 Department
* 对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
*
* 内连接:
* INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
* list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型
* 如果希望 list() 方法的返回的集合仅包含 Department 对象, 可以在 HQL 查询语句中使用 SELECT 关键字
*
*
*
*/
@Test
public void testInnerJoinFetch(){
//String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
String hql = "FROM Department d INNER JOIN FETCH d.emps ";
Query query = session.createQuery(hql);
List<Department> depts = query.list();
depts = new ArrayList<>(new LinkedHashSet(depts));
System.out.println(depts.size());
for(Department dept:depts){
System.out.println(dept.getName() + "--" + dept.getEmps().size() );
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~下面的例子是 从多 对 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Test
public void testLeftJoinFetch2(){
String hql = "FROM Employee e LEFT JOIN FETCH e.dept";
Query query = session.createQuery(hql);
List<Employee> emps = query.list();
System.out.println(emps.size());
for(Employee emp:emps){
System.out.println(emp + " -- " + emp.getDept());
}
}
}
以上是关于Hibernate 迫切连接和普通连接的区别的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记88:Hibernate学习之路-- -Hibernate检索策略(立即检索,延迟检索,迫切左外连接检索)