美文网首页
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