美文网首页
Hibernate之查询

Hibernate之查询

作者: 紫荆秋雪_文 | 来源:发表于2019-09-29 00:05 被阅读0次

一、Hibernate三种查询方式

问题:查询员工名字中含有a字符,且id在1~10之间的员工

1、HQL:使用面向对象的查询语句

  • 推荐使用的方式(在查询普通简单结果的时候使用)
  • 写SQL,把SQL中的属性变成对象的属性
    @Test
    public void HQLTest() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.name LIKE :name AND e.id BETWEEN :fv AND :lv";
        Query query = session.createQuery(hql)
                .setParameter("name", "%a%")
                .setParameter("fv", 1L)
                .setParameter("lv", 10L);
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e:list) {
            System.out.println(e);
        }
    }

2、SQL:在Hibernate当中也可以使用SQL来查询

  • 推荐使用的方式(在查询复查报表的时候使用,提示性能)
    public void SQLTest() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String sql = "SELECT e.* FROM Employee e WHERE e.name LIKE :name AND e.id BETWEEN :fv AND :lv";
        SQLQuery query = session.createSQLQuery(sql);
        query.setString("name", "%a%")
                .setLong("fv", 1L)
                .setLong("lv", 10L);
        List<Object[]> list = query.list();
        session.getTransaction().commit();

        for (Object[] obj:list) {
            System.out.println(Arrays.toString(obj));
        }
    }

3、Criteria:一种完全面向对象的查询方式

  • 使用Restrictions来设置查询限制条件,不推荐使用
    @Test
    public void CriteriaTest() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        Criteria criteria = session.createCriteria(Employee.class);
        Criterion like = Restrictions.like("name", "%a%");
        criteria.add(like)
                .add(Restrictions.between("id", 1L, 10L));
        List<Employee> list = criteria.list();
        session.getTransaction().commit();

        for (Employee e :list) {
            System.out.println(e);
        }
    }

二、数据

  • Department
package com.revanwang.common;


import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class Department {
    private Long        id;
    private String      name;
    private String      provice;
    private String      city;
    private String      street;
    private String      sn;

    private Employee    manager;//MANAGER_ID

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", provice='" + provice + '\'' +
                ", city='" + city + '\'' +
                ", street='" + street + '\'' +
                ", sn='" + sn + '\'' +
                '}';
    }
}
  • Employee
package com.revanwang.common;

import lombok.Getter;
import lombok.Setter;

import java.math.BigDecimal;
import java.util.Date;

@Setter
@Getter
public class Employee {
    private Long        id;
    private String      name;
    private BigDecimal  salary;
    private Date        hireDate;

    private Department  dept;   // DEPT_ID

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                ", hireDate=" + hireDate +
                '}';
    }
}
  • Phone
package com.revanwang.common;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class Phone {
    private Long        id;
    private PhoneType   types;
    private String      number;

    private Employee    employee;   //EMPLOYEE_ID

    @Override
    public String toString() {
        return "Phone{" +
                "id=" + id +
                ", types='" + types + '\'' +
                ", number='" + number + '\'' +
                '}';
    }
}
  • PhoneType
package com.revanwang.common;

public enum PhoneType {
    CELL, WORK
}
  • Project
package com.revanwang.common;

import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

@Setter
@Getter
public class Project {
    private Long        id;
    private String      name;

    private Employee    manager;    //MANAGER_ID
    private List<Employee> emps = new ArrayList<>();//many2many

}
  • common.xml
<?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC
                "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.revanwang.common">

    <!-- Department -->
    <class name="Department">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name"/>
        <property name="provice"/>
        <property name="city"/>
        <property name="street"/>
        <property name="sn"/>

        <many-to-one name="manager" column="MANAGER_ID"/>
    </class>

    <!-- Employee -->
    <class name="Employee">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name"/>
        <property name="salary" column="salay"/>
        <property name="hireDate" type="date"/>

        <many-to-one name="dept" column="DEPT_ID"/>
    </class>

    <!-- Phone -->
    <class name="Phone">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="types">
            <type name="org.hibernate.type.EnumType">
                <param name="enumClass">com.revanwang.common.PhoneType</param>
                <param name="useNamed">true</param>
            </type>
        </property>
        <property name="number"/>

        <many-to-one name="employee" column="EMPLOYEE_ID"/>
    </class>

    <!-- Phone -->
    <class name="Project">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name"/>

        <many-to-one name="manager" column="MANAGER_ID"/>
        <bag name="emps" table="project_employee">
            <key column="PROJECT_ID"></key>
            <many-to-many column="EMPLOYEE_ID" class="Employee"/>
        </bag>
    </class>

</hibernate-mapping>

三、HQL

1、HQL中的参数占位符

问题1:查询姓名中带有a字符

  • 使用"?"占位符
    public void test1() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.name LIKE ?";
        Query query = session.createQuery(hql)
                .setParameter(0, "%a%");
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e:list) {
            System.out.println(e);
        }
    }
  • 当有相同条件时
    public void test1() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.name LIKE ? AND e.name LIKE ?";
        Query query = session.createQuery(hql)
                .setParameter(0, "%a%")
                .setParameter(1, "%a%");
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e:list) {
            System.out.println(e);
        }
    }
1.1使用"?"占位符
  • ?:代表?号的位置需要一个参数,使用Query.setParameter(index, value); 来设置值,索引号index值从0开始
  • 使用?占位符,使用比较简单,但是参数位置如果发送变化或者遇到相同的参数,必须每次都重新设置值
1.2使用名称占位符
  • 1.2.1 在需要参数的地方,使用:参数名称就可以添加一个名称占位符
  • 1.2.2 使用query.setParameter("参数名称", value)的防护四设置参数值
  • 1.2.3 参数修改,只要参数的名称不变,代码不变。在HQL中,使用相同名称的参数只需要设置一次值就可以了
  • 1.2.4 使用名称占位符可以直接使用参数集合,用于in条件的设置
    public void test2() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.name LIKE :name AND e.name LIKE :name";
        Query query = session.createQuery(hql).setParameter("name", "%a%");
        List<Employee> list = query.list();

        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

2、名称占位符直接使用参数集合

问题2、查询salary等于 5000、6000、7000、8000 的员工
    /**
     * 查询salary等于 5000、6000、7000、8000 的员工
     */
    @Test
    public void test3() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.salary in (:salarys)";
        List<Employee> list = session.createQuery(hql)
                .setParameterList("salarys", new BigDecimal[]{new BigDecimal("5000"), new BigDecimal("6000"), new BigDecimal("7000"), new BigDecimal("8000")})
                .list();
        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

3、直接设置对象

  • 1、在Hibernate参数中,如果比较的是实体对象,可以直接使用对象的比较,Hibernate会自动的翻译为外键外键和主键的比较
  • 2、在比较实体的时候,可以使用setEntity方法来设置实体参数值.setEntity方法对于位置参数,和名称占位符都有效
问题3、查询,id为1的部门里面的员工
  • 使用id
    /**
     * 查询,id为1的部门里面的员工
     */
    @Test
    public void test4() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.dept.id = :deptID";
        Query query = session.createQuery(hql).setParameter("deptID", 1L);
        List<Employee> list = query.list();

        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }
  • 直接使用对象
    /**
     * 查询,id为1的部门里面的员工
     * 使用 实体
     */
    @Test
    public void test5() {
        Department department = new Department();
        department.setId(1L);

        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.dept = :dept";
        Query query = session.createQuery(hql).setParameter("dept", department);
        List<Employee> list = query.list();

        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

四、HQL分页查询

  • setFirstResult设置当前页
  • setMaxResult设置当前页个数
    /**
     * 分页查询
     */
    @Test
    public void test6() {
        //查询页数
        Integer currentPage = 6;
        //每一页个数
        Integer pageSize = 3;

        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e";
        Query query = session.createQuery(hql)
                .setFirstResult((currentPage - 1) * pageSize)   //当前页的开始索引
                .setMaxResults(pageSize);   //每页个数
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e:list) {
            System.out.println(e);
        }
    }

uniqueResult获取唯一记录

  • 获取表个数
    /**
     * 获取唯一记录
     * 使用传统方式获取
     */
    @Test
    public void test7() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT COUNT(e) FROM Employee e";
        Query query = session.createQuery(hql);
        List list = query.list();

        session.getTransaction().commit();

        System.out.println(list.get(0));
    }
  • uniqueResult
    /**
     * 获取唯一记录
     * uniqueResult
     */
    @Test
    public void test8() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT COUNT(e) FROM Employee e";
        Query query = session.createQuery(hql);
        
        //获取唯一结果
        Object row = query.uniqueResult();

        session.getTransaction().commit();

        System.out.println(row);
    }

五、HQL查询

1、参数占位符

1.1、 ?占位符

?占位符特点:

  • 使用简单
  • 如果参数的位置变化,参数索引会变化
  • 相同的参数只能手动重复设置
  • 没法作为 in 的参数

问题1:查询工资大于5000的员工

    /**
     * 查询工资大于5000的员工
     */
    @Test
    public void test1() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.salary > ?";
        Query query = session.createQuery(hql).setParameter(0, new BigDecimal("5000"));
        List<Employee> list = query.list();

        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

问题2:查询id为3、5、7的员工信息

/**
     * 查询id为3,5,7的员工信息
     */
    @Test
    public void test2() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.id = ? or e.id = ? or e.id = ?";
        Query query = session.createQuery(hql)
                .setParameter(0, 3L)
                .setParameter(1, 5L)
                .setParameter(2, 7L);
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

问题3:查询部门ID为1的员工信息

    /**
     * 查询部门ID为1的员工信息
     */
    @Test
    public void test3() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.dept.id = ?";
        Query query = session.createQuery(hql).setParameter(0, 1L);
        List<Employee> list = query.list();

        session.getTransaction().commit();
        for (Employee e:list) {
            System.out.println(e);
        }
    }

1.2、名称占位符

名称占位符特点:

  • 和位置无关
  • 相同参数值,设置一次值就可以了
  • 可以使用名称参数为in的参数设置多个值

问题1:查询工资大于5000的员工

    /**
     * 查询工资大于5000的员工
     */
    @Test
    public void test4() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.salary > :salary";
        Query query = session.createQuery(hql)
                .setParameter("salary", new BigDecimal("5000"));
        List<Employee> list = query.list();

        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

问题2:查询id为3、5、7的员工信息

    /**
     * 查询id为3,5,7的员工信息
     */
    @Test
    public void test5() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.id in (:eids)";
        Query query = session.createQuery(hql)
                .setParameterList("eids", new Long[]{3L, 5L, 7L});
        List<Employee> list = query.list();
        session.getTransaction().commit();

        for (Employee e : list) {
            System.out.println(e);
        }
    }

问题3:查询部门ID为1的员工信息

    /**
     * 查询部门ID为1的员工信息
     */
    @Test
    public void test6() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.dept.id = :deptId";
        Query query = session.createQuery(hql).setParameter("deptId", 1L);
        List<Employee> list = query.list();

        session.getTransaction().commit();
        for (Employee e:list) {
            System.out.println(e);
        }
    }
  • 参数是实体
    /**
     * 查询部门ID为1的员工信息
     * 参数是实体
     */
    @Test
    public void test6() {
        Department department = new Department();
        department.setId(1L);

        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.dept = :dept";
        Query query = session.createQuery(hql).setParameter("dept", department);
        List<Employee> list = query.list();

        session.getTransaction().commit();
        for (Employee e:list) {
            System.out.println(e);
        }
    }

2、查询结果

1、查询对象实体

问题1:查询所有员工信息

    /**
     * 查询所有员工信息
     */
    @Test
    public void test7() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e";
        List<Employee> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (Employee e:list) {
            System.out.println(e);
        }

    }

2、查询对象中某个属性

问题1:查询所有员工的名称

  • 查询的属性是一个简单类型,查询结果就是该类型的List集合
    /**
     * 查询所有员工的名称
     */
    @Test
    public void test8() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e.name FROM Employee e";
        List<String> list = session.createQuery(hql).list();

        session.getTransaction().commit();
        for (String name :list) {
            System.out.println(name);
        }
    }

问题2:查询所有的员工所在部门

    /**
     * 查询所有的员工的所在部门
     */
    @Test
    public void test9() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();
        
        //DISTINCT去重
        String hql = "SELECT DISTINCT e.dept FROM Employee e";
        Query query = session.createQuery(hql);
        List<Department> departList = query.list();

        session.getTransaction().commit();

        for (Department d:departList) {
            System.out.println(d);
        }

    }
  • 因为是内连接,若一个员工没有部门是不会被查询出来的

3、查询对象的某几个属性

问题1:需求:查询所有员工的编号,名字,工资,及所在部门的编号和名称

    /**
     * 需求:查询所有员工的编号,名字,工资,及所在部门的编号和名称
     */
    @Test
    public void test10() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e.id, e.name, e.salary, e.dept.id, e.dept.name FROM Employee e";
        List<Object[]> list = session.createQuery(hql).list();

        session.getTransaction().commit();
        for (Object[] obj : list) {
            System.out.println(Arrays.toString(obj));
        }
    }

  • 返回结果是一个Object[],在数组的对应位置就是对应的查询类型

4、查询结果的封装

问题1:查询所有员工的编号,名字,工资,及所在部门的编号和名称

4.1、查询类型Object[]

    /**
     * 返回结果类型 Object[]
     */
    @Test
    public void testObject() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e.id, e.name, e.salary, e.dept.id, e.dept.name FROM Employee e";
        List<Object[]> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (Object[] obj:list) {
            System.out.println(Arrays.toString(obj));
        }
    }

4.2、List<Object>

    /**
     * 返回结果类型 List<Object>
     */
    @Test
    public void testListObject() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.id, e.name, e.salary, e.dept.id, e.dept.name) FROM Employee e";
        List<List<Object>> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        System.out.println(list);
    }

4.3、Map<Integer, Object>

    /**
     * 返回结果类型 Map
     */
    @Test
    public void testMap() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new Map(e.id, e.name, e.salary, e.dept.id, e.dept.name) FROM Employee e";
        List<List<Object>> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        System.out.println(list);
    }

4.4、Map<String, Object>使用别名(AS)

    /**
     * 返回结果类型 MapAS
     */
    @Test
    public void testMapAS() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new Map(" +
                "e.id AS eId, " +
                "e.name  AS eName," +
                " e.salary AS eSalary," +
                " e.dept.id AS dID," +
                " e.dept.name AS dName)" +
                " FROM Employee e";
        List<Map<String, Object>> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        System.out.println(list);
    }

4.5、VO(值对象)

  • EDValueObject
package com.revanwang.query.hql;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class EDValueObject {
    private Long        eId;
    private String      eName;
    private BigDecimal eSalary;
    private Long        dId;
    private String      dName;

    public EDValueObject(Long eId, String eName, BigDecimal eSalary, Long dId, String dName) {
        this.eId = eId;
        this.eName = eName;
        this.eSalary = eSalary;
        this.dId = dId;
        this.dName = dName;
    }
}

  • common.xml中导入EDValueObject
<import class="com.revanwang.query.hql.EDValueObject" rename="EDValueObject"/>
  • 封装EDValueObject
    /**
     * 返回结果类型 EDValueObject
     */
    @Test
    public void testVO() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new EDValueObject(e.id, e.name, e.salary, e.dept.id, e.dept.name) FROM Employee e";
        List<EDValueObject> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (EDValueObject ed : list) {
            System.out.println(ed);
        }
    }

5、HQL中的集合操作

集合在Hibernate中经常出现,对集合的操作(size属性或size函数获取集合元素数量)

问题1:查询有员工参与开发的项目

    @Test
    public void test1() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT p FROM Project p WHERE p.emps.size > 0";
        List<Project> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (Project p : list) {
            System.out.println(p);
        }

    }

问题2:查询出没有员工参与的项目

    /**
     * 查询出没有员工参与的项目【对集合使用size/is empty】
     */
    @Test
    public void test2() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT p FROM Project p WHERE p.emps IS EMPTY";
        List<Project> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (Project p : list) {
            System.out.println(p);
        }

    }

问题3:查询出项目信息,按照项目的参与者总数排序【使用函数排序】

    /**
     * 查询出项目信息,按照项目的参与者总数排序【使用函数排序】
     */
    @Test
    public void test3() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT p FROM Project p ORDER BY p.emps.size DESC";
        List<Project> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (Project p : list) {
            System.out.println(p);
        }

    }

6、连接查询

6.1、查询出所有员工及部门名称

    /**
     * 查询出所有员工及部门名称【JOIN/LEFT JOIN】隐式内连接/显示内连接
     */
    @Test
    public void test4() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.name, e.dept.name) FROM Employee e";
        List<List<Object>> employeeList = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (List<Object> emp: employeeList) {
            System.out.println(emp);
        }

    }
  • Hibernate默认使用的是INNER JOIN

  • LEFT JOIN

    /**
     * 查询出所有员工及部门名称【JOIN/LEFT JOIN】隐式内连接/显示内连接
     */
    @Test
    public void test5() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.name, d.name) " +
                "FROM Employee e LEFT JOIN e.dept d";
        List<List<Object>> employeeList = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (List<Object> emp: employeeList) {
            System.out.println(emp);
        }

    }

6.2、查询所有的员工,包括没有部门的员工【LEFT JOIN】

    /**
     * 查询所有的员工,包括没有部门的员工【LEFT JOIN】
     */
    @Test
    public void test6() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.id, e.name, d.name) FROM Employee e LEFT JOIN e.dept d";
        List<List<Object>> list = session.createQuery(hql).list();

        session.getTransaction().commit();

        for (List<Object> e : list) {
            System.out.println(e);
        }
    }

6.3、查询出市场部员工信息及电话【LEFT/RIGHT JOIN】

    /**
     * 查询出市场部员工信息及电话
     */
    @Test
    public void test8() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.id, e.name, p.number) FROM Phone p RIGHT JOIN p.employee e" +
                " WHERE e.dept.name = :deptName";
        Query query = session.createQuery(hql).setParameter("deptName", "市场部");
        List<List<Object>> lists = query.list();

        session.getTransaction().commit();

        for (List<Object> obj : lists) {
            System.out.println(obj);
        }

    }

6.4、查询所有员工的部门信息

    /**
     * 查询所有员工的部门信息
     */
    @Test
    public void test9() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT d FROM Employee e LEFT JOIN e.dept d";
        Query query = session.createQuery(hql);

        List<Department> list = query.list();

        session.getTransaction().commit();

        for (Department d : list) {
            System.out.println(d);
        }
    }

7、聚集函数和子查询

问题1:查询出各个部门员工的平均工资和最高工资【使用聚集函数】

    /**
     * 查询出各个部门员工的平均工资和最高工资
     */
    @Test
    public void test10() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(e.dept.name, AVG(e.salary), MAX(e.salary)) FROM Employee e GROUP BY e.dept";
        Query query = session.createQuery(hql);

        List list = query.list();

        session.getTransaction().commit();

        System.out.println(list);

    }

问题2:查询出各个项目和该项目参与人数

    /**
     * 查询出各个项目和该项目参与人数
     */
    @Test
    public void test11() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT new List(pro.id, pro.name, pro.emps.size) FROM Project pro";
        List<List<Object>> list = session.createQuery(hql).list();

        session.getTransaction().commit();
        System.out.println(list);
    }

问题3:查询出大于平均工资的员工信息

    /**
     * 查询出大于平均工资的员工信息
     */
    @Test
    public void test12() {
        Session session = HibernateUtil.getHibernateSession();
        session.beginTransaction();

        String hql = "SELECT e FROM Employee e WHERE e.salary > (SELECT AVG(es.salary) FROM Employee es)";
        List<Employee> list = session.createQuery(hql).list();

        session.getTransaction().commit();
        System.out.println(list);
    }

8、命名查询

在Hibernate中,执行查询需要先将HQL翻译成SQL,再执行SQL。如果HQL比较复杂翻译的效率是比较低的。如果一条HQL重复执行,会重复翻译,效率低下。
Hibernate提供了NamedQuery方式,来稍微提高静态HQL语句的执行效率。

NamedQuery使用:在实体映射文件中添加

<!--为HQL起名为findCustomersByName,该HQL在hibernate启动的时候就会翻译成SQL -->
<query name="findCustomersByName">
     <![CDATA[from Customer c where c.name like :name]]>
</query>

使用NamedQuery查询:通过getNamedQuery,得到的就是已经翻译为SQL的query对象,只需要设置参数查询就行了

Query q=session.getNamedQuery("findCustomersByName");

NamedQuery的使用限制:NamedQuery里面只能配置静态的HQL。

相关文章

网友评论

      本文标题:Hibernate之查询

      本文链接:https://www.haomeiwen.com/subject/cajsuctx.html