Ini telah menggunakan data spring JPA untuk sementara waktu. Selama periode ini, saya belajar beberapa hal dan mengalami beberapa masalah. Saya akan membaginya dengan Anda di sini.
Kata pengantar:
Pengantar Data Musim Semi:
Spring Data adalah kerangka kerja open source untuk menyederhanakan akses basis data dan mendukung layanan cloud. Tujuan utamanya adalah untuk membuat akses ke data nyaman dan cepat, dan untuk mendukung kerangka kerja peta-reduce dan layanan data komputasi awan. Data pegas berisi beberapa subproyek:
Commons - Menyediakan kerangka kerja dasar bersama yang cocok untuk digunakan di setiap subproyject dan mendukung persistensi silang -database
JPA - Menyederhanakan kemampuan untuk membuat tingkatan akses data JPA dan tingkatan kegigihan di seluruh penyimpanan
Hadoop - Pekerjaan MapReduce Berdasarkan Konfigurasi Pekerjaan Hadoop Spring dan Model Pemrograman Pojo
Nilai Kunci - Mengintegrasikan Redis dan Riak untuk memberikan kemasan sederhana dalam beberapa skenario umum
Dokumen - Mengintegrasikan Database Dokumen: CouchDB dan MongoDB dan menyediakan pemetaan konfigurasi dasar dan dukungan perpustakaan
Grafik - Neo4j terintegrasi untuk memberikan model pemrograman berbasis POJO yang kuat
Graph Roo Addon - Dukungan Roo untuk Neo4j
Ekstensi JDBC - Mendukung Oracle RAD, antrian lanjutan, dan tipe data lanjutan
Pemetaan - Kerangka Pemetaan Objek yang Disediakan Berdasarkan Cawan, Mendukung Berbagai Basis Data
Contoh - Contoh program, dokumen, dan basis data grafik
Panduan - Dokumentasi Lanjutan
1. Pengantar JPA Data Musim Semi
Spring Data JPA adalah kerangka kerja aplikasi JPA yang dienkapsulasi oleh Spring berdasarkan kerangka kerja ORM dan spesifikasi JPA, dan menyediakan satu set lengkap solusi lapisan akses data.
2. Fungsi JPA Data Musim Semi
Data Spring JPA memiliki fungsi yang sangat kuat. Di sini kami melewatkan langkah konstruksi lingkungan dan melihat "manis" dari data pegas JPA.
Data Spring JPA memberi pengguna antarmuka berikut:
3. Antarmuka JPA Data Spring
1. Antarmuka crudrepository
Buat kelas entitas:
@Entity @table (name = "user") pengguna kelas publik {@id @generatedValue Private Integer ID; // Akun Akun String Pribadi; // Nama nama string pribadi; // Kata Sandi Private String Password; // Email email string pribadi; } Tulis antarmuka dan wariskan antarmuka crudrepository:
Antarmuka publik USErrepository memperluas crudrepository <user, integer> {} Tulis kelas tes (untuk melihat efeknya secara lebih intuitif, semua kelas tes tidak menggunakan pernyataan, dan pernyataan cetak yang secara langsung digunakan):
kelas publik userrepositorytest {@autowired private userrepository dao; @Tes // simpan public void testSave () {user user = new user (); user.setname ("chhliu"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); dao.save (pengguna); } @Test // simpan public void testSave1 () {list <user> user = new ArrayList <User> (); Pengguna pengguna = pengguna baru (); user.setname ("tanjie"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); Users.add (pengguna); pengguna = pengguna baru (); user.setname ("esdong"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); Users.add (pengguna); pengguna = pengguna baru (); user.setname ("qinhongfei"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); Users.add (pengguna); pengguna = pengguna baru (); user.setname ("huizhang"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); Users.add (pengguna); pengguna = pengguna baru (); user.setname ("caican"); user.setAccount ("10000"); user.setemail ("[email protected]"); user.setPassword ("123456"); Users.add (pengguna); dao.save (pengguna); } @Test // Perbarui public void testUpdate () {user user = dao.findone (1); user.setPassword ("123890"); // Untuk mengimplementasikan fungsi pembaruan dengan cara ini, Anda perlu menambahkan anotasi @transaction hal ke lapisan layanan} @test // hapus public void testDelete () {dao.delete (2); } @Test // kueri semua public void testFindAll () {list <user> user = (list <user>) dao.findall (); System.out.println (json.tojsonstring (pengguna)); } @Test // query Apakah objek ID yang ditentukan ada public void testisexist () {boolean isexist = dao.exist (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); Daftar <User> Users = (Daftar <User>) dao.findall (listIds); System.out.println (json.tojsonstring (pengguna)); }} Seperti yang Anda lihat, pada titik ini, saya hanya menulis satu kelas antarmuka dan tidak mengimplementasikan kelas antarmuka ini, jadi saya bisa menyelesaikan operasi dasar CRUD. Karena antarmuka ini akan secara otomatis membuat metode untuk menambah, menghapus, memodifikasi, dan mencari objek domain, untuk penggunaan langsung lapisan bisnis.
Antarmuka didefinisikan sebagai berikut, dan total 11 metode disediakan, yang pada dasarnya dapat memenuhi operasi CRUD sederhana dan operasi batch:
@Norepositorybean antarmuka publik crudrepository <t, ID memperluas serializable> memperluas repositori <t, id> {<s extends t> s save (s entitas); // simpan <s extends t> iterable <s> simpan (iterable <s> entitas); // query save t findone (id id); object has Iterable<T> findAll();//Query all objects Iterable<T> findAll(Iterable<ID> ids);//Query all objects based on the id list long count();//Calculate the total number of objects void delete(ID id);//Delete void delete(T entity);//Delete the object void delete(Iterable<? extends T> entities);//Batch hapus void deleteall (); // hapus semua} 2. PagingAndSortingRepository Interface
Antarmuka PagingAndSortingRepository mewarisi antarmuka crudrepository.
Tulis antarmuka dan warisan pagingandsortingrepository antarmuka
antarmuka publik userrepositoryWithOrder memperluas pagingandsortingrepository <user, integer> {} Tulis kelas tes:
@Runwith (springjunit4classrunner.class) @contextConfiguration (locations = {"classpath: applicationContext-config.xml"}) @transactionconfiguration (defaultrollback = false) @transactional public userrepository withoestest {@aePository @aePository @aePository UserRepositoryWithestest {@aePository @aePository @aRePository {a @aePository @Test public void testorder () {sort sort sort = new sort (direction.desc, "id"); Pengirim lampiran = pagerequest baru (0, 5, sort); Halaman <user> halaman = dao.findall (pagable); System.out.println (json.tojsonstring (halaman)); System.out.println (page.getsize ()); }} Selama Anda mewarisi antarmuka ini, JPA data pegas sudah akan memberi Anda fungsi pagination dan penyortiran. Antarmuka didefinisikan sebagai berikut, dan dua metode disediakan untuk digunakan, di mana T adalah kelas entitas yang akan dioperasikan dan ID adalah jenis kunci primer kelas entitas
@Norepositorybean Public Interface PagingAndSortingRepository <t, ID memperluas serializable> memperluas crudrepository <t, id> {iterable <t> findAll (sortir); // sortir tanpa halaman paging <t> findAll (pagable pagable);/ sort with paging} 3. Jarepository Interface
Jika bisnis perlu menyediakan operasi CRUD dan juga menyediakan fungsi paging dan penyortiran, maka Anda dapat secara langsung mewarisi antarmuka ini. Antarmuka ini mewarisi antarmuka pagingandsorttingrepository.
Antarmuka didefinisikan sebagai berikut:
antarmuka publik jparePository <t, id memperluas serializable> memperluas pagingandsortingrepository <t, id> {list <t> findAll (); // query semua objek, jangan mengurutkan daftar <t> findAll (sortir); // query semua objek, dan mengurutkan <s extends t> list <s save (save <) (save <serable); Sinkronisasi dengan database t saveandflush (t entitas); // simpan dan paksa sinkronisasi void deleteInbatch (iterable <t> entitas); // batch delete void deleteallinBatch (); // hapus semua} 4. JPaspecificationExecutor Interface
Antarmuka ini memberikan dukungan untuk kueri kriteria JPA. Perhatikan bahwa antarmuka ini sangat istimewa dan bukan milik sistem repositori. Data pegas JPA tidak akan secara otomatis memindai dan mengenali, sehingga kacang yang sesuai tidak akan ditemukan. Kita hanya perlu mewarisi setiap sub-antarmuka yang mewarisi repositori atau secara langsung mewarisi antarmuka repositori. JPA data pegas akan secara otomatis memindai dan mengenali dan melakukan manajemen terpadu.
Antarmuka ditulis sebagai berikut:
Spesifikasi Antarmuka Publik Executorrepository memperluas crudrepository <user, integer>, jpaspecificationExecutor <user> {} Kelas Layanan:
@Service Public Class SpecificationExecutorRepositoryManager {@Autowired Private SpecificationExecutorrepository DAO; /** * Description: Query the user based on name*/ public User findUserByName(final String name){ return dao.findOne(new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate predicate = cb.equal(root.get("name"), name); return predicate; } }); } / *** Deskripsi: Permintaan pengguna berdasarkan nama dan email* / pengguna publik findUserbyNeAndemail (nama string akhir, email string akhir) {return dao.findone (spesifikasi baru <user> () {@override public predredicate (root <user> root, criteriaquery <? Query, critereric criteriate (criteria> list = criteriaQuery <?> Critereric criteriate (criteria> list = criteriacery <? Predicate Predict1 = CB.Equal (root.get ("name"); } / *** Deskripsi: kueri kombinasi* / pengguna publik findUserByUser (pengguna akhir userVo) {return dao.findone (spesifikasi baru <User> () {@Override predikat publik TopRedicate (root <user> root, criteriaquery <?> Query, criteriAbuilder cb) {predicate pred predercor = cb. uservo.getname ()); } / *** Deskripsi: Rentang kueri dalam metode, seperti meminta pengguna dengan ID pengguna di [2,10]* / Daftar Publik <User> findUserbyIds (daftar akhir <Integer> ID) {return dao.findall (rooter) {criter {criter> @override {@Override topredicate (root> root, root, crriter {crritquuqu, criter {root, criter {root> {root, criter {root, criter {root, root, root. root.in (IDS);}}); } / *** Deskripsi: Range Query GT Metode, seperti meminta semua pengguna dengan ID pengguna lebih besar dari 9* / daftar publik <user> findUserByGTID (ID int final) {return dao.findall (spesifikasi baru <user> () {@Override public predredicate (root <user> root, criteriacery <) {@Override public cruTredicate (root <user> root, criteriacery <? cb.gt (root.get ("id"). as (integer.class), id); } /** * Description: Range query lt method, such as querying users with user id less than 10*/ public List<User> findUserByLtId(final int id){ return dao.findAll(new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.lt (root.get ("id"). as (integer.class), id); } / *** Deskripsi: Rentang kueri antara metode, seperti permintaan pengguna dengan ID antara 3 dan 10* / daftar publik <user> findUserbetweenId (final int start, final int end) {return dao.findall (spesifikasi baru <User> () {@Override public predicate Topredicate (root <user> root, critriancery <) {@override public topedicate (root <user> root, criterQuery <) <? cb.between (root.get ("id"). as (integer.class), start, end); } / *** Deskripsi: Operasi Sortir dan Pagination* / Halaman Publik <User> findUserAndOrder (ID int akhir) {sort sort = new sort (Direction.desc, "id"); return dao.findall (spesifikasi baru <User> () {@Override public predicate topredicate (root <user> root, criteriaquery <?> kueri, criteriAbuilder cb) {return cb.gt (root.get ("id"). as (integer.class), id);}} baru, pAG ("id"). } / *** Deskripsi: Hanya operasi penyortiran* / Daftar publik <user> findUserAndERSecondMethod (ID int akhir) {return dao.findall (spesifikasi baru <user> () {@Override public predicate Topedicate (root <user> root, criteriaQuery <?> Query, CriteriBuilder cb) {criteriaquery <?> Query, Criteriabuilder) {criteriaCeer <?> cb.gt (root.get ("id"). As (integer.class), id); }} Kelas Tes:
@Runwith (springjunit4classrunner.class) @contextConfiguration (lokasi = {"classpath: applicationContext-config.xml"}) @transactionCorrepository @AacoUrepiRent @AaCoCiPositRest @AaCoUCIRECTEST @AAGEROPOTEST @AAGEROPOTEST @AAGEROPOTEST @Test public void testFindUserbyName () {user user = manager.finduserbyname ("chhliu"); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserbyNeAndemail () {user user = manager.finduserbyneandemail ("chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserbyUservo () {user user = new user (); user.setname ("chhliu"); user.setemail ("[email protected]"); Pengguna u = manajer.finduserbyUser (pengguna); System.out.println (json.tojsonstring (u)); } @Test public void testFindUserbyIds () {list <user> user = manager.findUserbyIds (arraylist baru <Integer> (arrays.aslist (1,3,5,6))); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserbyGtId () {list <user> user = manager.finduserbygtid (5); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserbyLtId () {list <user> user = manager.finduserbyltid (5); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserbetweenId () {list <user> user = manager.finduserbetweenId (4, 9); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserAndoDorder () {page <user> user = manager.findUserAndOder (1); System.out.println (json.tojsonstring (pengguna)); } @Test public void testFindUserAndOrderSecondMethod () {list <user> user = manager.finduserAndORDersecondMethod (1); System.out.println (json.tojsonstring (pengguna)); }} 5. Antarmuka repositori
Antarmuka ini adalah antarmuka paling dasar, itu hanya antarmuka ikonik, dan tidak ada metode yang didefinisikan, jadi apa gunanya antarmuka ini? Karena Spring Data JPA menyediakan antarmuka ini, tentu saja berguna. Misalnya, beberapa metode yang tidak ingin kami berikan secara eksternal. Misalnya, kami hanya ingin memberikan metode penambahan dan modifikasi dan bukan metode penghapusan, maka antarmuka sebelumnya tidak dapat melakukannya. Pada saat ini, kita dapat mewarisi antarmuka ini dan menyalin metode yang sesuai di antarmuka crudrepository ke antarmuka repositori.
Ringkasan: Bagaimana seharusnya pengembang memilih lima antarmuka di atas? Faktanya, dasarnya sangat sederhana. Pilih salah satunya sesuai dengan kebutuhan bisnis tertentu. Karena tidak ada masalah kekuatan dan kekuatan antara setiap antarmuka.
4. Kueri JPA Data Musim Semi
1. Buat kueri menggunakan @Query
Penggunaan anotasi @Query sangat sederhana. Anda hanya perlu memberi label anotasi pada metode yang dinyatakan dan memberikan pernyataan kueri JP QL. Banyak pengembang suka menggunakan parameter bernama alih -alih nomor posisi saat membuat JP QL, dan @Query juga memberikan dukungan untuk ini. Dalam pernyataan JP QL, parameter ditentukan melalui format ": variabel", dan pada saat yang sama, @param digunakan di depan parameter metode agar sesuai dengan parameter yang disebutkan dalam JP QL. Selain itu, pengembang juga dapat melakukan operasi pembaruan dengan menggunakan @Query. Untuk melakukan ini, kita perlu menggunakan @modifying untuk mengidentifikasi operasi sebagai kueri yang dimodifikasi saat menggunakan @Query, sehingga kerangka kerja pada akhirnya akan menghasilkan operasi yang diperbarui, bukan operasi kueri.
Tulis antarmuka sebagai berikut:
/*** Deskripsi: Kueri khusus. Ketika data pegas JPA tidak dapat menyediakan, antarmuka khusus diperlukan. This method can be used at this time*/ public interface UserDefineBySelf extends JpaRepository<User, Integer> { /** * Named parameters* Description: It is recommended to use this method, you can ignore the location of the parameters*/ @Query("select u from User u where u.name = :name") User findUserByName(@Param("name") String name); /*** Parameter indeks* Deskripsi: Gunakan? placeholder*/ @Query ("Pilih u dari pengguna u di mana u.email =? 1") // 1 menunjukkan parameter pertama pengguna findUserByemail (email string); /*** Deskripsi: Pembaruan dapat dicapai melalui @modifying dan @query* Catatan: Nilai pengembalian kueri modifikasi hanya dapat dibatalkan atau int/integer*/@modifying @Query ("Perbarui pengguna u set u.name =: name where u.id =: id") int updateusById (@param ("name") name, @param ("name," @param ("name (" name ("name (" @param ("name (" name ("name," @param ("name (" name ("@param (" name ("name (" @param ("name (" @param ("name (" name ("name (" name ("name (" @param ("name (" name ("name (" name ("name (" name ("name (" @param ("name (" name ("name," } Catatan: @modifying anotasi memiliki konfigurasi dengan jelas secara jelas
Dikatakan bahwa konteks kegigihan yang mendasari dapat dibersihkan, yang merupakan kelas EntityManager. Kami tahu bahwa implementasi JPA yang mendasari akan memiliki cache sekunder, yaitu, setelah memperbarui database, jika Anda menggunakan objek ini nanti, Anda akan memeriksa objek. Objek ini di -cache pada tingkat pertama, tetapi tidak disinkronkan dengan database. Pada saat ini, ClearAutomatik = true akan digunakan untuk menyegarkan cache level pertama Hibernate. Jika tidak, Anda akan memperbarui objek dalam antarmuka yang sama dan kemudian meminta objek ini, maka objek yang Anda temukan masih merupakan keadaan sebelumnya yang belum diperbarui sebelumnya.
Kelas Tes:
@Runwith (springjunit4classrunner.class) @contextConfiguration (locations = {"classPath: applicationContext-config.xml"}) @transactionConfiguration (defaultrollback = false) @transaction Public UserDefineBySelftest {@aUrtollback = false) @transaction Public Class PublicEfineBySelFtest {@aUrtollback @transactional Public Class PublicFineSelfest @Test public void testFindUserbyName () {user user = dao.finduserbyname ("chhliu"); Assert.assertequals ("chhliu", user.getname ()); System.out.println (user.getName ()); } @Test public void testFindUserbyMail () {user user = dao.finduserbyemail ("chhliu @.com"); Assert.assertequals ("chhliu", user.getname ()); System.out.println (user.getName ()); } @Test public void testupDateUserbyId () {dao.updateUserbyId ("tanjie", 4); }} Dari kode uji, kita dapat melihat bahwa kita hanya mendefinisikan antarmuka, tanpa kelas implementasi, tetapi mengimplementasikan fungsi yang kita butuhkan.
2. Buat kueri menggunakan @NamedQueries
Named Query adalah fungsi yang disediakan oleh JPA yang memisahkan pernyataan kueri dari badan metode untuk berbagi beberapa metode. Spring Data JPA juga memberikan dukungan yang baik untuk kueri bernama. Pengguna hanya perlu menentukan pernyataan kueri di file ORM.XML atau dalam kode sesuai dengan spesifikasi JPA. Satu -satunya hal yang perlu mereka lakukan adalah memenuhi aturan penamaan "domainclass.methodname ()" saat menamai pernyataan itu.
Menulis Antarmuka:
antarmuka publik findUserByNamedQueryRepository memperluas jParepository <user, integer> {user findUserWithName (@param ("name") string name); } Menulis kelas:
@Entity @NamedQuery (value = {@NamedQuery (name = "user.findUserWithname", query = "pilih u dari user u where u.name =: name")}) // Catatan: Jika ada beberapa metode di sini, Anda perlu menggunakan @NamedQuery. Jika hanya ada satu metode, Anda dapat menggunakan @NamedQuery. The writing method is as follows: @NamedQuery(name="User.findUserWithName",query="select u from User u where u.name = :name") public class FindUserByNamedQuery { /** * Note: This entity class must be defined here, otherwise an exception will be reported*/ @Id @GeneratedValue private Integer id; } Catatan: Bagian -bagian yang ditandai merah dalam artikel perlu sesuai satu per satu, jika tidak mereka tidak akan memenuhi spesifikasi JPA.
Kelas Tes:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-config.xml" }) @TransactionConfiguration(defaultRollback = false) @Transactional public class FindUserByNamedQueryRepositoryTest { @Autowired private FindUserByNamedQueryRepository dao; @Test public void testFindUserByName () {user user = dao.finduserWithname ("caican"); System.out.println (json.tojsonstring (pengguna)); }} 3. Buat kueri dengan menganalisis nama metode
Seperti namanya, itu adalah membuat kueri berdasarkan nama metode. Mungkin kedengarannya luar biasa pada awalnya, tetapi setelah pengujian, saya menemukan bahwa semuanya mungkin.
Menulis Antarmuka:
Antarmuka publik SimpleConditionQueryRepository memperluas jParepository <user, integer> { /*** Deskripsi: Menurut aturan yang ditentukan oleh data pegas, metode kueri dimulai dengan Find | Read | Get* ketika datang ke kueri bersyarat, sifat -sifat kondisi tersebut terhubung dengan kata kunci bersyarat. Perlu dicatat bahwa: Surat pertama dari atribut bersyarat harus huruf besar* / / *** CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih U dari pengguna u di mana u.name =: nama dan u.email =: Parameter Paramet adalah huruf besar dalam nama awal yang harus diinterogasi dengan namanya adalah Uppercase, dan Paramet Paramet adalah Parameter adalah Huruf Interm dari Interm Name. Daftar*/ pengguna findByNeAndemail (nama string, email string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari user u di mana u.name =? 1 atau u.password =? 2 */ daftar <user> findByNameorPassword (nama string, kata sandi string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id antara? 1 dan? 2 */ Daftar <User> findByIdbetween (integer start, integer end); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id antara? 1 dan? 2 */ Daftar <User> findByIdbetween (integer start, integer end); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id <? 1 */ daftar <user> findbyidlessthan (integer end); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id>? 1 */ Daftar <User> findByidgreaterThan (integer start); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari user u di mana u.name null */ list <user> findBynameisnull (); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.name tidak null */ daftar <User> findByNameIsnotnull (); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.name seperti? 1 */ Daftar <User> findBynamelike (nama string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.name tidak seperti? 1 */ Daftar <User> findBynamenot like (nama string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari user u di mana u.password =? 1 pesanan oleh u.id desc */ daftar <user> findBypassworderbyIddesc (kata sandi string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.name <>? 1 */ Daftar <User> findBynamenot (nama string); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id masuk? 1 */ Daftar <User> findbyidin (Daftar <Integer> id); / ** * CATATAN: Antarmuka ini di sini setara dengan mengirim SQL: Pilih u dari pengguna u di mana u.id tidak masuk? 1 */ Daftar <User> findByIdnotin (Daftar <Integer> id); } Kelas Uji (Bagian Komentar adalah pernyataan SQL yang dikirim):
@Runwith (springjunit4classrunner.class) @contextConfiguration (locations = {"classpath: applicationContext-config.xml"}) @transactionconfiguration (defaultrollback = false) @transactional Public Class SimpleConditionyQueryrepositorytest {false) /*** Pilih user0_.id sebagai ID0_, user0_.account as Account0_, user0_.email sebagai email0_, user0_.name as name0_, user0_.password sebagai kata sandi0_ dari user user0_ di mana user0_.name =? dan user0_.email =? membatasi ? */ @Test public void testFindUserbyNeAndemail () {user user = dao.findbynameandemail ("chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password sebagai kata sandi1_ dari user user0_ di mana user0_.name =? atau user0_.password =? */ @Test public void testFindUserbyNameorPassword () {list <user> user = dao.findbynameorpassword ("chhliu", "123456"); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name sebagai name1_, user0_.password sebagai kata sandi1_ dari user user0_ di mana user0_.id antar? Dan ? */ @Test public void testFindByIdBetween () {list <user> user = dao.findbyidBetween (5, 8); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password sebagai kata sandi1_ dari user user0_ di mana user0_.id <? */ @Test public void testFindByIdlessThan () {list <user> user = dao.findbyidlessthan (4); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai ID0_, user0_.account as account0_, user0_.email as email0_, user0_.name sebagai name0_, user0_.password sebagai kata sandi0_ dari pengguna pengguna0_ di mana user0_.id>? */ @Test public void testfindbyidgreaterThan () {list <user> user = dao.findbyidgreaterthan (6); System.out.println (json.tojsonstring (pengguna)); } /** * select user0_.id as id0_, user0_.account as account0_, user0_.email as email0_, user0_.name as name0_, user0_.password as password0_ from USER user0_ where user0_.name is null */ @Test public void testFindByNameIsNull(){ List<User> users = dao.findByNameIsNull(); System.out.println (json.tojsonstring (pengguna)); } /** * select user0_.id as id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password as password1_ from USER user0_ where user0_.name is not null */ @Test public void testFindByNameIsNotNull(){ List<User> users = dao.findbynameisnotnull (); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password sebagai kata sandi1_ dari user user0_ di mana user0_.name seperti? */ @Test public void testfindbynamelike () {list <user> user = dao.findbynamelike ("chhliu"); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id0_, user0_.account as account0_, user0_.email as email0_, user0_.name as name0_, user0_.password sebagai kata sandi0_ dari pengguna user0_ di mana user0_.name tidak seperti? */ @Test public void testfindbynamenot like () {list <user> user = dao.findbynamenot like ("chhliu"); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai ID0_, user0_.account as account0_, user0_.email as email0_, user0_.name as name0_, user0_.password sebagai kata sandi0_ dari user user0_ di mana user0_.password =? Pesan oleh user0_.id desc */ @test public void testFindByPasswordOrdyIddesc () {list <user> user = dao.findbypassworderbyiddesc ("123456"); System.out.println (json.tojsonstring (pengguna)); } /*** Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password sebagai kata sandi1_ dari user user0_ di mana user0_.name <>? */ @Test public void testfindbynamenot () {list <user> user = dao.findbynamenot ("chhliu"); System.out.println (json.tojsonstring (pengguna)); } / ** * Pilih user0_.id sebagai id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password sebagai kata sandi1_ dari pengguna pengguna0_ di mana pengguna0_.id di (?,?,?) ArrayList <Integer> (arrays.aslist (3,4,6,8))); System.out.println (json.tojsonstring (pengguna)); } / ** * Pilih user0_.id as ID0_, user0_.account as account0_, user0_.email as email0_, user0_.name as name0_, user0_.password sebagai kata sandi0_ dari userser0_ di mana user0_.id tidak di (?,?,?) dao.findbyidnotin (arraylist baru <Integer> (arrays.aslist (3, 4, 6, 8)))); System.out.println (json.tojsonstring (pengguna)); }} Di sini, kami hanya mendefinisikan satu antarmuka. Hanya ada metode dalam antarmuka, tetapi tidak ada implementasi, tetapi berbagai operasi diselesaikan.
Setelah melihat ini, banyak orang mungkin akan bertanya, bagaimana data musim semi JPA melakukannya? Ternyata ketika kerangka kerja menganalisis nama metode, pertama -tama akan mencegat awalan berlebih dari nama metode, seperti Find, Findby, Read, Readby, Get, Getby, dan kemudian menguraikan bagian yang tersisa. Dan jika parameter terakhir dari metode ini adalah jenis atau tipe yang bisa di -halaman, informasi yang relevan juga akan diekstraksi untuk penyortiran atau kueri pagination berdasarkan aturan. Saat membuat kueri, kami mengekspresikannya dengan menggunakan nama atribut dalam nama metode, seperti findbyidin (). Ketika kerangka kerja mem -parsing metode ini, pertama -tama menghilangkan Findby dan kemudian menguraikan atribut yang tersisa.
Saat meminta, biasanya perlu untuk meminta berdasarkan beberapa atribut pada saat yang sama, dan kondisi kueri juga memiliki format yang berbeda (lebih besar dari nilai tertentu, dalam kisaran tertentu, dll.). Data pegas JPA menyediakan beberapa kata kunci untuk mengekspresikan kueri bersyarat, secara kasar sebagai berikut:
Dan --- setara dengan dan kata kunci di SQL, seperti findByUserNeMandPassword (Pengguna String, Striang PWD)
Atau --- setara dengan atau kata kunci di SQL, seperti FindByUserNameorAddress (String User, String Addr)
Antara --- antara kata kunci yang setara dengan SQL, seperti FindBysalaryBetween (int max, int min)
Lessthan --- setara dengan "<" dalam SQL, seperti FindBysalarylessthan (int max)
GreaterThan --- setara dengan ">" di SQL, seperti FindBysalaryyGreatreThan (int min)
Isnull --- setara dengan "adalah null" di SQL, seperti findbyusernameisnull ()
IsNotnull --- setara dengan "bukan nol" di SQL, seperti findbyusernameisnotnull ()
Notnull --- setara dengan isNotnull
Like --- setara dengan "seperti" di SQL, seperti FindByUserNamelike (Pengguna String)
Tidak seperti --- setara dengan "tidak suka" di SQL, seperti findbyusernamenot (pengguna string)
Orderby ---- setara dengan "memesan dengan" di SQL, seperti findByUserNameOrderbyararyasc (Pengguna String)
Tidak --- setara dengan "! =" Dalam SQL, misalnya, findByUserNamenot (Pengguna String)
Dalam --- setara dengan "dalam" di SQL, seperti FindByUserNamein (Collection <string> userList). Parameter metode ini dapat dari jenis pengumpulan, atau array atau parameter panjang tidak terbatas.
Notin --- setara dengan "tidak di" di SQL, seperti findByUserNamenotin (collection <string> userList). Parameter metode ini dapat dari jenis pengumpulan, atau array atau parameter panjang tidak terbatas.
5. Urutan membuat pertanyaan
Saat membuat objek proxy untuk antarmuka, jika menemukan bahwa kelipatan dari situasi di atas tersedia pada saat yang sama, strategi mana yang harus diadopsi terlebih dahulu? Untuk melakukan ini, <JPA: Repositories> menyediakan properti query-lookup-strategy untuk menentukan urutan pencarian. Ini memiliki tiga nilai berikut:
Buat --- Buat kueri dengan menyelesaikan nama metode. Bahkan jika ada kueri bernama yang cocok, atau pernyataan kueri yang ditentukan oleh metode ini melalui @Query, itu akan diabaikan.
create-if-not-found --- Jika metode ini menentukan pernyataan kueri melalui @Query, kueri diimplementasikan; Jika tidak, ditemukan apakah kueri bernama yang memenuhi kriteria didefinisikan, jika ditemukan, kueri bernama digunakan; Jika tidak ada yang ditemukan, kueri dibuat dengan parsing nama metode. 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. Mengapa ini?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.