hibernate-HQL查询

  1. Hibernate提供了以下几种检索对象的方式:

  2. 导航对象图检索方式: 根据已经加载的对象导航到其他对象。

  3. OID 检索方式: 按照对象的OID来检索对象。

  4. HQL 检索方式: 使用面向对象的 HQL 查询语言。

  5. QBC 检索方式: 使用QBC(QueryBy Criteria) API 来检索对象. 这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。

  6. 本地SQL检索方式:使用本地数据库的SQL查询语句。

  7. HQL(HibernateQuery Language) 是面向对象的查询语言, 它和SQL查询语言有些相似.在Hibernate提供的各种检索方式中,HQL 是使用最广的一种检索方式.它有如下功能:

  8. 在查询语句中设定各种查询条件。

  9. 支持投影查询,即仅检索出对象的部分属性。
  10. 支持分页查询。
  11. 支持连接查询。
  12. 支持分组查询,允许使用HAVING和GROUPBY 关键字。
  13. 提供内置聚集函数,如sum(),min() 和 max()。
  14. 支持子查询。
  15. 支持动态绑定参数。
  16. 能够调用用户定义的 SQL 函数或标准的SQL函数。

  17. HQL检索方式包括以下步骤:

  18. 通过Session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句.HQL 查询语句中可以包含命名参数。

  19. 动态绑定参数。
  20. 调用Query相关方法执行查询语句。

  21. 测试用例

```xml @Test public void testBatch(){ session.doWork(new Work() {
@Override public void execute(Connection connection) throws SQLException { //通过 JDBC 原生的 API 进行操作, 效率最高, 速度最快! } }); }

@Test
public void testManageSession(){

    //获取 Session
    //开启事务
    Session session = HibernateUtils.getInstance().getSession();
    System.out.println("-->" + session.hashCode());
    Transaction transaction = session.beginTransaction();

    DepartmentDao departmentDao = new DepartmentDao();

    Department dept = new Department();
    dept.setName("ATGUIGU");

    departmentDao.save(dept);
    departmentDao.save(dept);
    departmentDao.save(dept);

    //若 Session 是由 thread 来管理的, 则在提交或回滚事务时, 已经关闭 Session 了. 
    transaction.commit();
    System.out.println(session.isOpen()); 
}

@Test
public void testQueryIterate(){
    Department dept = (Department) session.get(Department.class, 70);
    System.out.println(dept.getName());
    System.out.println(dept.getEmps().size());

    Query query = session.createQuery("FROM Employee e WHERE e.dept.id = 80");

// List emps = query.list(); // System.out.println(emps.size());

    Iterator<Employee> empIt = query.iterate();
    while(empIt.hasNext()){
        System.out.println(empIt.next().getName()); 
    }
}

@Test
public void testUpdateTimeStampCache(){
    Query query = session.createQuery("FROM Employee");
    query.setCacheable(true);

    List<Employee> emps = query.list();
    System.out.println(emps.size());

    Employee employee = (Employee) session.get(Employee.class, 100);
    employee.setSalary(30000);

    emps = query.list();
    System.out.println(emps.size());
}

@Test
public void testQueryCache(){
    Query query = session.createQuery("FROM Employee");
    query.setCacheable(true);

    List<Employee> emps = query.list();
    System.out.println(emps.size());

    emps = query.list();
    System.out.println(emps.size());

    Criteria criteria = session.createCriteria(Employee.class);
    criteria.setCacheable(true);
}

@Test
public void testCollectionSecondLevelCache(){
    Department dept = (Department) session.get(Department.class, 80);
    System.out.println(dept.getName());
    System.out.println(dept.getEmps().size());

    transaction.commit();
    session.close();

    session = sessionFactory.openSession();
    transaction = session.beginTransaction();

    Department dept2 = (Department) session.get(Department.class, 80);
    System.out.println(dept2.getName());
    System.out.println(dept2.getEmps().size()); 
}

@Test
public void testHibernateSecondLevelCache(){
    Employee employee = (Employee) session.get(Employee.class, 100);
    System.out.println(employee.getName());

    transaction.commit();
    session.close();

    session = sessionFactory.openSession();
    transaction = session.beginTransaction();

    Employee employee2 = (Employee) session.get(Employee.class, 100);
    System.out.println(employee2.getName()); 
}

@Test
public void testHQLUpdate(){
    String hql = "DELETE FROM Department d WHERE d.id = :id";

    session.createQuery(hql).setInteger("id", 280)
                            .executeUpdate();
}

@Test
public void testNativeSQL(){
    String sql = "INSERT INTO gg_department VALUES(?, ?)";
    Query query = session.createSQLQuery(sql);

    query.setInteger(0, 280)
         .setString(1, "ATGUIGU")
         .executeUpdate();
}

@Test
public void testQBC4(){
    Criteria criteria = session.createCriteria(Employee.class);

    //1. 添加排序
    criteria.addOrder(Order.asc("salary"));
    criteria.addOrder(Order.desc("email"));

    //2. 添加翻页方法
    int pageSize = 5;
    int pageNo = 3;
    criteria.setFirstResult((pageNo - 1) * pageSize)
            .setMaxResults(pageSize)
            .list();
}

@Test
public void testQBC3(){
    Criteria criteria = session.createCriteria(Employee.class);

    //统计查询: 使用 Projection 来表示: 可以由 Projections 的静态方法得到
    criteria.setProjection(Projections.max("salary"));

    System.out.println(criteria.uniqueResult()); 
}

@Test
public void testQBC2(){
    Criteria criteria = session.createCriteria(Employee.class);

    //1. AND: 使用 Conjunction 表示
    //Conjunction 本身就是一个 Criterion 对象
    //且其中还可以添加 Criterion 对象
    Conjunction conjunction = Restrictions.conjunction();
    conjunction.add(Restrictions.like("name", "a", MatchMode.ANYWHERE));
    Department dept = new Department();
    dept.setId(80);
    conjunction.add(Restrictions.eq("dept", dept));
    System.out.println(conjunction);

    //2. OR
    Disjunction disjunction = Restrictions.disjunction();
    disjunction.add(Restrictions.ge("salary", 6000F));
    disjunction.add(Restrictions.isNull("email"));

    criteria.add(disjunction);
    criteria.add(conjunction);

    criteria.list();
}

@Test
public void testQBC(){
    //1. 创建一个 Criteria 对象
    Criteria criteria = session.createCriteria(Employee.class);

    //2. 添加查询条件: 在 QBC 中查询条件使用 Criterion 来表示
    //Criterion 可以通过 Restrictions 的静态方法得到
    criteria.add(Restrictions.eq("email", "SKUMAR"));
    criteria.add(Restrictions.gt("salary", 5000F));

    //3. 执行查询
    Employee employee = (Employee) criteria.uniqueResult();
    System.out.println(employee); 
}

@Test
public void testLeftJoinFetch2(){
    String hql = "SELECT e FROM Employee e INNER JOIN 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());
    }
}

@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()); 
    }

// List result = query.list(); // result = new ArrayList<>(new LinkedHashSet<>(result)); // System.out.println(result); //
// for(Object [] objs: result){ // System.out.println(Arrays.asList(objs)); // } }

@Test
public void testLeftJoinFetch(){

// 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());
    }
}

@Test
public void testGroupBy(){
    String hql = "SELECT min(e.salary), max(e.salary) "
            + "FROM Employee e "
            + "GROUP BY e.dept "
            + "HAVING min(salary) > :minSal";

    Query query = session.createQuery(hql)
                         .setFloat("minSal", 8000);

    List<Object []> result = query.list();
    for(Object [] objs: result){
        System.out.println(Arrays.asList(objs));
    }
}

@Test
public void testFieldQuery2(){
    String hql = "SELECT new Employee(e.email, e.salary, e.dept) "
            + "FROM Employee e "
            + "WHERE e.dept = :dept";
    Query query = session.createQuery(hql);

    Department dept = new Department();
    dept.setId(80);
    List<Employee> result = query.setEntity("dept", dept)
                                 .list();

    for(Employee emp: result){
        System.out.println(emp.getId() + ", " + emp.getEmail() 
                + ", " + emp.getSalary() + ", " + emp.getDept());
    }
}

@Test
public void testFieldQuery(){
    String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept";
    Query query = session.createQuery(hql);

    Department dept = new Department();
    dept.setId(80);
    List<Object[]> result = query.setEntity("dept", dept)
                                 .list();

    for(Object [] objs: result){
        System.out.println(Arrays.asList(objs));
    }
}

@Test
public void testNamedQuery(){
    Query query = session.getNamedQuery("salaryEmps");

    List<Employee> emps = query.setFloat("minSal", 5000)
                               .setFloat("maxSal", 10000)
                               .list();

    System.out.println(emps.size()); 
}

@Test
public void testPageQuery(){
    String hql = "FROM Employee";
    Query query = session.createQuery(hql);

    int pageNo = 22;
    int pageSize = 5;

    List<Employee> emps = 
                            query.setFirstResult((pageNo - 1) * pageSize)
                                 .setMaxResults(pageSize)
                                 .list();
    System.out.println(emps);
}

@Test
public void testHQLNamedParameter(){

    //1. 创建 Query 对象
    //基于命名参数. 
    String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";
    Query query = session.createQuery(hql);

    //2. 绑定参数
    query.setFloat("sal", 7000)
         .setString("email", "%A%");

    //3. 执行查询
    List<Employee> emps = query.list();
    System.out.println(emps.size());  
}

@Test
public void testHQL(){

    //1. 创建 Query 对象
    //基于位置的参数. 
    String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND e.dept = ? "
            + "ORDER BY e.salary";
    Query query = session.createQuery(hql);

    //2. 绑定参数
    //Query 对象调用 setXxx 方法支持方法链的编程风格.
    Department dept = new Department();
    dept.setId(80); 
    query.setFloat(0, 6000)
         .setString(1, "%A%")
         .setEntity(2, dept);

    //3. 执行查询
    List<Employee> emps = query.list();
    System.out.println(emps.size());  
}

} ```