序文
Spring Data JPAを使用した学生は、複雑なSQLクエリを処理することがまだ非常に複雑であることを非常に明確にしており、この記事のQueryDSLはJPA操作を簡素化するために使用されます。
QueryDSLは、永続的なドメインモデルデータをクエリするために一般的に使用される静的タイプ構文を定義します。 JDOとJPAは、QueryDSLの主要な統合テクノロジーです。この記事は、JPAと組み合わせてQueryDSLを使用する方法を説明することを目的としています。 JPAのQueryDSLは、JPQLおよび基準クエリに代わるものです。 QueryDSLは、Java APIを介してタイプセーフSQLクエリの構築に焦点を当てた一般的なクエリフレームワークにすぎません。
QueryDSLを使用するには、2つの前提条件操作が必要です。
1. POMファイルに依存関係を追加します
<! - Query DSL-> <Dependency> <GroupId> com.QueryDSL </groupId> <artifactid> querydsl-jpa </artifactid> </dependency> <dependency> <groupid> com.querydsl </groupid> <artifactid> querydsl-apt </supentid </scope> </scope> </scope>
2.コンパイルプラグインをPOMファイルに追加します
<プラグイン> <groupId> com.mysema.maven </groupid> <artifactid> apt-maven-plugin </artifactid> <バージョン> 1.1.3 </version> <executions> <実行> <ゴール>プロセス</goal> </goal> <outputing/<outputddirectory/Java </java <processor> com.querydsl.apt.jpa.jpaannotationProcessor </processor> </configuration> </execution> </executions> </plugin>
プラグインは、javax.persistence.entityで注釈が付けられたドメインタイプを探し、それらに対応するクエリタイプを生成します。以下は、説明するユーザーエンティティクラスであり、生成されたクエリタイプは次のとおりです。
パッケージcom.chhliu.springboot.jpa.entity; static com.querydsl.core.types.pathmetadatafactory。*; com.querydsl.core.types.dsl。*; com.querydsl.core.types.pathmetadataをインポートします。 javax.annotation.generatedをインポートします。 com.querydsl.core.types.pathをインポートします。 / ** * Quserはユーザーのquerydslクエリタイプです */ @generated( "com.querydsl.codegen.entityserializer")パブリッククラスquserはentitypathbase <user> {private static final long serialversionuid = 1153899872l; public static final quser user = new Quser( "user"); public final stringpathアドレス= createString( "address");パブリックファイナルナンバーパス<integer> age = createNumber( "age"、integer.class); public final numberpath <integer> id = createNumber( "id"、integer.class); public final stringpath name = createString( "name"); public quser(string variable){super(user.class、forvariable(variable)); } public quser(path <?extends user> path){super(path.getType()、path.getmetadata()); } public quser(pathmetadata metadata){super(user.class、metadata); }} Entityクラスを作成した後、MVN Clean Compliコマンドを実行すると、
<OutputDirectory>ターゲット/generated-sources/java </outputDirectory>
ディレクトリに対応するクエリタイプを生成します。次に、生成されたすべてのクラスをプロジェクトにコピーして、実行してください。
この記事に関係するエンティティは次のとおりです。
パッケージcom.chhliu.springboot.jpa.entity; java.io.serializableをインポートします。 javax.persistence.entityをインポートします。 javax.persistence.generatedValueをインポートします。 javax.persistence.generationTypeをインポートします。 javax.persistence.idをインポートします。 javax.persistence.tableをインポートします。 @Entity @Table(name = "T_User")パブリッククラスユーザーはSerializable { / ** * * / private static final long serialversionuid = 1l; @id()@generatedValue(Strategy = GenerationType.auto)private int id;プライベート文字列名;プライベート文字列アドレス。プライベートインクエイジ; …………省略ゲッター、セッターメソッド……………/ ** *注意: *詳細:テスト結果を表示するのに便利 * @author chhhliu */ @override public string toString(){return "user [id =" + id + "、name =" + name + "、address =" + address + "、age =" + "]"; }}上記のエンティティクラスは、主にシングルテーブル操作に使用されます。
パッケージcom.chhliu.springboot.jpa.entity; javax.persistence.cascadetypeをインポートします。 javax.persistence.entityをインポートします。 javax.persistence.generatedValueをインポートします。 javax.persistence.idをインポートします。 javax.persistence.onetooneをインポートします。 javax.persistence.tableをインポートします。 / ** *説明:dodo * @author chhliu */ @entity @table(name = "person")public class person {@id @generatedValue private integer id;プライベート文字列名;プライベート文字列アドレス。 @OnetOone(mappedby = "person"、cascade = {cascadetype.persist、cascadetype.remove、cascadetype.merge})private idcard idcard; …………省略ゲッター、セッターメソッド…………@Override public String toString(){return "person [id =" + id + "、name =" + name + "、address =" + address + "、idcard =" + idcard + "]"; }}パッケージcom.chhliu.springboot.jpa.entity; javax.persistence.cascadetypeをインポートします。 javax.persistence.entityをインポートします。 javax.persistence.fetchtypeをインポートします。 javax.persistence.generatedValueをインポートします。 javax.persistence.idをインポートします。 javax.persistence.onetooneをインポートします。 javax.persistence.tableをインポートします。 / ** *説明: * @author chhliu */ @entity @table(name = "idcard")public class idcard {@id @generatedvalue private integer id;プライベート文字列idno; @OnetOone(cascade = {cascadetype.merge、cascadetype.remove、cascadetype.persist}、fetch = fetchtype.eager)privateers person; …………省略ゲッター、セッターメソッド…………@Override public String toString(){return "idcard [id =" + id + "、idno =" + idno + "、person =" + person + "]"; }}上記の2つのエンティティは、主に1対1の関係の操作などで使用されます
パッケージcom.chhliu.springboot.jpa.entity; java.util.listをインポートします。 javax.persistence.cascadetypeをインポートします。 javax.persistence.columnをインポートします。 javax.persistence.entityをインポートします。 javax.persistence.fetchtypeをインポートします。 javax.persistence.generatedValueをインポートします。 javax.persistence.idをインポートします。 javax.persistence.onetomanyをインポートします。 javax.persistence.tableをインポートします。 / ***説明:Order Entity class* @author chhliu*/ @entity @table(name = "order_c")public class order {@id @generatedvalue @column(name = "id")private integer id; @column(length = 20、name = "order_name")private string ordername; @column(name = "count")private integer count; @onetomany(mappedby = "order"、cascade = {cascadetype.persist、cascadetype.remove}、fetch = fetchtype.eager)private list <OrderItem> OrderItems; ………Getter、Setter Methodを省略してください……}パッケージcom.chhliu.springboot.jpa.entity; javax.persistence.cascadetypeをインポートします。 javax.persistence.columnをインポートします。 javax.persistence.entityをインポートします。 javax.persistence.fetchtypeをインポートします。 javax.persistence.generatedValueをインポートします。 javax.persistence.idをインポートします。 javax.persistence.joincolumnをインポートします。 javax.persistence.manytooneをインポートします。 javax.persistence.tableをインポートします。 / ***説明:OrderItem Entity class* @author chhliu*/ @entity @table(name = "order_item")public class orderitem {@id @generatedvalue @column(name = "id"、nullable = false = false)private integer id; @column(name = "item_name"、length = 20)private string itemname; @column(name = "price")プライベート整数価格; @manytoone(cascade = {cascadetype.persist、cascadetype.remove、cascadetype.merge}、fetch = fetchtype.eager)@joincolumn(name = "order_id")private Order Order; …………getter、setter method………}上記の2つのエンティティは、1対多くの関係の操作の例を示すために使用されます。
まず、単一のテーブル操作を見てみましょう
1.スプリングデータJPAを使用します
Spring Data JPAによって提供されるQueryDSL関数を使用するには、非常に簡単で、インターフェイスを直接継承するだけです。 Spring Data JPAは、次のように、QueryDSLPredicateExecutorインターフェイスを提供します。
パッケージcom.chhliu.springboot.jpa.repository; Import org.springframework.data.jpa.repository.jparePository; Import org.springframework.data.querydsl.querydslpredicateexecutor; com.chhliu.springboot.jpa.entity.userをインポートします。パブリックインターフェイスuserrepositorydls拡張jparepository <user、integer>、querydslpredicateexecutor <user> {//継承インターフェイス}QueryDSLPREDICEALEXECUTORインターフェイスは、次の方法を提供します。
パブリックインターフェイスquerydslpredicateexecutor <t> {t findone(predicate predict); iterable <t> findall(述語予測、ソートソート); iterable <t> findall(Predicate Predict、Orderspecifier <?> ... Orders); iterable <t> findall(orderspecifier <?> ...注文);ページ<t> findall(述語予測、ページ可能なページ可能);長いカウント(述語予測); Booleanが存在する(述語述語); }上記の方法の使用は、Spring Data JPAの他のインターフェイス使用方法に似ています。詳細については、http://www.vevb.com/article/137757.htmを参照してください
テストは次のとおりです。
public user finduserbyusername(final string username){ / ** *この例は、Spring Data QueryDSLを使用して * / QUSER QUSER = QUSER.USER; Predicate Predicate = quser.name.eq(username); //ユーザー名に従って、ユーザーテーブルをquery return Repository.findone(predicate); }対応するSQLは次のとおりです。
コードのコピーは次のとおりです。ID1_5_としてuser0_.idを選択し、user0.address asdress2_5_、user0.age as age3_5_、user0.nameとしてt_user user0_ from user0_.name =?
単一のテーブル操作の例コードは次のとおりです。
パッケージcom.chhliu.springboot.jpa.repository; java.util.listをインポートします。 javax.persistence.entitymanagerをインポートします。 javax.persistence.persistenceContextをインポートします。 javax.persistence.queryをインポートします。 javax.transaction.transactionalをインポートします。 Import org.springframework.beans.factory.annotation.autowired; org.springframework.data.domain.pagerequestをインポートします。 Import org.springframework.data.domain.sort; org.springframework.steretype.componentをインポートします。 com.chhliu.springboot.jpa.entity.quserをインポートします。 com.chhliu.springboot.jpa.entity.userをインポートします。 com.querydsl.core.types.predicateをインポートします。 com.querydsl.jpa.impl.jpaqueryFactoryをインポートします。 / ** *説明:querydsl jpa * @author chhliu */ @component @transactional public class userrepositorymanagerdsl {@autowired private userrepositorydlsリポジトリ; @autowired @persistencecontext private entitymanager entitymanager; Private JPaqueryFactory QueryFactory; @PostConstruct public void init(){queryFactory = new JPaqueryFactory(EntityManager); } public user finduserbyusername(final string username){ / ** *この例は、Spring Data QueryDSLを使用して実装することです * / QUSER QUSER = QUSER.USER; Predicate Predict = quser.name.eq(username); return repository.findone(predicate); } / ***注意:*詳細:ユーザーテーブルのすべてのレコードをクエリ* / public List <user> findall(){quser quser = quser.user; return queryfactory.selectfrom(quser).fetch(); } / ***詳細:単一コンディションクエリ* / publicユーザーfindOneByUsername(final String username){quser quser = quser.user; return queryfactory.selectfrom(quser).where(quser.name.eq(username)).fetchone(); } / ***詳細:シングルテーブルマルチコンディションクエリ* /パブリックユーザーfindOneOneByUserNAMENDADDRESS(最終文字列ユーザー名、最終文字列アドレス){QUSER QUSER = QUSER.USER; queryfactory.select(quser)..from(quser)//上記の2つの文はselectromに相当します。 } / ***詳細:Joing Query* / public List <user> findusersbyjoin(){quser quser = quser.user; quser username = new Quser( "name"); return queryfactory.selectfrom(quser).innerjoin(quser)。 } / ** *詳細:クエリ結果をソート * / public List <user> finduserandordory(){quser quser = quser.user; return queryfactory.selectfrom(quser).orderby(quser.id.desc()).fetch(); } / ** *詳細: * / public list <string> finduserbygroup(){quser quser = quser.user; return queryfactory.select(quser.name).from(quser).groupby(quser.name).fetch(); } / ***詳細:ユーザーを削除* / public long deleteuser(string username){quser quser = quser.user; return queryfactory.delete(quser).where(quser.name.eq(username))。execute(); } / ***詳細:レコードを更新* / public long updateUser(最終ユーザーu、最終文字列ユーザー名){quser quser = quser.user; return queryfactory.update(quser).where(quser.name.eq(username)))))))。 } / ** *詳細:ネイティブクエリを使用 * / publicユーザーfinduenueuserbyoriginalsql(final string username){quser quser = quser.user;クエリquery = queryfactory.selectfrom(quser).where(quser.name.eq(username))。createQuery(); return(user)query.getsingleresult(); } / ***詳細:ページネーションクエリシングルテーブル* / public Page <user> findallandpager(final int offset、final int pagesize){predicate predicate = quser.user.id.lt(10);ソートsort = new sort(new sort.order(sort.direction.desc、 "id")); pagerequest pr = new Pagerequest(offset、Pagesize、sort); Return Repository.findall(Predicate、PR); }}マルチテーブル操作の例(1対1)は次のとおりです。
パッケージcom.chhliu.springboot.jpa.repository; java.util.arraylistをインポートします。 java.util.listをインポートします。 javax.annotation.postconstructをインポートします。 javax.persistence.entitymanagerをインポートします。 javax.persistence.persistenceContextをインポートします。 Import org.springframework.beans.factory.annotation.autowired; org.springframework.stereotype.componentをインポートします。 com.chhliu.springboot.jpa.dto.personidcarddtoをインポートします。 com.chhliu.springboot.jpa.entity.qidcardをインポートします。 com.chhliu.springboot.jpa.entity.qidcardをインポートします。 com.chhliu.springboot.jpa.entity.qpersonをインポートします。 com.querydsl.core.queryResultsをインポートします。 com.querydsl.core.tupleをインポートします。 com.querydsl.core.types.predicateをインポートします。 com.querydsl.jpa.impl.jpaqueryをインポートします。 com.querydsl.jpa.impl.jpaqueryFactoryをインポートします。 @component public class personandidcardmanager {@autowired @persistencontext private entitymanager entitymanager; Private JPaqueryFactory QueryFactory; @PostConstruct public void init(){queryFactory = new JPaqueryFactory(EntityManager); } / ***詳細:マルチテーブルダイナミッククエリ* / public List <tuple> findallpersonandidcard(){predicate predicate =(qperson.id.intvalue())。 jpaquery <tuple> jpaquery = queryfactory.select(qidcard.idcard.idno、qperson.person.address、qperson.person.name).from(qidcard.idcard、qperson.person).where(predice); jpaquery.fetch()を返します。 } / ***詳細:出力クエリの結果dto* / public list <personidcardtto> findbydto(){predicate predict =(qperson.person.id.intvalue())。 jpaquery <tuple> jpaquery = queryfactory.select(qidcard.idcard.idno、qperson.person.address、qperson.person.name).from(qidcard.idcard、qperson.person).where(predice);リスト<Tuple> Tupple = jpaquery.fetch(); List <PersonIdCarddto> dtos = new ArrayList <PersonIdCarddto>(); if(null!= tuples &&!tuples.isempty()){for(tuple tuple:tuples){string address = tuple.get(qperson.person.address);文字列名= tuple.get(qperson.person.name); string idcard = tuple.get(qidcard.idcard.idno); personidcarddto dto = new personidcarddto(); dto.setAddress(アドレス); dto.setidno(idcard); dto.setname(name); dtos.add(dto); }} dtosを返します。 } / ***詳細:マルチテーブルダイナミッククエリとページネーション* / public QueryResults <Tuple> findBydtoAndpager(int offset、int pagesize){predicate predicate =(qperson.person.id.intvalue())。 return queryfactory.select(qidcard.idcard.idno、qperson.person.address、qperson.person.name).from(qidcard.idcard、qperson.person).where(predicate).offset(offset).limit(pagesize).fetchResults(); }}クエリの結果がDTOモードで出力される上記の例では、クエリが終了した後、クエリの結果はDTOオブジェクトに手動で変換されます。この方法は実際にはあまりエレガントではありません。 QueryDSLは、より良い方法を提供します。次の例を参照してください。
/ ***詳細:方法1:Bean Projection*/ public List <PersonidCardtto> findBydtouseBean(){Predicate Predicate =(qperson.int.intvalue())。eq(qidcard.idcard.person.id.intvalue()); return queryfactory.select(projections.bean(personidcarddto.class、qidcard.idcard.idno、qperson.address、qperson.person.name))。 } / ** *詳細:方法2:setterの代わりにフィールドを使用 * / publicリスト<personidcarddto> findbydtousefields(){predicate predict =(qperson.id.intvalue())。 return queryfactory.select(projections.fields(personidcarddto.class、qidcard.idcard.idno、qperson.address、qperson.person.name))。 } / ***詳細:方法3:コンストラクターメソッドを使用して、コンストラクターの属性の順序はコンストラクターの順序と一致する必要があることに注意してください。 return queryfactory.select(projections.constructor(personidcarddto.class、qperson.name.name、qperson.address、qidcard.idcard.idno))。 }上記はいくつかのアイデアのみを提供します。もちろん、@QueryProjectionを使用して実装することもできます。これは非常に柔軟です。
1対多くの例:
パッケージcom.chhliu.springboot.jpa.repository; java.util.listをインポートします。 javax.annotation.postconstructをインポートします。 javax.persistence.entitymanagerをインポートします。 javax.persistence.persistenceContextをインポートします。 Import org.springframework.beans.factory.annotation.autowired; org.springframework.stereotype.componentをインポートします。 com.chhliu.springboot.jpa.entity.qorderをインポートします。 com.chhliu.springboot.jpa.entity.qorderitemをインポートします。 com.querydsl.core.tupleをインポートします。 com.querydsl.core.types.predicateをインポートします。 com.querydsl.jpa.impl.jpaqueryをインポートします。 com.querydsl.jpa.impl.jpaqueryFactoryをインポートします。 @Component Public Class OrderAndorderItemManager {@autowired @persistencontext private entitymanager entitymanager; Private JPaqueryFactory QueryFactory; @PostConstruct public void init(){queryFactory = new JPaqueryFactory(EntityManager); } /***詳細:1対Many、条件付きクエリ* /public List <tuple> indordordordordorderitembyordername(string ordername){// query条件Predicate = qorder.order.ordername.eq(ordername); jPaquery <Tuple> jPaquery = queryFactory.Select(QORDER.ORDER、QORDERITEM.ORDERITEM).FROM(QORDER.ORDER、QORDERITEM.ORDERITEM).WHERE(QORDERITEM.ORDERITEM.ORDER.ID.INTVALUE()。EQ(QORDER.ORDER.ID.INTVALUE()、予測); //結果を取得jpaquery.fetch(); } /***詳細:マルチテーブル結合クエリ* /public List <Tuple> findallByOrderName(String OrderName){//クエリ条件PRESTICE = QORDER.ORDER.ORDERNAME.EQ(ORDERNAME); jpaquery <Tuple> jPaquery = queryFactory.Select(QORDER.ORDER、QORDERITEM.ORDERITEM)。 jpaquery.where(predicate); //結果を取得jpaquery.fetch(); }}上記の例から、QueryDSLが私たちの運用を大幅に簡素化したことがわかります
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。