Spring Data JPAをしばらく使用しています。この期間中、私はいくつかのことを学び、いくつかの問題に遭遇しました。ここでそれらを共有します。
序文:
スプリングデータの紹介:
Spring Dataは、データベースアクセスを簡素化し、クラウドサービスをサポートするためのオープンソースフレームワークです。その主な目標は、データへのアクセスを便利かつ高速にアクセスし、Map-Reduceフレームワークとクラウドコンピューティングデータサービスをサポートすることです。スプリングデータには複数のサブプロジェクトが含まれています。
Commons-各サブプロジェクトで使用するのに適した共有基本フレームワークを提供し、横断節の持続性をサポートします
JPA-ストレージ全体でJPAデータアクセス層と永続性層を作成する機能を簡素化します
Hadoop -SpringのHadoopジョブ構成とPOJOプログラミングモデルに基づいてジョブをMapReduce
Key -Value- RedisとRiakを統合して、複数の共通シナリオで簡単なパッケージを提供する
ドキュメント - ドキュメントデータベースの統合:couchdbとmongodbと基本的な構成マッピングとライブラリサポートを提供する
グラフ - 強力なPOJOベースのプログラミングモデルを提供する統合NEO4J
グラフRooアドオン-Neo4jのROOサポート
JDBC拡張機能 - Oracle Rad、高度なキュー、および高度なデータ型をサポートします
マッピング-Grailsに基づいてオブジェクトマッピングフレームワークを提供し、さまざまなデータベースをサポートする
例 - サンプルプログラム、ドキュメント、グラフデータベース
ガイダンス - 高度なドキュメント
1。スプリングデータJPAの紹介
Spring Data JPAは、ORMフレームワークとJPA仕様に基づいてSpringでカプセル化されたJPAアプリケーションフレームワークであり、完全な一連のデータアクセスレイヤーソリューションを提供します。
2。スプリングデータJPA関数
Spring Data JPAには非常に強力な機能があります。ここでは、環境構築ステップをスキップし、Spring Data JPAの「甘さ」を見てみましょう。
スプリングデータJPAは、ユーザーに次のインターフェイスを提供します。
3。スプリングデータJPAインターフェイス
1。CrudrePositoryインターフェイス
エンティティクラスを作成します。
@entity @table(name = "user")public class user {@id @generatedValue private integer id; //アカウントプライベート文字列アカウント。 //名前プライベート文字列名; //パスワードプライベート文字列パスワード。 //プライベート文字列の電子メール。 }インターフェイスを書き、crudrepositoryインターフェイスを継承します。
パブリックインターフェイスuserrepositoryはcrudrepository <user、integer> {}を拡張しますテストクラスを作成します(エフェクトをより直感的に確認するには、すべてのテストクラスはアサーションを使用しません。また、直接使用される印刷ステートメントを使用します):
Public Class UserrePositoryTest {@autowired private userrepository dao; @test // public void testsave()を保存{user user = new user(); user.setname( "chhliu"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); dao.save(user); } @test // public void testsave1(){list <user> users = new arraylist <user>();を保存します。 user user = new user(); user.setname( "tanjie"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); users.add(user); user = new user(); user.setname( "esdong"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); users.add(user); user = new user(); user.setName( "Qinhongfei"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); users.add(user); user = new user(); user.setName( "Huizhang"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); users.add(user); user = new user(); user.setname( "caican"); user.setAccount( "10000"); user.setemail( "[email protected]"); user.setPassWord( "123456"); users.add(user); dao.save(users); } @test // public void testupdate(){user user = dao.findone(1); user.setPassWord( "123890"); //この方法で更新関数を実装するには、@Transaction Thing Annotationをサービスレイヤーに追加する必要があります} @test // public void testdelete(){dao.delete(2); } @test // queryすべてのpublic void testfindall(){list <user> users =(list <user>)dao.findall(); system.out.println(json.tojsonstring(users)); } @test //指定されたIDオブジェクトがpublic void tesisexist(){boolean isexist = dao.exists(8); System.out.println(isexist); } @test // query public void testfinduserbyids(){list <integer> listids = new arrayList <Integer>(); listids.add(2); listids.add(4); listids.add(7);リスト<ユーザー>ユーザー=(リスト<ユーザー>)dao.findall(listids); system.out.println(json.tojsonstring(users)); }}ご覧のとおり、この時点で、私は1つのインターフェイスクラスのみを作成し、このインターフェイスクラスを実装しなかったため、基本的なCRUD操作を完了することができました。このインターフェイスは、ビジネスレイヤーを直接使用するために、ドメインオブジェクトを追加、削除、変更、および検索するメソッドを自動的に作成するためです。
インターフェイスは次のように定義されており、合計11の方法が提供されます。これは、基本的に単純なCRUD操作とバッチ操作を満たすことができます。
@norepositorbeanパブリックインターフェイスcrudrepository <t、id extends serializable> extends repository <t、<s extends t> s save(s entity); iterable <t> findall(); //すべてのオブジェクトを照会可能<t> findall(iterable <id> ids); // id list long count()に基づいてすべてのオブジェクトをクエリします。 void deleteall(); //すべてを削除}
2。PagingandSortingRepositoryインターフェイス
PagingandSortingRepositoryインターフェイスは、CrudrePositoryインターフェイスを継承します。
インターフェイスを作成し、PagingandSortingRepositoryインターフェイスを継承します
パブリックインターフェイスuserrepositorywithordords extends pagingandsortingrepository <user、integer> {}テストクラスを書く:
@runwith(springjunit4classrunner.class)@contextconfiguration(locations = {classpath:applicationContext-config.xml "})@transactionconfiguration(false)@transactional public class userrepositorywithordertest {@autowired userrepositorywithord da @test public void testOrder(){sort sort = new sort(direction.desc、 "id"); Pageable Pageable = new Pagerequest(0、5、sort);ページ<ユーザー>ページ= dao.findall(pageable); system.out.println(json.tojsonstring(page)); System.out.println(page.getSize()); }}このインターフェイスを継承する限り、Spring Data JPAはすでにページネーションとソートの機能を提供します。インターフェイスは次のように定義されており、2つの方法が使用されます。ここで、tは操作するエンティティクラス、IDはエンティティクラスプライマリキーのタイプです
@norepositorybean public interface pagingandsortingRepository <t、id extends serializable> extends crudrepository <t、id> {iterable <t> findall(ソートソート); //ページングなしでソート3。JParePositoryインターフェイス
ビジネスがCRUD操作を提供し、ページングおよびソート機能を提供する必要がある場合は、このインターフェイスを直接継承することができます。このインターフェイスは、PagingandSortingRepositoryインターフェイスを継承します。
インターフェイスは次のように定義されています。
パブリックインターフェイスjParePository <t、id extends serializable> extends pagingandsortingRepository <t、id> {list <t> findall(); //すべてのオブジェクトをクエリ<t> findall(並べ替え); //すべてのオブジェクトをクエリしないでください。データベースT SaveandFlush(T Entity); // void deleteinbatch(iterable <t> entities); // batch delete void deleteallinbatch(); // delete all}を保存して強制同期すると同期します。 4。JPaspEcificationExecutorインターフェイス
このインターフェイスは、JPA基準クエリのサポートを提供します。このインターフェイスは非常に特別で、リポジトリシステムに属していないことに注意してください。 Spring Data JPAは自動的にスキャンして認識されないため、対応するBeanは見つかりません。リポジトリを継承するサブインターフェイスを継承するか、リポジトリインターフェイスを直接継承するだけです。 Spring Data JPAは、統一された管理を自動的にスキャンおよび認識し、実行します。
インターフェイスは次のように記述されています。
パブリックインターフェイス仕様ExecutorrePositoryは、crudrepository <user、integer>、jpaspecificationexecutor <user> {}を拡張しますサービスクラス:
@Service Public Class SpecizationEXECUTORREPOSITORYMANAGER {@AUTOWIRED PRIVATE SPICIANTEXECUTORREPOSITORY DAO; / ***説明:名前に基づいてユーザーをクエリ*/ publicユーザーfinduserbyname(最終文字列名){return dao.findone(new specification <user>(){@override public redicate topredicate(root <user> root、criteriaquery <? }); } / ***説明:名前と電子メールに基づいてユーザーをクエリします* / publicユーザーfinduserbynameandemail(final string name、final string email){return dao.findone(new specification <user>(){@override public redicate topredicate(root <user>、root、root、root、criteriaquery <? Predice1 = cb.equal( "name")、cb.equal( "email); } / ***説明:組み合わせクエリ* /パブリックユーザーfinduserbyuser(最終ユーザーUservo){return dao.findone(new specification <user>(){@override public redicate topredicate(root <user> root、criteriaquery <? cb.and(cb.equal( "email")、uservo.getword()); } / ***説明:[2,10]のユーザーIDでユーザーをクエリするなど、メソッドの範囲クエリ* / publicリスト<ユーザー> induserbyids(最終リスト<integer> ids){return dao.findall(new specification <user>(){@override public predicate topredicate(root <user> root、returtiaquery < root.in(ids); } / ***説明:9を超えるユーザーIDを持つすべてのユーザーをクエリするなどの範囲クエリGTメソッドcb.gt(root.get( "id")。 } / ***説明:ユーザーIDを持つユーザーのクエリ10未満のユーザーのクエリなど、範囲クエリLTメソッド* / public List <user> induserbyltid(final int id){return dao.findall(new specification <user>(){@override public predicate topredicate(root <user> root、criteriaquery、criteriabuilder cb) cb.lt(root.get( "id")。 } / ***説明:3〜10のIDを持つユーザーのクエリなどのメソッド間の範囲クエリ* / public list <user> induserbetweenid(final int start、final int end){return dao.findall(new specification <user>(){@Override public predicate topredicate(root <user> root、Criteriaquery <? cb.between(root.get( "id")。 } / ***説明:ソートおよびページネーション操作* / publicページ<ユーザー> finduserandordory(final int id){sort sort = new sort(direction.desc、 "id"); return dao.findall(new specification <user>(){@override public predicate topredicate(root <user> root、criteriaquery <?> query、criteriabuilder cb){return cb.gt(root.get( "id")。 } / ***説明:操作操作の並べ替えcb.gt( "id")。as(integer.class)、cb.desc( "id")。 }}テストクラス:
@runwith(springjunit4classrunner.class)@contextconfiguration(locations = {classpath:applicationContext-config.xml "})@transactionconfiguration(false)@transactional public class specificationexecutorrepositorytestestester @test public void testfinduserbyname(){user user = manager.finduserbyname( "chhliu"); system.out.println(json.tojsonstring(user)); } @test public void testfinduserbynameandemail(){user user = manager.finduserbynameandemail( "chhliu"、 "chhliu @.com"); system.out.println(json.tojsonstring(user)); } @test public void testfinduserbyuservo(){user user = new user(); user.setname( "chhliu"); user.setemail( "[email protected]");ユーザーu = manager.finduserbyuser(user); system.out.println(json.tojsonstring(u)); } @test public void testfinduserbyids(){list <user> users = manager.finduserbyids(new arraylist <integer>(arrays.aslist(1,3,5,6))); system.out.println(json.tojsonstring(users)); } @test public void testfinduserbygtid(){list <user> users = manager.finduserbygtid(5); system.out.println(json.tojsonstring(users)); } @test public void testfinduserbyltid(){list <user> users = manager.finduserbyltid(5); system.out.println(json.tojsonstring(users)); } @test public void testfinduserbetweenid(){list <user> users = manager.finduserbetweenid(4、9); system.out.println(json.tojsonstring(users)); } @test public void testfinduserandordor(){page <user> users = manager.finduserandordory(1); system.out.println(json.tojsonstring(users)); } @test public void testfinduserandordersecondmethod(){list <user> users = manager.finduserandordersecondmethod(1); system.out.println(json.tojsonstring(users)); }} 5。リポジトリインターフェイス
このインターフェイスは最も基本的なインターフェイスであり、単なる象徴的なインターフェイスであり、メソッドは定義されていないため、このインターフェイスの使用は何ですか? Spring Data JPAはこのインターフェイスを提供するため、もちろん便利です。たとえば、外部から提供したくないいくつかの方法。たとえば、削除方法ではなく、追加および変更方法のみを提供する必要があります。以前のインターフェイスはそれを行うことはできません。この時点で、このインターフェイスを継承し、CrudrePositoryインターフェイスの対応するメソッドをリポジトリインターフェイスにコピーできます。
概要:開発者は、上記の5つのインターフェイスをどのように選択する必要がありますか?実際、基礎は非常に簡単です。特定のビジネスニーズに応じて、そのいずれかを選択してください。各インターフェイス間に強度と強度の問題がないためです。
4。スプリングデータJPAクエリ
1. @Queryを使用してクエリを作成します
@Queryアノテーションの使用は非常に簡単です。宣言された方法で注釈にラベルを付け、JP QLクエリステートメントを提供するだけです。多くの開発者は、JP QLを作成する際に位置番号の代わりに名前付きパラメーターを使用することを好み、 @Queryもこれをサポートしています。 JP QLステートメントでは、パラメーターは「:variable」の形式を使用して指定され、同時に @paramは、JP QLの指定されたパラメーターに対応するためにメソッドパラメーターの前で使用されます。さらに、開発者は@Queryを使用して更新操作を実行することもできます。これを行うには、 @modifiingを使用して@queryを使用しながら操作を変更したクエリとして識別する必要があります。これにより、フレームワークは最終的にクエリ操作ではなく更新された操作を生成します。
次のようにインターフェイスを書きます。
/***説明:カスタムクエリ。 Spring Data JPAが提供できない場合、カスタムインターフェイスが必要です。このメソッドはこの時点で使用できます*/ public interface userdefineByselfはjparePository <user、integer> {/ ***名前付きパラメーター*説明*説明:このメソッドを使用することをお勧めします*/ @query( "us u.name =:name")user finduserbyname( "name name"); /***インデックスパラメーター*説明:使用しますか? PlaceHolder*/ @Query( "ユーザーuからu.email =?1")// 1を示します。 /***説明:更新は@Modifyingおよび @Queryを介して達成できます*注:クエリの変更の返品値はvoidまたはint/integer*/@modifying @query( "Update user u set u.name =:name where u.id =:id:id")int updetwususerbyid(@param( "name")string name、@param(id ")"); }注:@Modificing Annotationには、ClearAutomativeで構成があります
根本的な永続性のコンテキストをクリアできると述べています。これはEntityManagerクラスです。 JPAの基礎となる実装には、セカンダリキャッシュがあります。つまり、データベースを更新した後、このオブジェクトを後で使用すると、オブジェクトを確認します。このオブジェクトは最初のレベルでキャッシュされますが、データベースと同期されていません。現時点では、Clearautomatical = Trueを使用して、冬眠の最初のレベルのキャッシュを更新します。それ以外の場合、同じインターフェイス内のオブジェクトを更新してからこのオブジェクトを照会します。その後、見つけたオブジェクトは、以前に更新されなかった以前の状態です。
テストクラス:
@runwith(springjunit4classrunner.class)@contextconfiguration(locations = {classpath:applicationContext-config.xml "})@transactionconfiguration(false)@transactional public class userdefinebyselftest {@autowired private userdefinebyself @test public void testfinduserbyname(){user user = dao.finduserbyname( "chhliu"); assert.assertequals( "chhliu"、user.getname()); System.out.println(user.getName()); } @test public void testfinduserbyemail(){user user = dao.finduserbyemail( "chhliu @.com"); assert.assertequals( "chhliu"、user.getname()); System.out.println(user.getName()); } @test public void testupdateuserbyid(){dao.updateuserbyid( "tanjie"、4); }}テストコードから、実装クラスなしでインターフェイスのみを定義するだけでなく、必要な関数を実装することがわかります。
2。@namedqueriesを使用してクエリを作成します
名前付きクエリは、複数のメソッドを共有するためにクエリステートメントをメソッド本体から分離するJPAによって提供される関数です。 Spring Data JPAは、名前付きクエリの優れたサポートも提供します。ユーザーは、JPA仕様に従ってORM.XMLファイルまたはコードでクエリステートメントを定義する必要があります。彼らがする必要がある唯一のことは、ステートメントを命名するときに「domainclass.methodname()」の命名ルールを満たすことです。
インターフェイスを書く:
public interface finduserbynamedqueryRepositoryはjparePository <user、integer> {user induserwithname(@param( "name")string name); }クラスを書く:
@entity @namedquery(value = {@namedquery(name = "user.finduserwithname"、query = "select u user u where u.name =:name")//注:ここに複数のメソッドがある場合は、@namedqueryを使用する必要があります。メソッドが1つしかない場合は、@namedqueryを使用できます。執筆方法は次のとおりです。@namedquery(name = "user.finduserwithname"、query = "user u where u.name =:name")public class finduserbynamedquery { / ***注:このエンティティクラスはここで定義する必要があります。 }注:記事で赤でマークされた部品は、1つずつ対応する必要があります。そうしないと、JPA仕様を満たしません。
テストクラス:
@runwith(springjunit4classrunner.class)@contextconfiguration(locations = {classpath:applicationContext-config.xml "})@transactionconfiguration(false)@transactional public class finduserbynamedqueryRepositortytor @test public void testfinduserbyname(){user user = dao.finduserwithname( "caican"); system.out.println(json.tojsonstring(user)); }} 3.メソッド名を分析してクエリを作成します
名前が示すように、メソッドの名前に基づいてクエリを作成することです。最初は信じられないように聞こえるかもしれませんが、テストの後、私はすべてが可能であることがわかりました。
インターフェイスを書く:
Public Interface SimpleConditionQueryRepositoryはjparePository <user、integer> { /***説明:Springデータで定義されたルールに従って、条件クエリに関しては条件のキーワードで接続されている条件付きクエリに関しては、Queryメソッドはinfint | read | get*で始まります。条件付き属性の最初の文字は大文字である必要があります* / / ***注:このインターフェイスはSQLを送信することに相当します:ユーザーuからuse u where use use =:name =:name =:ememail =:email* parameter nameは大文字です。 list*/ user findbynameandemail(string name、string email); / ** *注:ここのこのインターフェイスは、sqlを送信するのと同等です。ユーザーuからuを選択しますu.name =?1またはu.password =?2 */ list <user> findbynameorpassword(string name、string password); / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、SQLの送信に相当します:ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、SQLの送信と同等です:ユーザーuからUを選択します。 / ** *注:ここでのこのインターフェイスは、sqlの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、sqlの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、sqlの送信と同等です。ユーザーuからuを選択します。ここでu.password =?1注文 */ list <user> findbypasswordorderbyiddesc(string password); / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択しますu.name <>?1 */ list <user> findbynamenot(string name); / ** *注:ここのこのインターフェイスは、SQLの送信と同等です。ユーザーuからuを選択します。 / ** *注:ここのこのインターフェイスは、sqlの送信と同等です。ユーザーuからuを選択します。 }テストクラス(コメントパーツは実際の送信SQLステートメントです):
@runwith(springjunit4classrunner.class)@contextconfiguration(locations = {classpath:applicationContext-config.xml "})@transactionconfiguration(false)@Transactional public class simpleconditionqueryRepositytest { /*** select user0.idはid0_、user0.accountとしてaccount0_、user0.email as email0_、user0.name as name0_、user0.passidword as password0_ from user0_ where user0_.name =?およびuser0_.email =?制限? */ @test public void testfinduserbynameandemail(){user user = dao.findbynameandemail( "chhliu"、 "chhliu @.com"); system.out.println(json.tojsonstring(user)); } /*** select user0.idはid1_、user0_.accountとしてaccount1_、user0_.emailとしてemail1_、user0_.name as name1_、user0_.password as password1_ from user0_ where user0_.name =?またはuser0_.password =? */ @test public void testfinduserbynameorpassword(){list <user> users = dao.findbynameorpassword( "chhliu"、 "123456"); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid1_、user0_.accountとしてaccount1_、user0_.emailとしてemail1_、user0_.name as name1_、user0_.password as password1_ from user0_ from user0_.id byther?そして ? */ @test public void testfindbyidbetween(){list <user> users = dao.findbyidbetween(5、8); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid1_、user0_.accountとしてaccount1_、user0_.email as email1_、user0_.name as name1_、user0_.password as password1_ from user0_where user0_.id <? */ @test public void testfindbyidlessthan(){list <user> users = dao.findbyidlessthan(4); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid0_、user0_.accountとしてaccount0_、user0_.email as email0_、user0.name as name0_、user0、as password0_としてuser0_.id>? */ @test public void testfindbyidgreaterthan(){list <user> users = dao.findbyidgreaterthan(6); system.out.println(json.tojsonstring(users)); } / ** * select user0.idはid0_、user0_.accountとしてaccount0_、user0_.emailとしてemail0_、user0.name as name0_、user0.name as password as user0_ as user0_.name is null * / @test public void testfindbynameisnull() system.out.println(json.tojsonstring(users)); } / ** * select user0.idはid1_、user0_.accountとしてaccount1_、user0_.emailとしてemail1、user0_.name as name1_、user0_.name as password1_ as user0_.nameはnull * / @test public void publicnameisnotnull = user dao.findbynameisnotnull(); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid1_、user0_.accountとしてaccount1_、user0_.emailとしてemail1_、user0_.name as name1_、user0_.password as password1_ from user0_where user0_.name like? */ @test public void testfindbynamelike(){list <user> users = dao.findbynamelike( "chhliu"); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid0_、user0_.accountとしてaccount0_、user0_.email as email0_、user0.name as name0_、user0.password as password0_ from user0_ from user0_.name not not not? */ @test public void testfindbynamenotlike(){list <user> users = dao.findbynamenotlike( "chhliu"); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid0_、user0_.accountとしてaccount0_、user0_.emailとしてemail0_、user0.name as name0_、user0.password as password0_ from user0_ where user0_.password =? user0_.id desc */ @test public public void testfindbypasswordordybyiddesc(){list <user> users = dao.findbypasswordordorybyiddesc( "123456"); system.out.println(json.tojsonstring(users)); } /*** select user0.idはid1_、user0_.accountとしてaccount1_、user0_.emailとしてemail1_、user0_.name as name1_、user0_.password as password1_ from user0_ where user0_.name <>? */ @test public void testfindbynamenot(){list <user> users = dao.findbynamenot( "chhliu"); system.out.println(json.tojsonstring(users)); } / ** * select user0.idはid1_、user0_.accountとしてaccount1_、user0_.email as email1_、user0_.name as name1_、user0_.name as password1_ as user0_.id in(?、?、?、?) * / @test public boid void void by <user arrayList <integer>(arrays.aslist(3,4,6,8))); system.out.println(json.tojsonstring(users)); } / ** * select user0.idはid0_、user0_.accountとしてaccount0_、user0_.email as email0_、user0.name as name0_、user0.name as password as user0_ as user0_.id not in(?、?、?) dao.findbyidnotin(new ArrayList <Integer>(arrays.Aslist(3、4、6、8))); system.out.println(json.tojsonstring(users)); }}ここでは、1つのインターフェイスのみを定義します。インターフェイスにはメソッドのみがありますが、実装はありませんが、さまざまな操作が完了しています。
これを見た後、多くの人がおそらく尋ねるでしょう、SpringデータJPAはどのようにそれをしましたか?フレームワークがメソッド名を分析すると、Find、FindBy、Read、Readby、GetByなど、メソッド名の過剰なプレフィックスを最初に傍受し、残りの部分を解析することがわかります。また、メソッドの最後のパラメーターがある種またはページ可能なタイプの場合、関連情報もルールごとにソートまたはページネーションクエリのために抽出されます。クエリを作成するとき、findbyidin()などのメソッド名に属性名を使用して表現します。フレームワークがこの方法を解析すると、最初にFindByを排除し、次に残りの属性を解析します。
クエリする場合、通常、複数の属性に基づいてクエリが同時にクエリする必要があり、クエリ条件も異なる形式(特定の範囲で特定の値よりも大きい)です。 Spring Data JPAは、条件付きクエリを表現するためのいくつかのキーワードを提供します。
および--- findbyusernameandpassword(String user、striang pwd)など、SQLのキーワードに相当します
または--- findbyusernameoraddress(string user、string addr)など、sqlのキーワードに相当するものまたはキーワード
間--- SQLに相当するキーワードの間、findbysalarybetween(int max、int min)など
Lessthan --- FindBysallessthan(int max)など、sqlの "<"に相当します
GreaterThan --- SQLの「>」に相当します。
isnull --- findbyusernameisnull()など、sqlの「null」に相当します
isnotnull --- findbyusernameisnotnull()など、sqlの「null」に相当します
notnull --- isnotnullに相当します
like --- findbyusernamelike(string user)など、SQLの「いいね」に相当する
類似していない--- findbyusernamenotlike(string user)など、sqlで「好きではない」に相当します
orderby ---- findbyUsernameOrderBySalaryASC(String user)など、SQLの「注文」に相当します
not --- sqlの "!="に相当します。たとえば、findbyusernamenot(string user)
in --- findbyusernamein(collection <string> userlist)など、sqlの「in」に相当します。メソッドのパラメーターは、コレクションタイプ、またはアレイ、または無期限の長さパラメーターを使用できます。
notin --- findbyusernamenotin(collection <string> userlist)など、sqlの「not in」に相当します。メソッドのパラメーターは、コレクションタイプ、またはアレイ、または無期限の長さパラメーターを使用できます。
5。クエリを作成する順序
インターフェイスのプロキシオブジェクトを作成する場合、上記の状況の複数が同時に利用可能であることがわかった場合、最初にどの戦略を採用する必要がありますか?これを行うには、<JPA:リポジトリ> Query-Lookup-Strategyプロパティを提供して、検索の順序を指定します。次の3つの値があります。
メソッド名を解決してクエリを作成します。名前付きクエリ、または@Queryを介してメソッドで指定されたクエリステートメントがある場合でも、無視されます。
create-if-not-found ---メソッドが@queryを介してクエリステートメントを指定する場合、クエリが実装されます。そうでない場合は、基準を満たす名前のクエリが定義されているかどうかが見つかりました。見つかった場合、名前付きクエリが使用されます。どちらも見つからない場合、メソッド名を解析することによりクエリが作成されます。 This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
Careful readers may see some clues from the above code. When we use Spring data JPA, we just define the interface. When using it, we can just inject it directly, and we do not do any processing related to things. But in fact, things have already achieved results.なぜこれがなぜですか?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。