如何在JPA中使用预处理语句

14

我是一名Play框架应用程序开发人员。我正在使用JPA中的createNativeQuery方法。在这个例子中,我想要使用预处理语句。请有经验的人帮助我。 以下是没有JPA的代码。我需要帮助将其转换为预处理语句。

Query query = JPA.em().createNativeQuery("select count(*) from truck t inner join" +
    "box b where t.truck_id=b.truck_id and t.shipment_upc='" + code + "'");

BigInteger val = (BigInteger)query.getSingleResult();
System.out.println(val);

2
使用参数t.shipment_upc= :upc -> setParameter("upc", code) - Paul Samsotha
谢谢您的回复。我是一个初学者。您能详细告诉我吗?提前感谢您。 - user3454863
Subir的回答指出了这一点 :) - Paul Samsotha
谢谢,非常感谢。 - user3454863
2个回答

21
Query query = JPA.em().createNativeQuery("select count(*) from truck t inner join box b where t.truck_id=b.truck_id and t.shipment_upc=:code");
query.setParameter("code", code);

3
嘿,@SubirKumarSao,使用像":xxx"这样的标签参数在“createNativeQuery”上不起作用,只能在“createQuery”上起作用,至少在我使用EclipseLink的设置中是如此。你确定上面的代码可以运行吗?如果是的话,请告诉我你使用的版本是什么?感谢合作。 - Adriano Spadoni
1
它对于选择和更新的操作完美地工作。我想知道如何执行相同的插入操作。 - user3454863
@Drix 你说的很对,至少在EclipseLink(至少到2.5.1版本为止)中是不可能实现的。请参见 我的答案 以获取与EclipseLink兼容的解决方案 - 采用位置参数。 - Birchlabs
我认为楼主要求的是PreparedStatement.class,它具有批量执行的优点?这并没有真正回答问题。 - TheRealChx101

6

简要概述

在这里,您需要使用查询参数,但由于您正在使用本机查询,因此与JPQL相比,您的选项可能受到限制。

世界状态

您可能仅限于位置参数

JPA不要求本机查询支持命名参数,但某些JPA提供程序可能会支持

Hibernate对JPA的实现支持命名参数

本机SQL查询支持位置参数和命名参数


解决方案

Hibernate

Subir Kumar Sao的答案展示了如何使用命名参数解决此问题。至少在Hibernate中是可行的。

为了比较起见,我将在此重复它:

Query query = JPA.em().createNativeQuery(
"SELECT COUNT(*) "+
"FROM truck AS t "+
"INNER JOIN box b "+
"WHERE t.truck_id = b.truck_id "+
"AND t.shipment_upc = :code"
);
query.setParameter("code", code);

通用JPA(包括EclipseLink)

我发现在EclipseLink(2.5.1)中不支持命名参数。

相反,需要使用位置参数。这可以通过两种方式来表达-显式和隐式。

显式索引

使用?1(或其他数字)标记参数。此索引可用于在查询中唯一标识该特定参数。

Query query = JPA.em().createNativeQuery(
"SELECT COUNT(*) "+
"FROM truck AS t "+
"INNER JOIN box b "+
"WHERE t.truck_id = b.truck_id "+
"AND t.shipment_upc = ?1"
);
query.setParameter(1, code);

隐式索引

只需使用?来标记参数。它的索引将基于参与查询字符串的所有参数的顺序。

Query query = JPA.em().createNativeQuery(
"SELECT COUNT(*) "+
"FROM truck AS t "+
"INNER JOIN box b "+
"WHERE t.truck_id = b.truck_id "+
"AND t.shipment_upc = ?"
);
query.setParameter(1, code);

注意事项

请注意以下内容:

  • 位置参数从1开始计数。
  • Query 参数映射中的键仅为定位参数的索引。

其他参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接