لقد كان يستخدم بيانات الربيع JPA لفترة من الوقت. خلال هذه الفترة ، تعلمت بعض الأشياء وواجهت بعض المشاكل. سوف أشاركهم معك هنا.
مقدمة:
مقدمة لبيانات الربيع:
بيانات Spring هي إطار مفتوح المصدر لتبسيط الوصول إلى قاعدة البيانات ودعم الخدمات السحابية. هدفها الرئيسي هو إمكانية الوصول إلى البيانات مريحة وسريعة ، ودعم إطار عمل Reduce وخدمات بيانات الحوسبة السحابية. تحتوي بيانات الربيع على مشاريع فرعية متعددة:
العموم - يوفر إطار عمل أساسي مشترك مناسب للاستخدام في كل مشروع فرعي ويدعم ثبات الإقرار المتقاطع
JPA - تبسيط القدرة على إنشاء مستويات الوصول إلى بيانات JPA ومواصفات الثبات عبر التخزين
Hadoop - MapReduce Job استنادًا إلى تكوين وظائف Hadoop في Spring ونموذج برمجة POJO
القيمة الرئيسية - يدمج Redis و Riak لتوفير عبوة بسيطة في سيناريوهات متعددة مشتركة
المستند - دمج قواعد بيانات المستندات: CouchDB و MongoDB وتوفير تعيين التكوين الأساسي ودعم المكتبة
الرسم البياني - Neo4J متكامل لتوفير نموذج برمجة قوي قائم على POJO
Graph Roo Addon - Roo Support for Neo4J
امتدادات JDBC - يدعم Oracle Rad ، قوائم الانتظار المتقدمة ، وأنواع البيانات المتقدمة
رسم الخرائط - توفير إطار رسم خرائط الكائنات بناءً على الكأس ، ودعم قواعد البيانات المختلفة
أمثلة - نماذج البرامج والمستندات وقواعد بيانات الرسم البياني
التوجيه - الوثائق المتقدمة
1. مقدمة لبيانات الربيع JPA
SPRING DATA JPA هو إطار تطبيق JPA مغلف بواسطة Spring استنادًا إلى مواصفات ORM Framework و JPA ، ويوفر مجموعة كاملة من حلول طبقة الوصول إلى البيانات.
2. بيانات الربيع JPA وظائف
بيانات الربيع JPA لها وظائف قوية للغاية. هنا نتخطى خطوة بناء البيئة ونلقي نظرة على "حلاوة" بيانات الربيع JPA.
يوفر بيانات الربيع JPA للمستخدمين الواجهات التالية:
3.
1. واجهة crudrepository
إنشاء فئة كيان:
entity @table (name = "user") user user {idgeneratedValue private integer id ؛ // حساب حساب السلسلة الخاصة ؛ // اسم اسم السلسلة الخاصة ؛ // كلمة المرور كلمة مرور السلسلة الخاصة ؛ // البريد الإلكتروني للسلسلة الخاصة ؛ } اكتب واجهة وراثي واجهة crudrepository:
الواجهة العامة userrepository يمتد crudrepository <user ، integer> {} اكتب فئة اختبار (لرؤية التأثير بشكل أكثر حدًا ، لا تستخدم جميع فئات الاختبار التأكيدات ، وبيانات الطباعة المستخدمة مباشرة):
الطبقة العامة userRepositoryTest {autowired 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 (المستخدم) ؛ } @test // حفظ public void testSave1 () {list <serve> users = new ArrayList <Sether> () ؛ مستخدم المستخدم = مستخدم جديد () ؛ user.setName ("tanjie") ؛ user.setAccount ("10000") ؛ user.setemail ("[email protected]") ؛ user.setPassword ("123456") ؛ user.add (user) ؛ المستخدم = مستخدم جديد () ؛ user.setName ("Esdong") ؛ user.setAccount ("10000") ؛ user.setemail ("[email protected]") ؛ user.setPassword ("123456") ؛ user.add (user) ؛ المستخدم = مستخدم جديد () ؛ user.setName ("Qinhongfei") ؛ user.setAccount ("10000") ؛ user.setemail ("[email protected]") ؛ user.setPassword ("123456") ؛ user.add (user) ؛ المستخدم = مستخدم جديد () ؛ user.setName ("huizhang") ؛ user.setAccount ("10000") ؛ user.setemail ("[email protected]") ؛ user.setPassword ("123456") ؛ user.add (user) ؛ المستخدم = مستخدم جديد () ؛ user.setName ("caicican") ؛ user.setAccount ("10000") ؛ user.setemail ("[email protected]") ؛ user.setPassword ("123456") ؛ user.add (user) ؛ dao.save (المستخدمين) ؛ } @test // تحديث public void testupdate () {user user = dao.findone (1) ؛ user.setPassword ("123890") ؛ // لتنفيذ وظيفة التحديث بهذه الطريقة ، تحتاج إلى إضافة التعليق التوضيحي thingtransaction إلى طبقة الخدمة} @test // حذف public void testDelete () {dao.delete (2) ؛ } @test // query all public void testfindall () {list <Sether> users = (list <Ser>) dao.findall () ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } @test // Query ما إذا كان كائن المعرف المحدد موجودًا باطلة باطلة عامة () {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) ؛ قائمة <Sether> المستخدمين = (قائمة <Sether>) dao.findall (listids) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ }} كما ترون ، في هذه المرحلة ، كتبت فقط فئة واجهة واحدة ولم أنفذ فئة الواجهة هذه ، حتى أتمكن من إكمال عملية CRUD الأساسية. نظرًا لأن هذه الواجهة ستقوم تلقائيًا بإنشاء طرق لإضافة وحذف وتعديل والبحث عن كائنات المجال ، للاستخدام المباشر لطبقة العمل.
يتم تعريف الواجهة على النحو التالي ، ويتم توفير ما مجموعه 11 طريقة ، والتي يمكن أن تلبي بشكل أساسي عمليات CRUD البسيطة وعمليات الدُفعات:
@norepositorybean الواجهة العامة crudrepository <t ، معرف يمتد serializable> يمتد المستودع <t ، id> {<s يمتد t> s (كيان s) ؛ // save <s تمديد t> it is exists (idefer <s> ectities) ؛ ITERBABLE <T> findall () ؛ // QUERY جميع الكائنات ITERFIR <T> findall (ITERFIR <ID> IDS) ؛ // QUERY جميع الكائنات بناءً على قائمة المعرفات الطويلة () ؛ // احسب العدد الإجمالي للكائنات الفراغ الفراغ (معرف المعرف) ؛ DELETEALL () ؛ // حذف الكل} 2. PagingandsortingRepository واجهة
ترث واجهة PagingandSortingRepository واجهة crudrepository.
اكتب واجهات وورث pagingandsortingrepository واجهة
الواجهة العامة userrepositorywithorder تمتد pagingandsortingRepository <user ، integer> {} اكتب فصول الاختبار:
Runwith (springJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classpath: applicationContext-config.xml"}) transactionConfiguration (defaultRollback = false) transactional public userrepositorywithorderTest {ateruutowired deo. test public void testorder () {sort sort = new sort (direction.desc ، "id") ؛ قابلة للباحة قابلة للباحة = جديد pagerequest (0 ، 5 ، الفرز) ؛ صفحة <Ser> page = dao.findall (قابلة للتماس) ؛ System.out.println (json.tojsonstring (page)) ؛ System.out.println (page.getSize ()) ؛ }} طالما أنك ترث هذه الواجهة ، ستوفر لك بيانات Spring Data JPA بالفعل وظائف ترقيم الصفحات والفرز. يتم تعريف الواجهة على النحو التالي ، ويتم توفير طريقتين للاستخدام ، حيث T هي فئة الكيان المراد تشغيلها ومعرف هو نوع المفتاح الأساسي للفئة الكيان
@norepositorybean الواجهة العامة pagingandsortingRepository <t ، معرف يمتد serializable>
3. واجهة JParepository
إذا احتاجت الأعمال إلى توفير عمليات CRUD وأيضًا توفير وظائف الترحيل والفرز ، فيمكنك أن ترث هذه الواجهة مباشرة. ترث هذه الواجهة واجهة pagingandsortingrepository.
يتم تعريف الواجهة على النحو التالي:
الواجهة العامة jParePository <t ، معرف يمتد serializable> يمتد pagingandsortingRepository <t ، id> {list <t> findall () ؛ // Query جميع الكائنات ، لا تقم بتصنيف القائمة <T> findall (الفرز) ؛ يتزامن مع قاعدة البيانات t saveandflush (كيان t) ؛ // حفظ وقوة مزامنة void deleteinbatch (iterable <T> الكيانات) ؛ // الدفعة حذف void deleteallinbatch () ؛ // حذف all} 4. jpaspecificationexecutor واجهة
توفر هذه الواجهة دعمًا لاستعلامات معايير JPA. لاحظ أن هذه الواجهة خاصة جدًا ولا تنتمي إلى نظام المستودع. لن تقوم JPA بيانات الربيع بالمسح والتعرف تلقائيًا ، وبالتالي لن يتم العثور على الفول المقابل. نحتاج فقط إلى ورث أي واجهة فرعية يرث مستودعًا أو يرث مباشرة واجهة المستودع. ستقوم بيانات SPRING DATA JPA تلقائيًا بمسح الإدارة الموحدة والتعرف عليها وتنفيذها.
الواجهة مكتوبة على النحو التالي:
توسيع نطاق الواجهة العامة specificexecutorrepository crudrepository <user ، integer> ، jpaspecificationExecutor <Ser> {} فئة الخدمة:
service public class spectionExecutorRepositoryManager {autowired private specificationExecutorrepository dao ؛ / *** الوصف: الاستعلام عن المستخدم استنادًا إلى الاسم*/ المستخدم العام findUserByName (اسم السلسلة النهائية) {return dao.findone (مواصفات جديدة <serve> () {Override Public Suster Topredicate (root <ser> root ، criteriaquery <؟> Query ، Criteriabuilder cb) }) ؛ } / *** الوصف: الاستعلام عن المستخدم استنادًا إلى الاسم والبريد الإلكتروني* / المستخدم العام FindUserByNameAndemail (اسم السلسلة النهائية ، البريد الإلكتروني السلسلة النهائية) {return dao.findone (مواصفات جديدة <Sether> () { @Override predicate topredicate (prest> atray <sust> Predict1 = cb.equal ("الاسم") ؛ } / *** الوصف: تركيبة الاستعلام* / المستخدم العام findUserByUser (المستخدم النهائي Uservo) {return dao.findone (مواصفات جديدة <serve> () uservo.getName ()) ؛ } / *** الوصف: استعلام النطاق في الطريقة ، مثل الاستعلام عن المستخدم بمعرف المستخدم في [2،10]* / قائمة عامة <Seter> findUserByIds (القائمة النهائية <integer> ids) {return dao.findall (مواصفات جديدة <Seter> () rout.in (ids) ؛ ) cb.gt (root.get ("id"). as (integer.class) ، id) ؛ ) cb.lt (root.get ("id"). as (integer.class) ، id) ؛ } / *** الوصف: استعلام النطاق بين الأساليب ، مثل الاستعلام عن المستخدمين الذين يعانون من معرفات بين 3 و 10* / قائمة عامة <sustr> findUserBetweenId (بداية int النهائية ، نهاية int النهائية) cb.between (root.get ("id"). AS (integer.class) ، start ، end) ؛ } / *** الوصف: عمليات الفرز والتراجع* / الصفحة العامة <Sether> findUserAndorder (معرف int النهائي) {sort sort = new sort (direction.desc ، "id") ؛ return dao.findall (مواصفات جديدة <Sether> () {Override Public Predicate Topredicate (Root <Seter> Root ، NeteriaQuery <؟> Query ، Criteriabuilder cb) {return cb.gt (root.get ("id"). } / *** الوصف: فقط عمليات الفرز* / قائمة عامة <Seter> findUserAndorSERSECONDMETHOD (Final int id) {return dao.findall (مواصفات جديدة <Sether> () cb.gt (root.get ("id"). as (integer.class) ، id) ؛ }} فئة الاختبار:
RunWith (springJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classPath: ApplicationContext-config.xml"}) transactionConfiguration (defaultRolback = false) transactional public specitionExecutoreRepoStoryAgerTest { 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]") ؛ user u = manager.finduserByuser (user) ؛ System.out.println (json.tojsonstring (u)) ؛ } test public void testfinduserbyids () {list <Sether> users = manager.finduserByids (ArrayList new integer> (Arrays.Aslist (1،3،5،6))) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } test public void testfinduserbygtid () {list <Ser> users = manager.finduserbygtid (5) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } test public void testfinduserbyltid () {list <Ser> users = manager.finduserbyltid (5) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } test public void testFindUserBetweenId () {list <Sether> users = manager.finduserBetweenId (4 ، 9) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } test public void testfinduserandorder () {page <Ser> users = manager.finduserandorder (1) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } test public void testFindUserAndorseCondMethod () {list <Sether> users = manager.finduserAndorseCondMethod (1) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ }} 5. واجهة المستودع
هذه الواجهة هي الواجهة الأساسية ، إنها مجرد واجهة مبدئية ، ولا يتم تعريف أي طرق ، فما هو فائدة هذه الواجهة؟ نظرًا لأن بيانات الربيع توفر JPA هذه الواجهة ، فهي مفيدة بالطبع. على سبيل المثال ، بعض الطرق التي لا نريد تقديمها من الخارج. على سبيل المثال ، نريد فقط توفير طرق الإضافة والتعديل وليس طرق الحذف ، ثم لا يمكن للواجهات السابقة القيام بذلك. في هذا الوقت ، يمكننا أن نرث هذه الواجهة ونسخ الأساليب المقابلة في واجهة crudrepository إلى واجهة المستودع.
ملخص: كيف ينبغي للمطورين اختيار الواجهات الخمسة المذكورة أعلاه؟ في الواقع ، الأساس بسيط للغاية. اختر أحدهم وفقًا لاحتياجات العمل المحددة. لأنه لا توجد مشكلة في القوة والقوة بين كل واجهة.
4. استعلام بيانات الربيع JPA
1. إنشاء استعلام باستخدام Query
استخدام التعليقات التوضيحية Query أمر بسيط للغاية. تحتاج فقط إلى تسمية التعليق التوضيحي على الطريقة المعلنة وتقديم بيان استعلام JP QL. يحب العديد من المطورين استخدام المعلمات المسماة بدلاً من أرقام الموضع عند إنشاء JP QL ، كما يوفر Query الدعم لهذا الغرض. في عبارة JP QL ، يتم تحديد المعلمات من خلال تنسيق ": متغير" ، وفي نفس الوقت ، يتم استخدام param أمام معلمات الطريقة لتتوافق مع المعلمات المسماة في JP QL. بالإضافة إلى ذلك ، يمكن للمطورين أيضًا إجراء عملية تحديث باستخدام Query. للقيام بذلك ، نحتاج إلى استخدام التعديل لتحديد العملية كاستعلام معدّل أثناء استخدام @Query ، بحيث يقوم الإطار في النهاية بإنشاء عملية محدثة ، وليس عملية استعلام.
اكتب واجهة على النحو التالي:
/*** الوصف: استعلام مخصص. عندما لا يمكن توفير بيانات SPRING JPA ، يلزم وجود واجهة مخصصة. يمكن استخدام هذه الطريقة في هذا الوقت*/ الواجهة العامة userDefineByself يمتد JParePository <user ، integer> {/ *** parameters المسماة* الوصف: من المستحسن استخدام هذه الطريقة ، يمكنك تجاهل موقع المعلمات*/ Query ("حدد u من المستخدم u where youghename =: name") finduserbyname ("paraper" ؛ /*** معلمات الفهرس* الوصف: استخدام؟ العنصر النائب*/ Query ("حدد U من user u where U.Email =؟ 1") // 1 يشير المستخدم إلى المعلمة الأولى FindUserByEmail (سلسلة البريد الإلكتروني) ؛ /*** الوصف: يمكن تحقيق التحديثات من خلال modifypify و @query* ملاحظة: لا يمكن أن تكون قيمة الإرجاع لتعديل الاستعلامات باطلة أو int/integer*/modifypification @Query ("تحديث المستخدم U.Name =: name where u.id = id") Int UpdateSerByid (name ") اسم السلسلة ، id id") ؛ } ملاحظة: التعليق التوضيحي المعدني يحتوي على تكوين واضح بشكل واضح
تقول أنه يمكن مسح سياق الثبات الأساسي ، وهو فئة ContityManager. نحن نعلم أن التنفيذ الأساسي لـ JPA سيكون له ذاكرة التخزين المؤقت الثانوية ، أي بعد تحديث قاعدة البيانات ، إذا كنت تستخدم هذا الكائن لاحقًا ، فستقوم بفحص الكائن. تم تخزين هذا الكائن في المستوى الأول ، لكنه لم يتم مزامنته مع قاعدة البيانات. في هذا الوقت ، سيتم استخدام ClearAtominy = true لتحديث ذاكرة التخزين المؤقت من المستوى الأول من السبات. خلاف ذلك ، ستقوم بتحديث كائن في نفس الواجهة ثم الاستعلام عن هذا الكائن ، فإن الكائن الذي عثرت عليه لا يزال الحالة السابقة التي لم يتم تحديثها من قبل.
فئة الاختبار:
Runwith (springJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classPath: ApplicationContext-config.xml"}) transactionConfiguration (defaultrollback = false) transactional public userDefineByselfTest {autoWired userDefineByselfine 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 تفصل بين عبارات الاستعلام عن هيئة الطريقة لمشاركة طرق متعددة. يوفر Dring Data JPA أيضًا دعمًا جيدًا للاستعلامات المسماة. يحتاج المستخدمون فقط إلى تحديد عبارة الاستعلام في ملف ORM.XML أو في الرمز وفقًا لمواصفات JPA. الشيء الوحيد الذي يتعين عليهم فعله هو تلبية قواعد التسمية "domainclass.methodname ()" عند تسمية البيان.
كتابة واجهة:
الواجهة العامة FindUserByNamedQueryRepository يمتد JParePository <user ، integer> {user findUserWithName (param ("name") اسم السلسلة) ؛ } كتابة فصل:
entity @namedquery (value = {namedquery (name = "user.finduserWithName" ، Query = "Select u from u u u u.name =: name")}) // ملاحظة: إذا كانت هناك طرق متعددة هنا ، فأنت بحاجة إلى استخدام namedquery. إذا كانت هناك طريقة واحدة فقط ، فيمكنك استخدام NamedQuery. طريقة الكتابة هي كما يلي: namedquery (name = "user.finduserWithName" ، Query = "SELECT u من user u where U.Name =: name") فئة عامة findUserByNamedQuery { / *** ملاحظة: يجب تعريف هذه الفئة الكيان هنا ، وإلا سيتم الإبلاغ عن استثناء* / @ @generatedvalue id id ideer ؛ } ملاحظة: يجب أن تتوافق الأجزاء المحددة باللون الأحمر في المقالة واحدة تلو الأخرى ، وإلا فلن تفي بمواصفات JPA.
فئة الاختبار:
runwith (springJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classpath: applicationContext-config.xml"}) transactionConfiguration (defaultRollback = false) trans actactional publicnamnamedquereReposeRepositoryTest { test public void testfinduserbyname () {user user = dao.finduserWithName ("caiCan") ؛ System.out.println (json.tojsonstring (user)) ؛ }} 3. قم بإنشاء استعلام عن طريق تحليل اسم الطريقة
كما يوحي الاسم ، هو إنشاء استعلام بناءً على اسم الطريقة. ربما يبدو الأمر لا يصدق في البداية ، ولكن بعد الاختبار ، وجدت أن كل شيء ممكن.
كتابة واجهة:
الواجهة العامة SimplEconditionQuereRepository تمتد JParePository <user ، integer> { /*** الوصف: وفقًا للقواعد المحددة بواسطة بيانات الربيع ، تبدأ طريقة الاستعلام بـ Find | read | get* عندما يتعلق الأمر بالاستعلام الشرطي ، ترتبط خصائص الشرط بالكلمات الرئيسية الشرطية. تجدر الإشارة إلى أن: الحرف الأول من السمة الشرطية يجب أن يكون كبيرًا*// *** ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم u حيث يكون اسم U.NAME =: الاسم و u.email =: البريد الإلكتروني* اسم المعلمة هو assucture as as ass straptar FindBynameAndemail (اسم السلسلة ، البريد الإلكتروني السلسلة) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد u من المستخدم u where U.Name =؟ 1 أو U.Password =؟ 2 */ LIST <Sether> findByNamePassword (اسم السلسلة ، كلمة مرور السلسلة) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث U.ID بين 1 و 2 */ LIST <Sether> findByidBetween (integer start ، integer end) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث U.ID بين 1 و 2 */ LIST <Sether> findByidBetween (integer start ، integer end) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من uster u حيث U.ID <؟ 1 */ list <Sether> findbyidlessthan (integer end) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد u من المستخدم u where U.ID> 1 */ list <Sether> findbyidgreaterthan (integer start) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث يكون اسم الأمم المتحدة فارغًا */ LIST <Sether> findByNameIsnull () ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث لا يكون اسم الأمم المتحدة فارغًا */ LIST <Sether> findbyNameIsnotnull () ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث اسم الأمم المتحدة مثل؟ 1 */ LIST <Sether> findbynamelike (اسم السلسلة) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد u من المستخدم U حيث لا تحب اسم الأمثال؟ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من user u where U.Password =؟ 1 order by U.ID desc */ list <Sether> findByPasswordorderByidDesc (سلسلة كلمة مرور) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من user u where yutegy <>؟ 1 */ list <serve> findbynamenot (اسم السلسلة) ؛ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من المستخدم U حيث U.ID في؟ / ** * ملاحظة: هذه الواجهة هنا تعادل إرسال SQL: حدد U من user u حيث U.ID لا في؟ } فئة الاختبار (جزء التعليق هو بيان SQL الفعلي المرسل):
RunWith (springJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classPath: ApplicationContext-config.xml"}) transactionConfiguration (defaultRollback = false) thantactactional public class simpleconditionRepositoryTestOrest { /*** حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_password 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)) ؛ } /*** حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.name =؟ أو user0_.password =؟ */ test public void testfinduserbynameorpassword () {list <Sether> users = dao.findbynamePassword ("chhliu" ، "123456") ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.id بين؟ و ؟ */ test public void testfindbetbetween () {list <Sether> users = dao.findbyidbetween (5 ، 8) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.id <؟ */ test public void testfindbyidhan () {list <Sether> users = dao.findbyidhanthan (4) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_password as password0_ from user0_ where user0_.id>؟ */ test public void testfindbyidgreaterthan () {list <Sether> users = dao.findbyidgreaterthan (6) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } / ** * حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_.password as password0_ from user0_ where user0_.name null * / test public void testfindbynamenull () System.out.println (json.tojsonstring (المستخدمين)) ؛ } / ** * حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.name لا null * / test public void testfindbynameisnull ( dao.findbynameisnotnull () ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_name ke؟ */ test public void testfindbynameLike () {list <Sether> users = dao.findbynamelike ("chhliu") ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_password as password0_ from user0_ where user0_.name not like؟ */ test public void testfindbynamenotlike () {list <Sether> users = dao.findbynamenotlike ("chhliu") ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_password as password0_ from user0_ where user0_password =؟ order بواسطة user0_.id desc */ test public void testfindbypasswordorderbyiddesc () {list <Sether> users = dao.findbypasswordorderbydesc ("123456") ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } /*** حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.name <>؟ */ test public void testfindbynamenot () {list <Ser> users = dao.findbynamenot ("chhliu") ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } / ** * حدد user0_.id as id1_ ، user0_.account as account1_ ، user0_.email as email1_ ، user0_.name as name1_ ، user0_password as password1_ from user0_ where user0_.id in (؟ ،؟ ،؟ ،؟) ArrayList <integer> (Arrays.aslist (3،4،6،8))) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ } / ** * حدد user0_.id as id0_ ، user0_.account as account0_ ، user0_.email as email0_ ، user0_.name as name0_ ، user0_password as password0_ from user0_ where user0_.id not in (؟ ،؟ ،؟ ،؟) dao.findbyidnotin (ArrayList جديد <integer> (Arrays.aslist (3 ، 4 ، 6 ، 8))) ؛ System.out.println (json.tojsonstring (المستخدمين)) ؛ }} هنا ، نحدد واجهة واحدة فقط. لا توجد سوى طرق في الواجهة ، ولكن لا يوجد تنفيذ ، ولكن يتم الانتهاء من العمليات المختلفة.
بعد رؤية هذا ، من المحتمل أن يسأل الكثير من الناس ، كيف فعلت بيانات الربيع JPA؟ اتضح أنه عندما يقوم الإطار بتحليل اسم الطريقة ، فإنه سيعترض أولاً على البادئات الزائدة لاسم الطريقة ، مثل Find و FindBy و Readby و READBY و GET و GETBY ، ثم تحليل الجزء المتبقي. وإذا كانت المعلمة الأخيرة من الطريقة من النوع أو نوعًا قابلاً للباحة ، فسيتم أيضًا استخراج المعلومات ذات الصلة للفرز أو استعلام ترقيم الصفحات حسب القواعد. عند إنشاء استعلام ، نعبر عنه باستخدام أسماء السمات في اسم الطريقة ، مثل FindByidin (). عندما يقوم الإطار بتوصيف هذه الطريقة ، فإنه يزيل أولاً Findby ثم يوسع السمات المتبقية.
عند الاستعلام ، يكون من الضروري عادةً الاستعلام بناءً على سمات متعددة في نفس الوقت ، كما أن ظروف الاستعلام هي أيضًا تنسيقات مختلفة (أكبر من قيمة معينة ، في نطاق معين ، إلخ). يوفر Dring Data JPA بعض الكلمات الرئيسية للتعبير عن الاستعلام الشرطي ، على النحو التالي:
و --- ما يعادل الكلمة والكلمة الرئيسية في SQL ، مثل FindByuserNameAndPassword (مستخدم سلسلة ، Striang PWD)
أو --- تعادل أو الكلمات الرئيسية في SQL ، مثل FindByUserNameoraddress (مستخدم سلسلة ، سلسلة addr)
بين --- بين الكلمة الرئيسية المكافئة لـ SQL ، مثل FindBysAlaryBetween (int max ، int min)
Lessthan --- ما يعادل "<" في SQL ، مثل FindBysalarylessthan (int max)
Greatthan --- ما يعادل ">" في SQL ، مثل FindBysalaryGreaterthan (int min)
isnull --- ما يعادل "هو خالية" في SQL ، مثل FindByUsernameIsnull ()
isnotnull --- ما يعادل "ليس فارغا" في SQL ، مثل FindByUsernameIsnotnull ()
Notnull --- ما يعادل isnotnull
مثل --- يعادل "أعجبني" في SQL ، مثل FindByusernameLike (مستخدم سلسلة)
ليس مثل --- ما يعادل "ليس مثل" في SQL ، مثل FindByusernamenotlike (مستخدم سلسلة)
Orderby ---- ما يعادل "Order by" في SQL ، مثل FindByUserNameOrderBysalaryasc (مستخدم سلسلة)
لا --- تعادل "! =" في SQL ، على سبيل المثال ، FindByusernamenot (مستخدم سلسلة)
في --- ما يعادل "في" في SQL ، مثل FindByuserNameIn (Collection <String> userlist). يمكن أن تكون معلمات الطريقة من نوع المجموعة ، أو صفيف أو معلمة طول غير محددة.
notin --- ما يعادل "لا في" في SQL ، مثل FindByusernamenotin (Collection <string> userlist). يمكن أن تكون معلمات الطريقة من نوع المجموعة ، أو صفيف أو معلمة طول غير محددة.
5. ترتيب إنشاء استفسارات
عند إنشاء كائن وكيل لواجهة ، إذا وجدت أن مضاعفات المواقف المذكورة أعلاه متوفرة في نفس الوقت ، ما هي الاستراتيجية التي يجب أن تتبناها أولاً؟ للقيام بذلك ، <JPA: RESOSITIONS> يوفر خاصية QUERY-LOOKUP-Strategy لتحديد ترتيب عمليات البحث. لديها القيم الثلاث التالية:
إنشاء --- إنشاء استعلام عن طريق حل اسم الطريقة. حتى إذا كان هناك استعلام مطابق ، أو بيان الاستعلام المحدد بواسطة الطريقة من خلال Query ، فسيتم تجاهله.
إنشاء-إذا لم يكن --- إذا كانت الطريقة تحدد عبارة استعلام من خلال Query ، يتم تنفيذ الاستعلام ؛ إذا لم يكن الأمر كذلك ، فقد تم العثور على ما إذا كان الاستعلام المسماة الذي يلبي المعايير محددة ، إذا وجدت ، يتم استخدام الاستعلام المسماة ؛ إذا لم يتم العثور على أي منهما ، يتم إنشاء الاستعلام عن طريق تحليل اسم الطريقة. This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
细心的读者也许从上面的代码中看出了一些端倪,我们在使用Spring data JPA的时候,只是定义了接口,在使用的时候,直接注入就可以了,并没有做与事物相关的任何处理,但实际上,事物已经起到效果了,这又是为什么了?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.