You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CriteriaQuery中实现Restrictions.sqlRestriction?

在JPA CriteriaQuery中实现类似Restrictions.sqlRestriction的原生SQL限制

当然可以实现,结合你使用的Hibernate环境(从getSession()调用判断),以下是两种实用方案:

方案1:直接使用Hibernate专属API(最贴合旧版用法)

这是替代旧Restrictions.sqlRestriction()的最优方式,支持参数绑定避免SQL注入:

CriteriaBuilder builder = getSession().getCriteriaBuilder();
CriteriaQuery<Test> query = builder.createQuery(Test.class);
Root<Test> root = query.from(Test.class);

// 示例1:添加带位置参数的原生SQL条件
Predicate sqlPredicate = builder.sqlRestriction("test_column > ?1", 100, Integer.class);

// 示例2:添加带命名参数的原生SQL条件(更易读)
// Predicate sqlPredicate = builder.sqlRestriction(
//     "status = :activeStatus AND create_time > :startTime",
//     Map.of("activeStatus", "ACTIVE", "startTime", LocalDate.now().minusDays(7))
// );

query.where(sqlPredicate);

// 执行查询
List<Test> results = getSession().createQuery(query).getResultList();

方案2:通用JPA兼容方案(不依赖Hibernate特性)

如果需要保持JPA标准兼容性,可通过自定义表达式实现原生SQL条件:

CriteriaBuilder builder = getSession().getCriteriaBuilder();
CriteriaQuery<Test> query = builder.createQuery(Test.class);
Root<Test> root = query.from(Test.class);

// 构建包含原生SQL片段的布尔表达式
Expression<Boolean> sqlCondition = builder.function(
    "BOOLEAN", Boolean.class,
    builder.literal("test_column LIKE '%keyword%'")
);

query.where(sqlCondition);
List<Test> results = getSession().createQuery(query).getResultList();

关键注意点

  • 始终使用参数绑定(位置参数?1或命名参数),禁止直接拼接字符串,避免SQL注入
  • 原生SQL中的表/列名要与数据库实际映射一致,若Hibernate配置了表名/列名映射,需使用映射后的名称
  • 方案1是Hibernate特有的实现,写法简洁;方案2兼容所有JPA实现,但灵活性稍弱

内容的提问来源于stack exchange,提问作者Navneet Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:20:26