SpringDataJPAで動的クエリを実装する2つの方法


序文
一般に、ビジネスインターフェイスを作成するプロセスでは、さまざまなクエリ条件を動的に組み合わせることができるインターフェイスを実装する可能性が非常に高くなります。クエリ条件に従ってメソッドを作成すると、メソッドが多数存在することになり、煩雑で保守が困難になります。実際、動的クエリを実現するには、スプライシングSQLステートメントを実装する必要があります。実装がどれほど複雑であっても、基本的には、selectフィールド、fromまたはjoinテーブル、およびwhereまたはhaing条件が含まれます。 Spring Data JPAでクエリ条件の動的クエリを実装する方法は2つあり、どちらもCriteriaAPIを使用します。
基準API
このAPIのセットを使用して、データベースに対するクエリを作成できます。


タイプセーフティ。メタデータモデルを定義することにより、タイプを見つけるためにMysqlと対話する必要があるSQLとは異なり、プログラムのコンパイル段階でタイプをチェックできます。傷。


以下はメタデータモデルです。メタモデルクラスを作成します。クラス名の最後の文字はアンダースコアであり、内部メンバー変数はエンティティクラスUserInfo.classの属性値に対応します。


@StaticMetamodel(UserInfo.class)
public class UserInfo_ {
public static volatile SingularAttribute userId;
public static volatile SingularAttribute name;
public static volatile SingularAttribute age; < br /> public static volatile SingularAttribute high;
}

ポータブル。 strong> APIは特定のデータベースに依存せず、データベースの種類に応じてデータベースの種類に対応するSQLを生成できるため、移植性があります。


オブジェクト指向。 strong> Criteria APIは、CriteriaQuery、Predicateなどのさまざまなクラスとオブジェクトを使用してクエリを構築し、オブジェクト指向です。そして、SQLを直接書く場合、それはstrinに関連していますgs。
1つ目:JPAのCriteriaAPIを使用


li>EntityManagerはCriteriaBuilderを取得します
CriteriaBuilderはCriteriaQueryを作成します
CriteriaQueryはテーブルを次のように指定しますクエリされ、ルートを取得します。ルートはクエリされるテーブルを表します
li>CriteriaBuilderは条件付き述語を作成します。述語は、SQLwhere条件に関連しています。複数の述部は、ANDまたはOR操作を実行できます。
li>EntityManagerを使用してTypedQueryを作成する
TypedQueryはクエリを実行し、結果を返します
li> ol>


public class UserInfoExtendDao {

@PersistenceContext(unitName = "springJpa")
EntityManager em;

public List getUserInfo(String name、int age、 int high){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery query = cb.createQuery(UserInfo.class);

// from
ルートルート= query.from(UserInfo.class);

// where
述語p1=null;
if(name!= null){
述語p2= cb.equal(root.get(UserInfo_.name)、name);
if(p1!= null){
p1 = cb.and(p1、p2);
} else {
p1 = p2;
}
} < br />
if(age!= 0){
述語p2= cb.equal(root.get(UserInfo_.age)、age);
if(p1!= null){
p1 = cb.and(p1、p2);
} else {
p1 = p2;
}
}

if( high!= 0){
述語p2= cb.equal(root.get(UserInfo_.high)、high);
if(p1!= null){
p1 = cb.and (p1、p2);
} else {
p1 = p2;
}
}
query.where(p1);

List userInfos = em.createQuery(query).getResultList();
return userInfos;
}
}



2番目:DAOレイヤーインターフェースはJpaSpecificationExecutorインターフェースを実装します strong>
JpaSpecificationExecutorは次のとおりです。メソッドパラメータSpecificationインターフェイスにはメソッドtoPredicateがあり、戻り値は正確にPredicateです。Criteria API、および述語はSQLwhere条件に関連しています。以前の方法と比較して、この書き込み方法では、クエリするテーブルを指定する必要がなく、CriteriaAPIを介して並べ替えとページングを実装する必要もありません。新しいPageableおよびSortオブジェクトを作成し、パラメータをfindAllメソッドに渡すだけです。よりシンプル。


public interface JpaSpecificationExecutor {
T findOne(Specification spec);
List findAll(Specification spec);
Page findAll(Specification spec、Pageable pageable);
List findAll (仕様仕様、並べ替え並べ替え);
long count(仕様仕様);
}

UserInfoDao


public interface UserInfoDao
extends PagingAndSortingRepository、JpaSpecificationExecutor {}

仕様


public static Specification getSpec(final String name、final int age、final int high){
新しい仕様を返す(){
@Override
public Predicate toPredicate(Root root、CriteriaQuery&lt;?&gt; query、CriteriaBuilder cb){
述語p1= null;
if(name!= null ){
述語p2= cb.equal(root.get(UserInfo_.name)、name);
if(p1!= null){
p1 = cb.and(p1、p2 );
} else {
p1 = p2;
}
}

if(age!= 0){
述語p2= cb.equal(root.get(UserInfo_.age)、age);
if(p1!= null){
p1 = cb.and(p1、p2);
} else {
p1 = p2;
}
}

if(high!= 0){
述語p2= cb.equal(root.get(UserInfo_ .high)、high);
if(p1!= null){
p1 = cb.and(p1、p2);
} else {
p1 = p2; < br />}
}

return p1;
}
};
}



プロジェクトコード:springdatajpademo_*。rar


以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。