hibernate-HQL查询
-
Hibernate提供了以下几种检索对象的方式:
-
导航对象图检索方式: 根据已经加载的对象导航到其他对象。
-
OID 检索方式: 按照对象的OID来检索对象。
-
HQL 检索方式: 使用面向对象的 HQL 查询语言。
-
QBC 检索方式: 使用QBC(QueryBy Criteria) API 来检索对象. 这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。
-
本地SQL检索方式:使用本地数据库的SQL查询语句。
-
HQL(HibernateQuery Language) 是面向对象的查询语言, 它和SQL查询语言有些相似.在Hibernate提供的各种检索方式中,HQL 是使用最广的一种检索方式.它有如下功能:
-
在查询语句中设定各种查询条件。
- 支持投影查询,即仅检索出对象的部分属性。
- 支持分页查询。
- 支持连接查询。
- 支持分组查询,允许使用HAVING和GROUPBY 关键字。
- 提供内置聚集函数,如sum(),min() 和 max()。
- 支持子查询。
- 支持动态绑定参数。
-
能够调用用户定义的 SQL 函数或标准的SQL函数。
-
HQL检索方式包括以下步骤:
-
通过Session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句.HQL 查询语句中可以包含命名参数。
- 动态绑定参数。
-
调用Query相关方法执行查询语句。
-
测试用例
```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
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
@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());
}
} ```