红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Spring Boot 学习笔记
  4. 正文

从零开始 Spring Boot 66:JPA 查询参数

2023年7月8日 942点热度 0人点赞 0条评论

spring boot

图源:简书 (jianshu.com)

JPA 的查询参数分为两种:

  • 命名参数(Named Parameters)

  • 位置参数(Positional Parameters)

类似于 Python 中的函数的位置参数和指名参数。

本文的示例使用下面的实体类:

@Entity
public class Student {
    private static final int MAX_SCORE = 100;
    private static final int MIN_SCORE = 0;
​
    public enum Type {
        MIDDLE_SCHOOL_STUDENT,
        HIGH_SCHOOL_STUDENT,
        COLLEGE_STUDENT
    }
​
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
​
    @Length(max = 45)
    @NotBlank
    @NotNull
    @Column(unique = true)
    private String name;
​
    @NotNull
    private Type type;
​
    @NotNull
    @Min(MIN_SCORE)
    @Max(MAX_SCORE)
    private Integer mathScore;
​
    @NotNull
    @Min(MIN_SCORE)
    @Max(MAX_SCORE)
    private Integer englishScore;
​
    @NotNull
    @Min(MIN_SCORE)
    @Max(MAX_SCORE)
    private Integer chineseScore;
}

位置参数

位置参数由?+数字构成。

直接看示例:

List<Student> students = session.createQuery("select s from Student s where s.chineseScore>=?1" +
                                             " and s.mathScore>=?2" +
                                             " and s.englishScore>=?3", Student.class)
    .setParameter(1, 50)
    .setParameter(2, 60)
    .setParameter(3, 70)
    .getResultList();
students.forEach(s -> {
    System.out.println(s);
});

JPQL 中的?1表示位置为1的参数,该参数由setParameter(1, ...)设置参数值。

位置参数同样可以在原生 SQL 中使用:

List<Student> students = session.createNativeQuery("select * from student as s where s.chinese_score>=?1" +
                                                   " and s.math_score>=?2" +
                                                   " and s.english_score>=?3", Student.class)
    .setParameter(1, 50)
    .setParameter(2, 60)
    .setParameter(3, 70)
    .getResultList();

命名参数

命名参数由:+参数名称构成。

示例:

String searchName = "icexmoon";
var student = session.createQuery("select s from Student s where s.name=:name", Student.class)
    .setParameter("name", searchName)
    .getSingleResult();

可以调用Query.setParameter并结合参数名称来设置参数值。

同一个名称的参数可以在 JPQL 中使用多次:

var students = session.createQuery("select s from Student s where s.mathScore>=:minScore" +
                                   " and s.englishScore>=:minScore" +
                                   " and s.chineseScore>=:minScore", Student.class)
    .setParameter("minScore", 70)
    .getResultList();

当然值只需要设置一次。

命名参数同样可以在 Hibernate 的原生 SQL 上使用:

String searchName = "icexmoon";
var student = session.createNativeQuery("select * from student as s where s.name=:name", Student.class)
    .setParameter("name", searchName)
    .getSingleResult();

不过 JPA 本身并没有要求原生 SQL 必须支持命名参数,所以 Hibernate 的原生 SQL 支持命名参数并不代表所有的 JPA 实现都支持。

集合参数

无论是位置参数还是命名参数,都可以使用集合作为参数值:

var students = session.createQuery("select s from Student s where s.type in :types", Student.class)
    .setParameter("types", List.of(Student.Type.HIGH_SCHOOL_STUDENT, Student.Type.COLLEGE_STUDENT))
    .getResultList();

条件查询参数

在条件查询(Criterial Query)中同样可以定义参数:

var cb = sessionFactory.getCriteriaBuilder();
JpaCriteriaQuery<Object> query = cb.createQuery();
JpaRoot<Student> root = query.from(Student.class);
JpaParameterExpression<String> nameParam = cb.parameter(String.class);
JpaParameterExpression<Integer> minScoreParam = cb.parameter(Integer.class);
query = query.select(root)
    .where(cb.and(cb.equal(root.get("name"), nameParam),
                  cb.ge(root.get("chineseScore"), minScoreParam),
                  cb.ge(root.get("mathScore"), minScoreParam),
                  cb.ge(root.get("englishScore"), minScoreParam)));
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = (Student) session.createQuery(query)
    .setParameter(nameParam, "icexmoon")
    .setParameter(minScoreParam, 60)
    .getSingleResult();
System.out.println(student);
transaction.commit();
session.close();

这里需要用HibernateCriteriaBuilder.parameter方法创建JpaParameterExpression对象作为条件查询中的参数对象,该对象可以用于HibernateCriteriaBuilder.ge或HibernateCriteriaBuilder.equal这样的 API 构建条件语句,也可以用于Query.setParamter方法的参数来设置执行查询时的参数值。

The End,谢谢阅读。

可以从这里获取本文的完整实例代码。

参考资料

  • JPA Query Parameters Usage | Baeldung

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: jpa spring 参数
最后更新:2023年7月8日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号