Java框架 Hibernate入门笔记二 使用HQL&Criteria&标准SQL

之前已经学过了如何用Hibernate做简单的CRUD操作, 但是SQL语句其实有很多功能, 光有之前的简单crud可能是不够的, 比如之前的:
Retrieve查询是只能根据主键(id)来查询

一.通过HQL进行查询

这是一种类似于SQL的语法;
比如可以这样做:

import Entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        String name = "client";
        Query q = s.createQuery("from User a where a.name like :name");
        q.setParameter("name",name+"%");
        List<User> list = q.list();
        for(User i : list){
            System.out.println(i);
        }

        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

之前的HQL语法和我这里写的有些不同, 因为现在的HQL可以使用JPA-style来符合java persistence api, 有两种写法:
一种是像我上面写的, 使用命名的方式3:

Query q = s.createQuery("from User a where a.name like :name");
q.setParameter("name",name+"%");

也可以这样, 使用占位符:

Query q = s.createQuery("from User a where a.name like ?0");
q.setParameter(0,name+"%");

以前的HQL语法现在已经过时如果用这样的语法:

Query q = s.createQuery("from User a where a.name like ?");
q.setString(0,name+"%");

可能会提示
org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported;
最好使用新标准的JPA规范;

二.使用CRITERIA进行查询

第一个问题是什么事Criteria, 为什么要用它:
Criteria API,它为 Java 语言带来了一种独特的能力:开发一种 Java 编译器可以在运行时验证其正确性的查询。Criteria API 还提供一个能够在运行时动态地构建查询的机制。
Criteria可以保证查询的输出结果是对应于某个实体类的, 而不是运行之后才发现类型不匹配;
Criteria API 的最大优势之一就是禁止构造语法错误的查询。
可以使用Criteria进行查询:

import Entity.User;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import java.util.List;

public class Test {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        String name = "client";
        Criteria c = s.createCriteria(User.class);
        c.add(Restrictions.like("name",name+"%"));
        List<User> list = c.list();
        for(User i : list){
            System.out.println(i);
        }
        
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

查询结果大概是这样:
在这里插入图片描述
但是可以看到, 这种方法似乎已经过时了;
好像新的做法大概是这样的:

import Entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        String name = "client";

        CriteriaBuilder crb= s.getCriteriaBuilder();
        CriteriaQuery<User> crq=crb.createQuery(User.class);
        Root<User> root=crq.from(User.class);
        crq.select(root);
        crq.where(crb.like(root.get("name"),name));
        List<User> list = s.createQuery(crq).getResultList();

        for(User i : list){
            System.out.println(i);
        }

        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

流程大概是这样:
1.从Hibernate获得一个Session
2.从Session中获得一个用于Criteria的builder然后创建一个对User的查询Query
3.设置query的查询内容
4.获得ResultList

这里对于设置query的查询内容部分代码可以简单理解一下;
Root<User> root=crq.from(User.class);这里就相当于sql中的from user
crq.select(root);表示把root用于select查询
crq.where(crb.like(root.get("name"),name));表示给query添加一个where的条件(限制);

在Hibernate中也可以:

三.使用标准的sql语句进行查询

代码大概是这样:

import Entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test {

    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        String name = "client";

        String sql = "select * from user where name like \'"+name+"%\'";
        Query q = s.createSQLQuery(sql);
        List<Object[]> list = q.list();

        for(Object[] i : list){
            for(Object j : i){
                System.out.println(j);
            }
        }

        s.getTransaction().commit();
        s.close();
        sf.close();
    }

}

注意是s.createSQLQuery(sql);要指定是SQL查询;
查询结果大概是这样:

要注意的是这里的返回结果是一个Object[]数组的List, 数组里面存放着表中的数据;
因为标准SQL语句有可能返回各种各样的结果,比如多表查询,分组统计结果等等。 不能保证其查询结果能够装进一个Product对象中,所以返回的集合里的每一个元素是一个对象数组。 然后再通过下标把这个对象数组中的数据取出来。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值