hibernate13HQL查询2
HQL(迫切)左外连接
迫切左外连接:
-LEFT JOIN FETCH 关键字表示迫切做外连接检索策略。
-list()方法返回的集合中存放尸体对象的引用,每个Department对象关联的Employee集合都被初始化,存放所有关联的Employee的实体对象。
-查询结果中可能过会包含重复元素,可以通过一个HashSet来过滤重复元素
//迫切左外连接:返回满足连接条件的记录和左表中不满足连接条件的记录
@Test
public void testLeftJoinFetch(){
//此语句返回的是左外连接的效果
//String hql = "FROM Department d LEFT JOIN FETCH d.emps";
//词句是去重的HQL语句
//String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps";
String hql = "FROM Department d LEFT JOIN FETCH d.emps";
Query query = session.createQuery(hql);
List<Department> depts = query.list();//返回的是对象类型的集合
//去重
depts = new ArrayList<Department>(new LinkedHashSet(depts));
System.out.println(depts.size());
for(Department dept : depts){
System.out.println(dept.getName() + "-" + dept.getEmps().size());
}
}
左外连接:
-LEFT JOIN关键字表示左外连接查询
-list()方法默认的情况下返回的集合中存放的是对象数组类型。
-根据配置文件来决定Employee集合的检索策略(配置文件中用的fetch 或lazy 属性)。
-如果希望list()方法返回的集合中仅包含Department对象,可以在HQL查询语句中使用SELECT关键字
如果需要用的话,我们推荐使用left join fetch的方式
public void testLeftJoin(){
//左外连接
String hql = "FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);
List<Object[]> result = query.list();//返回的是对象数组类型的集合
//result = new ArrayList<Object[]>(new LinkedHashSet<Object[]>(result));利用这种方式不可以去重,
System.out.println(result);
for(Object[] objs : result){
System.out.println(Arrays.asList(objs));
}
}
public void testLeftJoin2(){
//左外连接去重
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());//左外连接
}
}
HQL(迫切)内连接
--INNER JOIN FETCH 关键字表示迫切内连接,也可以省略INNER 关键字
--list()方法返回的集合中存放Department对象的引用,每个Department对象的Employee集合都被初始化,存放所有关联的Employee对象。
内连接:
--INNER JOIN 关键字表示内连接,也可以省略INNER关键字
--list()方法的集合中存放的每个元素对应查询结果的一条记录,每个元素都是对象数组类型。
--如果希望list()方法的返回的集合仅包含Department对象,可以再HQL查询语句中使用SELECT 关键字
迫切内连接于迫切左外连接的不同就有一点:就是没有了左边表中不满足条件的记录;
内连接与迫切内连接同上;
上面是一对多查询,如果是多对一查询呢::
//对于多对一的查询(由多的一方来连接一的一方)
@Test
public void test(){
String hql = "SELECT e 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.getName()+" , "+emp.getDept().getName());
//如果这样打印会出现异常,因为是左外连接,有的人是没有部门的,emp.getDept()会返回空,所以会出现空指针,
//所以讲上面的hql语句可以改为内连接 "SELECT e FROM Employee e INNER JOIN FETCH e.dept",就没有这个问题了因为不符合条件的左右元素都将不在
}
}
关联级别运行时的检索策略
如果在HQL中没有指定检索策略,将使用映射文件配置的检索策略。
HQL会忽略映射文件中设置的迫切左外连接检索策略,如果希望HQL采用迫切左外连接策略,就必须在HQL查询语句中显示的指定它。
若在HQL代码中显示指定了检索策略,就会覆盖映射文件中配置的检索策略
优质内容筛选与推荐>>