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

本文介绍了SpringBoot中JPA查询的两种参数类型:命名参数和位置参数。通过示例展示了如何在JPQL和原生SQL中使用这两种参数,以及如何处理集合参数和条件查询参数。此外,还提到了在条件查询(CriterialQuery)中定义参数的方法。

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

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

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.geHibernateCriteriaBuilder.equal这样的 API 构建条件语句,也可以用于Query.setParamter方法的参数来设置执行查询时的参数值。

The End,谢谢阅读。

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

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值