Data pegas jpa

Dalam artikel ini saya akan menjelaskan penggunaan Data Musim Semi.

Spring Data adalah mekanisme tambahan yang nyaman untuk berinteraksi dengan entitas basis data, mengaturnya dalam repositori, mengambil data, mengubah, dalam beberapa kasus, untuk ini akan cukup untuk mendeklarasikan antarmuka dan metode di dalamnya, tanpa implementasi.

Konten:

  1. Repositori musim semi
  2. Metode Permintaan dari Nama Metode
  3. Konfigurasi dan pengaturan
  4. Pemrosesan parameter khusus
  5. Implementasi Repositori Kustom
  6. Repositori Basis Kustom
  7. Metode Permintaan - Permintaan


1. Spring Repository


Konsep dasar dalam Spring Data adalah repositori. Ini adalah beberapa antarmuka yang menggunakan JPA Entity untuk berinteraksi dengannya. Jadi misalnya sebuah antarmuka
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID>
menyediakan operasi dasar untuk mencari, menyimpan, menghapus data (operasi CRUD)

 T save(T entity); Optional findById(ID primaryKey); void delete(T entity); 

dan operasi lainnya.

Ada abstraksi lain, seperti PagingAndSortingRepository.

Yaitu jika daftar yang disediakan antarmuka cukup untuk berinteraksi dengan entitas, maka Anda dapat langsung memperluas antarmuka dasar untuk entitas Anda, menambahnya dengan metode kueri Anda dan melakukan operasi. Sekarang saya akan menunjukkan secara singkat langkah-langkah yang diperlukan untuk kasus paling sederhana (tanpa terganggu sejauh ini oleh konfigurasi, ORM, database).

1. Buat entitas

 @Entity @Table(name = "EMPLOYEES") public class Employees { private Long employeeId; private String firstName; private String lastName; private String email; // . . . 

2. Diwarisi dari salah satu antarmuka Spring Data, misalnya dari CrudRepository

 @Repository public interface CustomizedEmployeesCrudRepository extends CrudRepository<Employees, Long> 

3. Gunakan di klien (layanan) antarmuka baru untuk operasi data

 @Service public class EmployeesDataService { @Autowired private CustomizedEmployeesCrudRepository employeesCrudRepository; @Transactional public void testEmployeesCrudRepository() { Optional<Employees> employeesOptional = employeesCrudRepository.findById(127L); //.... } 

Di sini saya menggunakan metode findById yang sudah jadi. Yaitu begitu cepat dan mudah, tanpa implementasi, kami mendapatkan daftar operasi yang sudah jadi dari CrudRepository:

  S save(S var1); Iterable<S> saveAll(Iterable<S> var1); Optional<T> findById(ID var1); boolean existsById(ID var1); Iterable<T> findAll(); Iterable<T> findAllById(Iterable<ID> var1); long count(); void deleteById(ID var1); void delete(T var1); void deleteAll(Iterable<? extends T> var1); void deleteAll(); 

Jelas bahwa daftar ini kemungkinan besar tidak cukup untuk berinteraksi dengan entitas, dan di sini Anda dapat memperluas antarmuka Anda dengan metode kueri tambahan.

2. Metode kueri dari nama metode


Permintaan kepada entitas dapat dibangun langsung dari nama metode. Untuk melakukan ini, cari ... Dengan, baca ... Dengan, kueri ... Dengan, hitung ... Dengan, dan dapatkan ... Dengan awalan yang digunakan, lebih jauh dari awalan metode, ia mulai menguraikan sisanya. Kalimat pengantar dapat berisi ekspresi tambahan, misalnya, Distinct. Selanjutnya, By pertama bertindak sebagai pembatas untuk menunjukkan awal kriteria aktual. Anda dapat menentukan kondisi untuk properti entitas dan menggabungkannya menggunakan Dan dan Atau. Contohnya

 @Repository public interface CustomizedEmployeesCrudRepository extends CrudRepository<Employees, Long> { //    firstName And LastName Optional<Employees> findByFirstNameAndLastName(String firstName, String lastName); //   5  FirstName       FirstName List<Employees> findFirst5ByFirstNameStartsWithOrderByFirstName(String firstNameStartsWith); 

Dokumentasi mendefinisikan seluruh daftar dan aturan untuk menulis metode. Hasilnya dapat berupa entitas T, Opsional, Daftar, Aliran. Di lingkungan pengembangan, seperti Ide, ada petunjuk untuk menulis metode kueri.

gambar
Cukup mendefinisikan metode dengan cara ini, tanpa implementasi, dan Spring akan menyiapkan permintaan untuk entitas.

 @SpringBootTest public class DemoSpringDataApplicationTests { @Autowired private CustomizedEmployeesCrudRepository employeesCrudRepository; @Test @Transactional public void testFindByFirstNameAndLastName() { Optional<Employees> employeesOptional = employeesCrudRepository.findByFirstNameAndLastName("Alex", "Ivanov"); 

3. Konfigurasi dan pengaturan


Seluruh proyek tersedia di github
github DemoSpringData

Di sini saya hanya akan menyentuh beberapa fitur.

TransactionManager, dataSource, dan kacang entitasManagerFactory didefinisikan dalam context.xml. Penting untuk menunjukkan di dalamnya juga

 <jpa:repositories base-package="com.example.demoSpringData.repositories"/> 

jalur tempat repositori didefinisikan.

EntityManagerFactory dikonfigurasikan untuk bekerja dengan Hibernate ORM, dan, pada gilirannya, adalah dengan database Oracle XE, di sini opsi lain dimungkinkan, dalam context.xml semua ini terlihat. File pom memiliki semua dependensi.

4. Pemrosesan parameter khusus


Dalam metode kueri, dalam parameternya, Anda dapat menggunakan parameter khusus Pageable, Sortir, serta pembatasan Top dan First.

Misalnya, seperti ini, Anda dapat mengambil halaman kedua (indeks dengan -0), ukuran tiga elemen dan disortir berdasarkan firstName, setelah menentukan parameter Pageable dalam metode repositori, kriteria dari nama metode juga akan digunakan - β€œCari dengan FirstName dimulai dengan%β€ž

 @Repository public interface CustomizedEmployeesCrudRepository extends CrudRepository<Employees, Long> { List<Employees> findByFirstNameStartsWith(String firstNameStartsWith, Pageable page); //.... } //   @Test @Transactional public void testFindByFirstNameStartsWithOrderByFirstNamePage() { List<Employees> list = employeesCrudRepository .findByFirstNameStartsWith("A", PageRequest.of(1,3, Sort.by("firstName"))); list.forEach(e -> System.out.println(e.getFirstName() + " " +e.getLastName())); } 

5. Implementasi kustom untuk repositori


Misalkan Anda memerlukan metode dalam repositori yang tidak dapat dijelaskan dengan nama metode, maka Anda bisa menerapkannya menggunakan antarmuka Anda sendiri dan kelas implementasinya. Dalam contoh di bawah ini, saya akan menambahkan ke repositori metode untuk mendapatkan karyawan dengan gaji maksimum.

Deklarasikan Antarmuka

 public interface CustomizedEmployees<T> { List<T> getEmployeesMaxSalary(); } 

Menerapkan antarmuka. Menggunakan HQL (SQL) saya mendapatkan karyawan dengan gaji maksimum, implementasi lain dimungkinkan.

 public class CustomizedEmployeesImpl implements CustomizedEmployees { @PersistenceContext private EntityManager em; @Override public List getEmployeesMaxSalary() { return em.createQuery("from Employees where salary = (select max(salary) from Employees )", Employees.class) .getResultList(); } } 

Dan juga memperluas Crud Repository Pegawai dengan CustomizedEmployees.

 @Repository public interface CustomizedEmployeesCrudRepository extends CrudRepository<Employees, Long>, CustomizedEmployees<Employees> 

Ada satu fitur penting di sini. Antarmuka implementasi kelas harus diakhiri (postfix) pada Impl , atau dalam konfigurasi Anda perlu meletakkan postfix Anda

 <repositories base-package="com.repository" repository-impl-postfix="MyPostfix" /> 

Memeriksa pengoperasian metode ini melalui repositori

 public class DemoSpringDataApplicationTests { @Autowired private CustomizedEmployeesCrudRepository employeesCrudRepository; @Test @Transactional public void testMaxSalaryEmployees() { List<Employees> employees = employeesCrudRepository.getEmployeesMaxSalary(); employees.stream() .forEach(e -> System.out.println(e.getFirstName() + " " + e.getLastName() + " " + e.getSalary())); } 

Lain halnya ketika perlu untuk mengubah perilaku metode yang ada di antarmuka Spring, misalnya, hapus di CrudRepository, saya perlu bahwa alih-alih menghapus dari database, tanda penghapusan akan ditetapkan. Tekniknya persis sama. Di bawah ini adalah contohnya:

 public interface CustomizedEmployees<T> { void delete(T entity); // ... } //  CustomizedEmployees public class CustomizedEmployeesImpl implements CustomizedEmployees { @PersistenceContext private EntityManager em; @Transactional @Override public void delete(Object entity) { Employees employees = (Employees) entity; employees.setDeleted(true); em.persist(employees); } 

Sekarang, jika Anda memanggil delete di employeeCrudRepository, objek hanya akan ditandai sebagai dihapus.

6. Repositori Basis Pengguna


Pada contoh sebelumnya, saya menunjukkan cara mendefinisikan ulang repositori penghapusan suatu entitas di Crud, tetapi jika Anda perlu melakukan ini untuk semua entitas proyek, buat antarmuka Anda sendiri tidak begitu bagus untuk masing-masing ... maka dalam data Spring Anda dapat mengonfigurasi repositori dasar Anda. Untuk melakukan ini:
Antarmuka dideklarasikan dan di dalamnya metode untuk mengganti (atau umum untuk semua entitas proyek). Di sini, untuk semua entitas saya, saya memperkenalkan antarmuka BaseEntity saya (ini tidak perlu), untuk kenyamanan memanggil metode umum, metodenya bertepatan dengan metode entitas.

 public interface BaseEntity { Boolean getDeleted(); void setDeleted(Boolean deleted); } //  Employees @Entity @Table(name = "EMPLOYEES") public class Employees implements BaseEntity { private Boolean deleted; @Override public Boolean getDeleted() { return deleted; } @Override public void setDeleted(Boolean deleted) { this.deleted = deleted; } //    @NoRepositoryBean public interface BaseRepository <T extends BaseEntity, ID extends Serializable> extends JpaRepository<T, ID> { void delete(T entity); } //    BaseRepository public class BaseRepositoryImpl <T extends BaseEntity, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> { private final EntityManager entityManager; public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) { super(entityInformation, entityManager); this.entityManager = entityManager; } @Transactional @Override public void delete(BaseEntity entity) { entity.setDeleted(true); entityManager.persist(entity); } } 

Dalam konfigurasi, Anda perlu menentukan repositori dasar ini, itu akan umum untuk semua repositori proyek

  <jpa:repositories base-package="com.example.demoSpringData.repositories" base-class="com.example.demoSpringData.BaseRepositoryImpl"/> 

Sekarang Repositori Karyawan (dan lainnya) harus diperluas dari BaseRepository dan sudah menggunakannya di klien.

 public interface EmployeesBaseRepository extends BaseRepository <Employees, Long> { // ... } 

Memeriksa GudangBaseRepository

 public class DemoSpringDataApplicationTests { @Resource private EmployeesBaseRepository employeesBaseRepository; @Test @Transactional @Commit public void testBaseRepository() { Employees employees = new Employees(); employees.setLastName("Ivanov"); // Query by Example (QBE) Example<Employees> example = Example.of(employees); Optional<Employees> employeesOptional = employeesBaseRepository.findOne(example); employeesOptional.ifPresent(employeesBaseRepository::delete); } 

Sekarang, seperti sebelumnya, objek akan ditandai sebagai dihapus, dan ini akan dilakukan untuk semua entitas yang memperluas antarmuka BaseRepository. Dalam contoh, metode pencarian - Query by Example (QBE) diterapkan, saya tidak akan menjelaskannya di sini, contohnya menunjukkan apa yang dikerjakannya, sederhana dan nyaman.

7. Metode Permintaan - Permintaan


Sebelumnya, saya menulis bahwa jika Anda memerlukan metode tertentu atau implementasinya, yang tidak dapat dijelaskan menggunakan nama metode, maka ini dapat dilakukan melalui beberapa antarmuka yang Disesuaikan (CustomizedEmp Karyawan) dan membuat implementasi perhitungan. Dan Anda bisa pergi ke arah lain, dengan menunjukkan kueri (HQL atau SQL), cara menghitung fungsi ini.
Sebagai contoh saya dengan getEmployeesMaxSalary, opsi implementasi ini bahkan lebih sederhana. Saya akan memperumitnya dengan parameter input gaji. Yaitu itu cukup untuk mendeklarasikan metode perhitungan dan permintaan di antarmuka.

 @Repository public interface CustomizedEmployeesCrudRepository extends CrudRepository<Employees, Long>, CustomizedEmployees<Employees> { @Query("select e from Employees e where e.salary > :salary") List<Employees> findEmployeesWithMoreThanSalary(@Param("salary") Long salary, Sort sort); // ... } 

Memeriksa

 @Test @Transactional public void testFindEmployeesWithMoreThanSalary() { List<Employees> employees = employeesCrudRepository.findEmployeesWithMoreThanSalary(10000L, Sort.by("lastName")); 

Saya hanya akan menyebutkan bahwa mungkin ada modifikasi permintaan, untuk ini tambahan anotasi @Modifikasi ditambahkan ke dalamnya

 @Modifying @Query("update Employees e set e.firstName = ?1 where e.employeeId = ?2") int setFirstnameFor(String firstName, String employeeId); 

Fitur hebat lainnya dari anotasi Query adalah penggantian jenis entitas domain ke dalam kueri menggunakan templat # {# entitasName} , melalui ekspresi SpEL.

Jadi, misalnya, dalam contoh hipotetis saya, ketika saya perlu memiliki tanda "dihapus" untuk semua entitas, saya akan membuat antarmuka dasar dengan metode memperoleh daftar objek dengan tanda "dihapus" atau "aktif"

 @NoRepositoryBean public interface ParentEntityRepository<T> extends Repository<T, Long> { @Query("select t from #{#entityName} t where t.deleted = ?1") List<T> findMarked(Boolean deleted); } 

Lebih lanjut, semua repositori untuk entitas dapat diperluas darinya. Antarmuka yang bukan repositori, tetapi terletak di folder konfigurasi "paket-dasar", anotasi @NoRepositoryBean.

Repositori Karyawan

 @Repository public interface EmployeesEntityRepository extends ParentEntityRepository <Employees> { } 

Sekarang, ketika permintaan dieksekusi, nama entitas T akan diganti ke dalam badan permintaan untuk repositori tertentu yang akan memperpanjang ParentEntityRepository, dalam hal ini Karyawan.

Periksa

 @SpringBootTest public class DemoSpringDataApplicationTests { @Autowired private EmployeesEntityRepository employeesEntityRepository; @Test @Transactional public void testEntityName() { List<Employees> employeesMarked = employeesEntityRepository.findMarked(true); // ... 

Material
Spring Data JPA - Dokumentasi Referensi
Proyek di github .

Source: https://habr.com/ru/post/id435114/


All Articles