SpringBoot-Spring Data Jpa Tuning

創造を続け、成長を加速させましょう!「ナゲッツデイリーニュープラン・6月アップデートチャレンジ」に参加して4日目です。クリックしてイベントの詳細をご覧ください。

Hibernateは迅速な開発に非常に便利ですが、クエリプロセスのSQLの複雑さと、N + 1クエリの問題のため、中国では広く使用されていません。以下に、参照用のN+1クエリ問題のチューニングソリューションをいくつか示します。それだけ。

クエリメソッドの実行から生じるN+1クエリ

基準クエリ

Specification.toPredicateメソッドでfetchメソッドを使用します。書き込みメソッドは次のとおりです。使用後、クエリはクエリに関連付けられます。ただし、コレクションエンティティの属性については、誤ったデータが生成されます。お勧めしません。このメソッドを使用してコレクション属性を照会します。

   public Predicate toPredicate(Root<实体> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    root.fetch("xxx");
    ...
    List<Predicate> predicates = new ArrayList<>();
    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
   }
复制代码

ページングクエリは最初にカウントをチェックするため、ページングクエリは判断を追加する必要があります

   public Predicate toPredicate(Root<实体> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    if(criteriaQuery.getResultType().equals(实体.class)){
     root.fetch("xxx"); 
    }
    ...
    List<Predicate> predicates = new ArrayList<>();
    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
   }
复制代码

root.fetch( "xxx")ここで、xxxはエンティティ内の特定の属性です

@Queryを使用したクエリ

 @Query(value = "select d from Document d join fetch e.filetype ")
 List<User> findDocuments();

复制代码

その他:すべてのプロパティをフェッチすると、すべてのプロパティが積極的にクエリされますが、コレクションのプロパティは自動的に偽造されません

 @Query(value = "select d from Document d fetch all properties")
 List<User> findDocuments();
复制代码

シリアル化されたエンティティから生じるN+1クエリ

背景メモ

チューニングの前に、2つの構成について説明します。

//是否支持当实体在没有标记事务的方法中访问设置为lazy的属性
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
//使用jackson序列化时 实体属性为lazy时是否报错
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS = false
复制代码

構成を有効にすると、フロントエンドページに戻るエンティティのJSONシリアル化プロセス中にLazyとマークされた属性が呼び出され、セカンダリクエリがトリガーされます。オンにしない場合、システムのフロントエンドに戻るシリアル化のループで次の2つの例外は発生しません。

//List属性:
 com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of 属性名: 实体.属性, could not initialize proxy - no Session
// 实体属性:
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer];
复制代码

解決

  • jsonシリアル化の最良の方法は、@ JsonIgnoreを使用してコレクションのプロパティを無視し、エンティティのプロパティをフェッチすることです。
  • エンティティをサービス中のvoに変換します

参考文献

yq.aliyun.com/articles/23…

www.cnblogs.com/lcchuguo/p/…

www.java2s.com/Tutorials/J…

docs.jboss.org/hibernate/o…

おすすめ

転載: juejin.im/post/7102686972417671181