HQL连接查询和注解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HQL连接查询和注解相关的知识,希望对你有一定的参考价值。
1.连接查询
迫切内连接: 特点是:不返回左表不满足条件
eg:FROM Department d INNER JOIN FETCH d.emps
eg:FROM Department d INNER JOIN d.emps
2.. 查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
迫切内连接: 特点是:不返回左表不满足条件
eg:FROM Department d INNER JOIN FETCH d.emps
-
- INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
- list() 方法返回的集合中存放Department对象的引用, 每个Department对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
eg:FROM Department d INNER JOIN d.emps
-
- INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
- list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型, 如果希望 list() 方法的返回的集合仅包含 Department 对象, 可以在 HQL 查询语句中使用 SELECT 关键字
-
- LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
- list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化,存放所有关联的 Employee 的实体对象.
2.. 查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
去重:
方法一:使用 distinct
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
Query query = session.createQuery(hql);
List<Department> depts = query.list();
System.out.println(depts.size());
方法二
String hql = "FROM Department d LEFT 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() );
}
左外连接:
1. LEFT JOIN 关键字表示左外连接查询.
2. list() 方法返回的集合中存放的是对象数组类型
3. 根据配置文件来决定 Employee 集合的检索策略.
4. 如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT 关键字
这样的语句查询的结果有重复:
String hql = "FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);
List<Object[]> results = query.list();
System.out.println(results.size());
去重:
仅能使用 distinct 的方法去除重复
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语句中不使用
String hql = "from Book" <==>
String hql = "select bookId,bookName,author,price from Book";
String hql = "select bookName,author from Book";
如果只查询某一列的值,那么集合中对应的就不再是一个对象了
List<String> list = query.list(hql);
如果查询某几列的数据,那么集合中对应的每个元素对应的就是一个数组相同数据类型使用String[] 或其他数据类型数组,不同数据类型使用Object[], 模糊查询 排序都不变,查询不需要发起事务,修改需要发起事务query.executeUpdate(); 可以自行修改删除
HQL分页
query.setFirstResult(); 设置当前页起始行索引
query.setMaxResults(); 设置每页记录条数
具体查询一条数据可以使用uniqueResult();
Book book = (Book)uniqueResult();
2.2.Criteria查询:
Criteria查询示例:
1.获得Session
Session session = HibernateSessionFactory.getSession();
2.通过session创建Criteria对象
Criteria criteria = session.createCriteria(Class arg);
eg:Criteria criteria = session.createCriteria(Book.class);
Criteria criteria = session.createCriteria(String arg);
eg:Criteria criteria = session.createCriteria("com.entity.Book");
3.通过Criteria对象执行查询
List<Book> list = criteria.list();
4.关闭Session
session.close();
方法一:使用 distinct
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
Query query = session.createQuery(hql);
List<Department> depts = query.list();
System.out.println(depts.size());
方法二
String hql = "FROM Department d LEFT 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() );
}
左外连接:
1. LEFT JOIN 关键字表示左外连接查询.
2. list() 方法返回的集合中存放的是对象数组类型
3. 根据配置文件来决定 Employee 集合的检索策略.
4. 如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT 关键字
这样的语句查询的结果有重复:
String hql = "FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);
List<Object[]> results = query.list();
System.out.println(results.size());
去重:
仅能使用 distinct 的方法去除重复
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语句中不使用
String hql = "from Book" <==>
String hql = "select bookId,bookName,author,price from Book";
String hql = "select bookName,author from Book";
如果只查询某一列的值,那么集合中对应的就不再是一个对象了
List<String> list = query.list(hql);
如果查询某几列的数据,那么集合中对应的每个元素对应的就是一个数组相同数据类型使用String[] 或其他数据类型数组,不同数据类型使用Object[], 模糊查询 排序都不变,查询不需要发起事务,修改需要发起事务query.executeUpdate(); 可以自行修改删除
HQL分页
query.setFirstResult(); 设置当前页起始行索引
query.setMaxResults(); 设置每页记录条数
具体查询一条数据可以使用uniqueResult();
Book book = (Book)uniqueResult();
2.2.Criteria查询:
Criteria查询示例:
1.获得Session
Session session = HibernateSessionFactory.getSession();
2.通过session创建Criteria对象
Criteria criteria = session.createCriteria(Class arg);
eg:Criteria criteria = session.createCriteria(Book.class);
Criteria criteria = session.createCriteria(String arg);
eg:Criteria criteria = session.createCriteria("com.entity.Book");
3.通过Criteria对象执行查询
List<Book> list = criteria.list();
4.关闭Session
session.close();
条件查询
//比较运算
cri.add(Restrictions.eq("bookName","sql")); //eq等于 le小于等于 lt小于 ge大于等于 gt大于
//模糊查询
cri.add(Restrictions.like("bookName","%a%"));
//范围运算
Restrictions.in
( )
//逻辑运算
Restrictions.and( )
cri.add(Restrictions.or(Restrictions.eq("bookName","sql"),Expression.eq("price",50)));
criteria.addOrder(Order.desc("price"));
集合运算
Restrictions.isEmpty( )
排序
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.gt
("salary", 4000D))
.addOrder(Order.asc("salary"))
.addOrder(Order.desc("empNo")).list();
分页:
criteria.setFirstResult(); 设置当前页起始行索引
criteria.setMaxResults(); 设置每页记录条数
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setFirstResult(0)
.setMaxResults(2).list();
查询唯一对象:
Emp emp = (Emp) session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setMaxResults(1)
.uniqueResult();
关联:
方式一:
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.ilike("empName", "a", MatchMode.ANYWHERE))
.createCriteria("dept")
.add(Restrictions.eq("deptName", "财务部").ignoreCase()) .list();
方式二:
List<Emp> list = session.createCriteria(Emp.class, "e")
.createAlias("dept", "d")
.add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE))
.add(Restrictions.eq("d.deptName", "财务部").ignoreCase()).list();
投影:
List<String> list = session.createCriteria(Dept.class).setProjection(Property.forName("deptName")).list();
List<Object[]> list = session.createCriteria(Emp.class)
.setProjection(Projections.projectionList().add(Property.forName("empName")).add(Property.forName("hiredate"))).list();
分组、聚合函数:
List<Object[]> list = session.createCriteria(Emp.class, "e").createAlias("e.dept", "d")
.setProjection(Projections.projectionList().add(Projections.groupProperty("d.deptName"))
.add(Projections.avg("e.salary")).add(Projections.max("e.salary")).add(Projections.min("e.salary"))).list();
for (Object[] obj : list) {
System.out.println(obj[0] + ","+obj[1]+ ","+obj[2]+ ","+obj[3]);
}
DetachedCriteria查询:
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Emp.class, "e").createAlias("e.dept", "d")
.add(Restrictions.eq("d.deptName", "财务部").ignoreCase()).add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE));
List<Emp> list = detachedCriteria.getExecutableCriteria(session).list();
3. 注解
//比较运算
cri.add(Restrictions.eq("bookName","sql")); //eq等于 le小于等于 lt小于 ge大于等于 gt大于
//模糊查询
cri.add(Restrictions.like("bookName","%a%"));
//范围运算
Restrictions.in
( )
//逻辑运算
Restrictions.and( )
cri.add(Restrictions.or(Restrictions.eq("bookName","sql"),Expression.eq("price",50)));
criteria.addOrder(Order.desc("price"));
集合运算
Restrictions.isEmpty( )
排序
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.gt
("salary", 4000D))
.addOrder(Order.asc("salary"))
.addOrder(Order.desc("empNo")).list();
分页:
criteria.setFirstResult(); 设置当前页起始行索引
criteria.setMaxResults(); 设置每页记录条数
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setFirstResult(0)
.setMaxResults(2).list();
查询唯一对象:
Emp emp = (Emp) session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setMaxResults(1)
.uniqueResult();
关联:
方式一:
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.ilike("empName", "a", MatchMode.ANYWHERE))
.createCriteria("dept")
.add(Restrictions.eq("deptName", "财务部").ignoreCase()) .list();
方式二:
List<Emp> list = session.createCriteria(Emp.class, "e")
.createAlias("dept", "d")
.add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE))
.add(Restrictions.eq("d.deptName", "财务部").ignoreCase()).list();
投影:
List<String> list = session.createCriteria(Dept.class).setProjection(Property.forName("deptName")).list();
List<Object[]> list = session.createCriteria(Emp.class)
.setProjection(Projections.projectionList().add(Property.forName("empName")).add(Property.forName("hiredate"))).list();
分组、聚合函数:
List<Object[]> list = session.createCriteria(Emp.class, "e").createAlias("e.dept", "d")
.setProjection(Projections.projectionList().add(Projections.groupProperty("d.deptName"))
.add(Projections.avg("e.salary")).add(Projections.max("e.salary")).add(Projections.min("e.salary"))).list();
for (Object[] obj : list) {
System.out.println(obj[0] + ","+obj[1]+ ","+obj[2]+ ","+obj[3]);
}
DetachedCriteria查询:
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Emp.class, "e").createAlias("e.dept", "d")
.add(Restrictions.eq("d.deptName", "财务部").ignoreCase()).add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE));
List<Emp> list = detachedCriteria.getExecutableCriteria(session).list();
3. 注解
Hibernate 提供了注解进行对象--关系映射,它可以代替大量的hbm.xml 文件,使得Hibernate 程序的文件的数量大大精简。使用注解,可以直接映射信息定义在持久化类中,而无需编写对应的*.hbm.xml文件。
使用hibernate 注解的步骤:
-
- 使用注解配置持久化类及对象关联关系
- 在Hibernate 配置文件(hibernate.cfg.xml) 中声明持久化类
以上是关于HQL连接查询和注解的主要内容,如果未能解决你的问题,请参考以下文章
JPA 查询连接错误:org.hibernate.hql.internal.ast.QuerySyntaxException:连接所需的路径