跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Spring Data JPA nativeQuery 的问题,在线跪求大佬解答。
未分類
30 5 月 2020

Spring Data JPA nativeQuery 的问题,在线跪求大佬解答。

Spring Data JPA nativeQuery 的问题,在线跪求大佬解答。

資深大佬 : snailsir 1

背景:本人不会 java,但是基本上能够看懂逻辑,维护一个老 java 项目,现在遇到一个慢查询的问题( mysql 最后选择了一个错误的索引),不考虑数据库表的修改,索引都是正常的。

spring-data-jpa 版本:1.6.5 。

问题描述如下:

首先 status 是一个枚举。然后有下面有两个基于 JPA 查询数据的方法

public enum Status {     UPLOADING,  // 0     PROCESSING, // 1     PUBLISHED,  // 2     FAILED,     // 3     DELETED;    // 4 }      // 方法一:生成的 sql 存在慢查询问题( mysql 选择了一个错误的索引) Slice<Document> findByUserIdAndStatusIn(String userId, Collection<Status> status, Pageable pageable);  // 方法二:使用 nativeQuery,指定使用的索引 @Query(value = "select * from #{#entityName} use index (userId_createTime_idx) "                 + " where userId = :userId and status in :status "                 + " order by createTime desc "                 + " limit :offset,:size",     nativeQuery = true) List<Document> findByUserIdAndStatusInUseIndex(@Param("userId") String userId,                                                 @Param("status") Collection<Status> status,                                                 @Param("offset") int limitOffset,                                                 @Param("size") int limitSize); 

第一个方法最后生成的 sql 语句是正常的,比如

status in (1,2,3) 

第二个方法是新增的,使用 nativeQuery 指定使用索引,但基于同样的参数Collection<Status> status生成的 sql 语句,就不正常,比如

// 里面的...翻译后,涉及敏感信息,故用...代替 status in (     x'...2E706C6174666F726D2E6D6F64656C2E646F63756D656E742E53746174757300000000000000001200007872000E6A6176612E6C616E672E456E756D0000000000000000120000787074000A50524F43455353494E47',      x'...2E706C6174666F726D2E6D6F64656C2E646F63756D656E742E53746174757300000000000000001200007872000E6A6176612E6C616E672E456E756D000000000000000012000078707400095055424C4953484544',      x'...2E706C6174666F726D2E6D6F64656C2E646F63756D656E742E53746174757300000000000000001200007872000E6A6176612E6C616E672E456E756D000000000000000012000078707400064641494C4544')   

这几个莫名的字符,经过翻译之后,是这样的

.platform.model.document.Status           xr  java.lang.Enum           xpt  PROCESSING  .platform.model.document.Status           xr  java.lang.Enum           xpt  PUBLISHED  .platform.model.document.Status           xr  java.lang.Enum           xpt  FAILED 

所以,使用 nativeQuery 之后,为什么同样的参数Collection<Status> status最后生成的 sql 语句就不对了?如果是使用姿势不对,那该怎么解决啊?[快哭了]

大佬有話說 (11)

  • 資深大佬 : duwan

    你把参数 Collection<Status>换成 Collection<Integer>不就行了?

  • 資深大佬 : duwan

    然后,先将 Collection<Status>转换成 Collection<Integer>,再调用

  • 主 資深大佬 : snailsir

    @duwan 怎么转换啊

  • 資深大佬 : lybcyd

    JPA 把枚举填进 SQL 不会自动转换吧。你手动转换成 int 就可以了。不过建议你看看 jpa 自动生成的语句为什么不会用到正确的索引,还需要手动指定索引。

  • 資深大佬 : hantsy

    nativeQuery 基本对应 Jdbc 语句,执行数据库原始的 SQL 。

    在用 JPA 真的很少用。忘记不了 SQL,还不如直接用 jdbc 。Spring 的 Jdbc 封装真的不错,另外 Spring Data Jdbc 相当于一个简单的 ORM 框架。

  • 主 資深大佬 : snailsir

    @lybcyd 但是第一个非 nativeQuery 的方式,生成的 `status in (1,2,3)` 就是正确的啊。只是下面使用 nativeQuery 的时候,就不正常了。

    手动转换成 int 怎么搞呀,本人不太会 java [哎]

  • 主 資深大佬 : snailsir

    @hantsy 这个是老项目,使用的 JPA,目前都不想动了,只是维护,改改 bug 的那种样子,本人也不大会 java,所以换基本上是不可能的 [无奈]

  • 資深大佬 : kevinWHX

    UPLOADING.ordinal() =1

  • 資深大佬 : Jrue0011

    不太了解 SPRING DATA JPA,似乎用了 nativeQuery 后就不支持枚举的处理,可能作为 Object 序列化了。

    解决办法:

    1 、参数改成 Collections<Integer>,然后调用的地方手动将 Collections<Status>转成 Collections<Integer>

    2 、参考这个定义一个接口和实现,实现注册 bean,可以注入 jdbcTemplate 做某些操作,最后让这个 repository 继承自定义接口就可以了。

    https://docs.spring.io/spring-data/jpa/docs/1.6.5.RELEASE/reference/html/repositories.html#repositories.single-repository-behaviour

  • 主 資深大佬 : snailsir

    @Jrue0011 嗯,我也是感觉使用 nativeQuery 之后,枚举就不行了。目前在考虑将 Collections<Status> 转成 Collections<Integer>,然后再试试了。

  • 主 資深大佬 : snailsir

    @Jrue0011 但是不知道为啥使用 nativeQuery 之后,枚举就不行了,哪里出了问题。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具