Hibernate的三种查询方式

本文深入探讨Hibernate中的多种查询方式,包括Criteria API、SQL查询及HQL查询的特点与使用技巧,并详细解析不同场景下的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这三种方式的共同点:
1.在查询多个字段时:
.list()里面默认存放的是Object[]的集合
.uniqueResult()时,默认是Object[] (需要强转,因为实际上是Object类型)
2.在查询一个字段时:
.list()里面默认存放的是字段相应的类型
.uniqueResult()时,默认就是字段相应的类型(需要强转,因为实际上是Object类型)
3.select * 时
除了SQL查询,其他两种都会自动将查询结果映射到实体对象中

表结构
示例表

  • 条件查询(Criteria)
    Criteria(标准)
    Restriction(限制)
    通过session.CreateCriteria(Entity.class);获得Criteria对象
Session session = HibernateUtil.SESSIONFACTORY.openSession();
//session.createCriteria(User.class)相当于select * from user(实体映射的表)
//add(Restrictions.条件(键,值)),相当于where ...
List<User> list = session.createCriteria(User.class).add(Restrictions.eq("username", "admin123")).list();
  • SQL查询

通过session.createSQLQuery(sql语句)获得SQLQuery对象
scalar(标量)

实例1:

Session session = HibernateUtil.SESSIONFACTORY.openSession();
        //.addScalar("字段",类型)在sql语句的基础上,可以指定查询的字段,并给查出来的字段设置类型,并添加到当前数组中
        //.addScalar("字段")在sql语句的基础上,查询指定的字段,查出来的就是字段相应的类型
        //.addEntity(实体类名.class),可以将查询出来的结果封装到实体类中(注意,只有在查询所有字段时才生效),并添加到当前数组中
        List<Object[]> list = session.createSQLQuery("select * from user").addScalar("username").addEntity(User.class).list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
            System.out.println(((User)objects[1]).getPassword());
            System.out.println(objects[0] instanceof String);
        }

结果:
Hibernate:
select
*
from
user
[admin1, com.linksky.query.entity.User@6bb33971]
abc123
true
[admin2, com.linksky.query.entity.User@9af67f5]
abc123
true
[admin123, com.linksky.query.entity.User@5ad20aca]
abc123
true

实例2:
通过StandardBasicTypes来指定字段的类型

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        List<Object[]> list = session.createSQLQuery("select * from user").addScalar("join_time").addEntity(User.class).list();
        for (Object[] objects : list) {
            System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(objects[0]));
        }

结果:
Hibernate:
select
*
from
user
2017-08-02
2017-08-02
2017-08-02

从结果可以看出,join_time默认是相应的类型(timestamp)
如果给这个join_time指定一个类型:

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        List<Object[]> list = session.createSQLQuery("select * from user").addScalar("join_time",StandardBasicTypes.STRING).addEntity(User.class).list();
        for (Object[] objects : list) {
            System.out.println(objects[0] instanceof String);
        }

结果:
Hibernate:
select
*
from
user
true
true
true

从结果可以看出,确实将字段以指定的类型取了出来

实例3
分页:

Session session = HibernateUtil.SESSIONFACTORY.openSession();
        //注意这里的对象是Query,说明有继承关系,并且分页也同样适用于HQL查询
        Query query = session.createSQLQuery("select * from user").addEntity(User.class);
        //相当于设置了limit 0,2
        List<User> list = query.setFirstResult(0).setMaxResults(2).list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }

结果:
Hibernate:
select
*
from
user limit ?
admin1
admin2

  • HQL查询(重点)

HQL全称:Hibernate Query Language

通过session.createQuery(hql语句)来获得Query对象

hql语句中的字段全部都是对象的属性或对象的

hql中的select * 可以省略不写

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("from User");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }

如果非要写可以利用起别名

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("select u from User as u");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }

结果都是一样的:
Hibernate:
select
user0_.id as id1_0_,
user0_.username as username2_0_,
user0_.password as password3_0_,
user0_.join_time as join_tim4_0_
from
User user0_
admin1
admin2
admin123

可以通过两种方式设置占位符:
1.set类型(占位符,值);
2.setParameter(占位符,值);
区别:set类型 效率高 ,setParameter效率低但方便(可以不用知道字段的类型)

上面的两种方式就在下面的例子中一起展示了

占位符的两种形式:
1.?

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("from User where username = ?");
        //注意了,hibernate中占位符下标从0开始,JDBC中从1开始
        query.setString(0, "admin123");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }
Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("from User where username = ?");
        //这里用了parameter
        query.setParameter(0, "admin123");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }

2.:变量名

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("from User where username = :myvar");
        query.setString("myvar", "admin123");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }
        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("from User where username = :yourvar");
        query.setParameter("yourvar", "admin123");
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user.getUsername());
        }

以上4个代码块结果相同:
Hibernate:
select
user0_.id as id1_0_,
user0_.username as username2_0_,
user0_.password as password3_0_,
user0_.join_time as join_tim4_0_
from
User user0_
where
user0_.username=?
admin123

可以将查询的字段指定为自己的类型:

        Session session = HibernateUtil.SESSIONFACTORY.openSession();
        Query query = session.createQuery("select new map(username as un,password as pw) from User");
        List<Map<String,String>> list = query.list();
        for (Map<String, String> map : list) {
            System.out.println(map);
        }

结果:
Hibernate:
select
user0_.username as col_0_0_,
user0_.password as col_1_0_
from
User user0_
{un=admin1, pw=abc123}
{un=admin2, pw=abc123}
{un=admin123, pw=abc123}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值