spring-data-jpa 使用 @Query 和 @Modifying 插入而不使用 nativeQuery 或 save() 或 saveAndFlush()
Posted
技术标签:
【中文标题】spring-data-jpa 使用 @Query 和 @Modifying 插入而不使用 nativeQuery 或 save() 或 saveAndFlush()【英文标题】:spring-data-jpa to insert using @Query & @Modifying without using nativeQuery or save() or saveAndFlush() 【发布时间】:2018-01-26 14:50:39 【问题描述】:我看过这些链接
How to use JPA Query to insert data into db? 使用 nativeQuery=true How to insert into db in spring-data? 建议使用内置的保存方法(还有一个 saveAndFulsh() 方法)我的例子如下:
Person 是一个简单的实体,包含 3 个字段“Long id、String name、Integer age”,并且映射到对应的 Person 表,每个表包含 3 个列)
@Repository
public interface DualRepository extends JpaRepository<Dual,Long>
@Modifying
@Query(? - what goes here - ?)
public int modifyingQueryInsertPerson(@Param("id")Long id, @Param("name")String name, @Param("age")Integer age);
有没有办法只使用@Query & @Modifying 进行插入(即不使用本机 SQL 查询 & nativeQuery=true,或者,save(),或者,saveAndFlush()?
【问题讨论】:
【参考方案1】:而不是传递所有参数,您可以传递 java 对象,如下所示
@Modifying(clearAutomatically = true)
@Transactional
@Query(value = "insert into [xx_schema].[shipment_p] (gpn,qty,hscode,country_of_origin,created_date_time,shipment_id) "
+ "VALUES (:##sp.gpn,:##sp.qty, :##sp.hscode ,:##sp.countryOfOrigin, :##sp.createdDateTime, :##sp.id )", nativeQuery = true)
public void saveShipmentPRoducts(@Param("sp") ShipmentProducts sp);
【讨论】:
【参考方案2】:@Query
通常用于创建自定义用户查询以从数据库中获取值
@Query
和@Modifying
用于在数据库中执行更新操作
save
方法用于插入新记录或更新会话中存在的记录。
【讨论】:
请看我上面的评论。使用 @Query+@Modifying 的 INSERT 将适用于具有虚拟表的数据库(如 Oracle 中的 DUAL),因此我们可以在 SELECT 之后有一个 FROM 子句(这是 HQL 所要求的)。【参考方案3】:在尝试了几件事之后,有一种方法可以做到这一点,但这取决于您使用的数据库。
下面在 Oracle 中为我工作 & 1 行被插入到表中(使用 Dual 表,因为我可以在“select”之后使用“from Dual”):
@Repository
public interface DualRepository extends JpaRepository<Dual,Long>
@Modifying
@Query("insert into Person (id,name,age) select :id,:name,:age from Dual")
public int modifyingQueryInsertPerson(@Param("id")Long id, @Param("name")String name, @Param("age")Integer age);
在 MS SqlServer 中,可以有一个没有“from 子句”的“select”,所以“select 10,'name10',100”可以工作,所以下面的内容应该适用于 MS Sqlserver(但还没有测试过)
@Repository
public interface PersonRepository extends JpaRepository<Person,Long>
@Modifying
@Query("insert into Person (id,name,age) select :id,:name,:age")
public int modifyingQueryInsertPerson(@Param("id")Long id, @Param("name")String name, @Param("age")Integer age);
我没有尝试过使用任何其他数据库。这是一个链接,它显示(最后)哪个 db 支持不带 from 子句的 select stmts:http://modern-sql.com/use-case/select-without-from
【讨论】:
经过进一步测试,它不在 MS-SqlServer 中工作,因为 MS-SqlServer 不提供系统虚拟表(如 Oracle 中的 DUAL)。它确实在 Oracle 和 mysql 中工作,因为它们都有一个 DUAL 虚拟表。由于 HQL 在 SELECT 之后需要 FROM,因此仅当底层数据库具有虚拟表(如 Oracle 中的 DUAL)时,上述方法才适用于 INSERT。以上是关于spring-data-jpa 使用 @Query 和 @Modifying 插入而不使用 nativeQuery 或 save() 或 saveAndFlush()的主要内容,如果未能解决你的问题,请参考以下文章
spring-data-jpa 存储库在 Query 中使用 Collection 作为 @Param
spring-data-jpa 使用 @Query 和 @Modifying 插入而不使用 nativeQuery 或 save() 或 saveAndFlush()
在 spring-data-jpa 中通过布尔属性查询而不使用方法参数