hibernate的三种查询方式
hibernate的查询方式常见的主要分为三种: HQL, QBC, 以及使用原生SQL查询(Session的查询)
1)Query的查询:使用HQL语句或SQL语句完成查询
2)Criteria的查询:通过方法和类中属性的关系,来设置查询条件,完成查询。
3)Session的查询:按主键查询查询,方法为get或load
一.HQL查询
• HQL(Hibernate Query Language)提供了丰富灵活的查询方式,使用HQL进行查询也是Hibernate官方推荐使用的查询方式。
• HQL在语法结构上和SQL语句十分的相同,所以可以很快的上手进行使用。使用HQL需要用到Hibernate中的Query对象,该对象专门执行HQL方式的操作。
查询所有示例
1
2
3
4
5
6
7
8
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
|
1
2
3
4
5
6
7
|
|
1
2
3
4
5
6
7
8
9
10
11
12
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
|
1
2
3
4
5
6
7
8
9
10
11
12
|
|
1.1HQL语句不只支持查询功能,还支持修改以及删除功能
- public void doRemove(Integer id) throws Exception {
- // 注意,使用Hibernate删除时,必须先查询对象,再删除.
- // HibernateSessionFactory.getSession().delete(findById(id));
- String hql = "DELETE FROM News AS n WHERE n.id = ?" ;
- Query query = HibernateSessionFactory.getSession().createQuery(hql);
- query.setInteger(0, id);
- query.executeUpdate();
- }
注:使用HQL的删除可以不需要先查询,直接删除,支持一次删除多条数据
开发中的选择:1)当删除一条数据时,直接使用session.delete()就可以,因为简单,hibernate不在乎那点查询的性能;
2)批量删除时,使用Hql形式,这是可以提高性能的方法,因为它中间省去了查询的步骤。
1.2HQL语句修改功能
- public void doUpdate(News vo) throws Exception {
- // HibernateSessionFactory.getSession().update(vo);
- String hql = "UPDATE News AS n SET n.title = ?,n.content = ? WHERE n.id = ?" ;
- Query query = HibernateSessionFactory.getSession().createQuery(hql);
- query.setString(0, vo.getTitle());
- // ....其他参数一样设置
- query.executeUpdate();
- }
开发中的选择:1)如果是直接的修改功能,选择session.update()方法;
2)如果是只修改某一字段,使用HQL方式。
注:HQL语句不支持添加,但是Query支持添加。
1.3针对HQL的查询功能,也支持写SELECT,可以通过编写SELECT,来只查询对象中某一个或某几个属性。
但是对于多种字段不同类型的查询返回的,Hibernate中只能是数组。
例如:
- public List testHQL() throws Exception {
- String hql = "SELECT n.id,n.title FROM News AS n";
- Query query = HibernateSessionFactory.getSession().createQuery(hql);
- return query.list();
- }
经过测试,发现当只查询一个字段时,直接返回该类型的List集合。
但查询两个以上的字段时,返回的是List<Object[]>,每一条查询出的数据,使用Object[]来表示,这就很不方便。
- public void testHQL() throws Exception {
- List all = ServiceFactory.getINewsServiceInstance().testHQL();
- Object[] value1 = (Object[]) all.get(0);
- System.out.println(value1[1]);
- }
这样使用起来很麻烦,因此在Hibernate3.2以上的版本中,提供了一个自动转换类,可以将查询出的Object[],自动转换为pojo 对象。
- public List testHQL() throws Exception {
- String hql = "SELECT n.id AS id,n.title AS title FROM News AS n";
- Query query = HibernateSessionFactory.getSession().createQuery(hql);
- <span style="color:#cc0000;">query
- .setResultTransformer(new AliasToBeanResultTransformer(
- News.class));</span>
- return query.list();
- }
注:一般开发中不会使用这种方法,只有当表中的字段过多,但查询只需要其中的几个字段时,才会用到这种方法。
1.4Hibernate还可以将语句写到配置文件中
- <query name="findAll">
- FROM News AS n WHERE n.title LIKE ?
- </query>
通过程序读取配置文件,取得这段HQL,并生成Query对象,完成查询。
- Query query = HibernateSessionFactory.getSession().getNamedQuery(
- "findAll");
- query.setString(0, "%测试%");
- return query.list();
这种方式在Mybatis中普遍使用,但是在Hibernate中一般很少这样做。
二.QBC(Query By Criteria)查询
• Criteria对象提供了一种面向对象的方式查询数据库。Criteria对象需要使用Session对象来获得。
• 一个Criteria对象表示对一个持久化类的查询。
查询所有
1
2
3
4
5
6
7
8
9
10
11
|
|
或
- public List<News> testCriteria() throws Exception {
- // 根据传入的pojo类型,查询该类型对应的全部数据
- Criteria c = HibernateSessionFactory.getSession().createCriteria(
- News.class);
- return c.list();
- }
1
2
3
4
5
6
7
8
9
10
11
|
|
- public List<News> testCriteria() throws Exception {
- // 根据传入的pojo类型,查询该类型对应的全部数据
- Criteria c = HibernateSessionFactory.getSession().createCriteria(
- News.class);
- // 1、WHERE id = 26
- // c.add(Restrictions.eq("id", 26));
- // 2、WHERE id > 26
- // c.add(Restrictions.gt("id", 26));
- // 3、WHERE id < 26
- // c.add(Restrictions.lt("id", 26));
- // 4、WHERE id >= 26
- // c.add(Restrictions.ge("id", 26));
- // 5、WHERE id <= 26
- // c.add(Restrictions.le("id", 26));
- // 6、WHERE id <> 26
- // c.add(Restrictions.ne("id", 26));
- // 7、WHERE title LIKE '%测试%'
- // c.add(Restrictions.like("title", "%测试%"));
- // 8、WHERE id between 23 and 27
- // c.add(Restrictions.between("id", 23, 27));
- // 9、WHERE id IN (23,25,27)
- // List<Integer> allIds = new ArrayList<Integer>();
- // allIds.add(23);
- // allIds.add(25);
- // allIds.add(27);
- // c.add(Restrictions.in("id", allIds));
- // 10、复杂条件,需要使用and或or来连接各个条件
- // WHERE id = 23 OR (id <> 26 AND title LIKE '%测试%')
- c
- .add(Restrictions.or(Restrictions.eq("id", 23), Restrictions
- .and(Restrictions.ne("id", 26), Restrictions.like(
- "title", "%测试%"))));
- return c.list();
- }
如果想加入ORDER BY排序条件,需要使用Order对象。
- c.addOrder(Order.desc("id"));
如果想加入统计函数和分组函数,则需要用到Projection这个类
- <span style="white-space:pre"> </span>ProjectionList pro = Projections.projectionList();
- // 加入统计函数
- pro.add(Projections.rowCount());
- // 还可以加入分组条件
- pro.add(Projections.groupProperty("title"));
- c.setProjection(pro);
1
2
3
4
5
6
7
8
9
10
11
12
|
|
1
2
3
4
5
6
|
|
1
2
3
4
5
6
7
8
9
10
|
|
1
2
3
4
|
|
1
2
3
4
5
6
7
8
9
10
|
|
1
2
3
4
5
6
7
8
9
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
|
1
2
3
|
|
1
2
3
4
5
6
7
8
9
10
11
12
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
|
1
2
3
4
5
6
7
8
9
10
|
|