JPA将列表传递给命名本机查询中的IN子句

Li *_*Yin 28 jpa arraylist in-clause nativequery

我知道我可以在JPA中将列表传递给命名查询,但NamedNativeQuery怎么样?我尝试了很多方法,但仍然无法将列表传递给NamedNativeQuery.任何人都知道如何将列表传递给NamedNativeQuery中的in子句?非常感谢你!

NamedNativeQuery如下:

@NamedNativeQuery(
   name="User.findByUserIdList", 
   query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+
         "where u.user_id in (?userIdList)"
)
Run Code Online (Sandbox Code Playgroud)

它被称为这样:

List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList();
Run Code Online (Sandbox Code Playgroud)

但结果并不像我预期的那样.

System.out.println(userList.size());  //output 1

Object[] user = userList.get(0);
System.out.println(user.length);   //expected 5 but result is 3
System.out.println(user[0]);       //output MDAVERSION which is not a user_id
System.out.println(user[1]);       //output 5
System.out.println(user[2]);       //output 7
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 16

列表不是本机SQL查询的有效参数,因为它不能绑定在JDBC中.您需要为列表中的每个参数指定一个参数.

其中u.user_id在(?id1,?id2)

这通过JPQL支持,但不支持SQL,因此您可以使用JPQL而不是本机查询.

某些JPA提供程序可能会支持此功能,因此您可能希望记录提供程序的错误.

  • 注意:这个答案是错误的。请参阅下面的答案以及参考资料。 (5认同)

Hop*_*ing 12

上面接受的答案是不正确的,让我偏离了很多天!!

JPA和Hibernate都使用Query接受本机查询中的集合.

你只需要这样做

String nativeQuery = "Select * from A where name in :names"; //use (:names) for older versions of hibernate
Query q = em.createNativeQuery(nativeQuery);
q.setParameter("names", l);
Run Code Online (Sandbox Code Playgroud)

另请参考这里提出相同的答案(我从其中一个中选择了上面的例子)

  1. 参考1
  2. 参考文献2提到了将列表作为参数的哪些情况下的paranthesis有效

  • 那些是JPA/JPQL查询,而不是本机SQL查询,现在是它们.问题是关于_native queries_,接受的答案甚至可以说出这种差异,或者我在这里误读了什么? (4认同)
  • 这是错误的,也是行不通的。您可以在 JPA/JPQL 查询中执行此操作,而不是像 @SanderVerhagen 所说的本机 SQL 查询 (3认同)
  • 对我有用,但前提是列表中至少有 1 个条目。 (2认同)
  • 这对我来说根本不适用于本机查询,答案不正确 (2认同)

小智 12

可以很简单:

@Query(nativeQuery =true,value = "SELECT * FROM Employee as e WHERE e.employeeName IN (:names)")  
 List<Employee> findByEmployeeName(@Param("names") List<String> names);
Run Code Online (Sandbox Code Playgroud)


Isi*_*oan 9

使用 hibernate、JPA 2.1 和 deltaspike 数据,我可以将列表作为包含 IN 子句的查询中的参数传递。我的查询如下。

@Query(value = "SELECT DISTINCT r.* FROM EVENT AS r JOIN EVENT AS t on r.COR_UUID = t.COR_UUID where " +
        "r.eventType='Creation' and t.eventType = 'Reception' and r.EVENT_UUID in ?1", isNative = true)
public List<EventT> findDeliveredCreatedEvents(List<String> eventIds);
Run Code Online (Sandbox Code Playgroud)


Erh*_*nis 5

实际上,根据您的数据库/提供者/驱动程序/等等,您可以将列表作为绑定参数传递给JPA本机查询。

例如,使用Postgres和EclipseLink,以下工作(返回true),展示了多维数组以及如何获取双精度数组。(SELECT pg_type.* FROM pg_catalog.pg_type对于其他类型,请执行;可能是与一起使用_,但在使用前先将其剥离。)

Array test = entityManager.unwrap(Connection.class).createArrayOf("float8", new Double[][] { { 1.0, 2.5 }, { 4.1, 5.0 } });
Object result = entityManager.createNativeQuery("SELECT ARRAY[[CAST(1.0 as double precision), 2.5],[4.1, 5.0]] = ?").setParameter(1, test).getSingleResult();
Run Code Online (Sandbox Code Playgroud)

强制转换在那里,因此文字数组是双精度的,而不是数字的。

更重要的是,我不知道如何或是否可以进行命名查询。我认为这可能取决于。但我认为以下方法对Array有用。

Array list = entityManager.unwrap(Connection.class).createArrayOf("int8", arrayOfUserIds);
List<Object[]> userList = entityManager.createNativeQuery("select u.* from user u "+
     "where u.user_id = ANY(?)")
     .setParameter(1, list)
     .getResultList();
Run Code Online (Sandbox Code Playgroud)

我没有与OP相同的架构,因此我没有进行确切的检查,但是我认为它应该可以工作-至少在Postgres和EclipseLink上可以。

此外,还可以在以下网址找到该密钥:http : //tonaconsulting.com/postgres-and-multi-dimensions-arrays-in-jdbc/