INSERT Statement dalam JPA

1. Gambaran keseluruhan

Dalam tutorial ringkas ini, kita akan belajar bagaimana melakukan penyataan INSERT pada objek JPA .

Untuk maklumat lebih lanjut mengenai Hibernate secara umum, lihat panduan komprehensif kami untuk JPA dengan Spring dan pengenalan kepada Spring Data dengan JPA untuk mengetahui topik ini.

2. Objek Berterusan di JPA

Dalam JPA, setiap entiti yang bergerak dari keadaan sementara ke keadaan terurus secara automatik dikendalikan oleh EntityManager .

The EntityManager cek sama ada entiti yang diberi sudah wujud dan kemudian memutuskan jika ia perlu dimasukkan atau yang dikemas kini. Kerana pengurusan automatik ini, t dia hanya penyata dibenarkan oleh JPA adalah SELECT, UPDATE dan DELETE.

Dalam contoh di bawah, kita akan melihat pelbagai cara mengurus dan melewati batasan ini.

3. Menentukan Model Biasa

Sekarang, mari kita mulakan dengan menentukan entiti mudah yang akan kita gunakan sepanjang tutorial ini:

@Entity public class Person { @Id private Long id; private String firstName; private String lastName; // standard getters and setters, default and all-args constructors }

Juga, mari tentukan kelas repositori yang akan kami gunakan untuk pelaksanaan kami:

@Repository public class PersonInsertRepository { @PersistenceContext private EntityManager entityManager; }

Selain itu, kami akan menerapkan anotasi @Transactional untuk mengendalikan transaksi secara automatik menjelang Spring. Dengan cara ini, kita tidak perlu risau membuat transaksi dengan EntityManager, melakukan perubahan, atau melakukan rollback secara manual sekiranya terdapat pengecualian.

4. createNativeQuery

Untuk pertanyaan yang dibuat secara manual, kita boleh menggunakan kaedah EntityManager # createNativeQuery . Ini membolehkan kita membuat sebarang jenis pertanyaan SQL, bukan hanya yang disokong oleh JPA. Mari tambahkan kaedah baru ke kelas repositori kami:

@Transactional public void insertWithQuery(Person person) { entityManager.createNativeQuery("INSERT INTO person (id, first_name, last_name) VALUES (?,?,?)") .setParameter(1, person.getId()) .setParameter(2, person.getFirstName()) .setParameter(3, person.getLastName()) .executeUpdate(); }

Dengan pendekatan ini, kita perlu menentukan pertanyaan literal termasuk nama lajur dan menetapkan nilai yang sesuai.

Kami kini boleh menguji repositori kami:

@Test public void givenPersonEntity_whenInsertedTwiceWithNativeQuery_thenPersistenceExceptionExceptionIsThrown() { Person person = new Person(1L, "firstname", "lastname"); assertThatExceptionOfType(PersistenceException.class).isThrownBy(() -> { personInsertRepository.insertWithQuery(PERSON); personInsertRepository.insertWithQuery(PERSON); }); }

Dalam ujian kami, setiap operasi cuba memasukkan entri baru ke dalam pangkalan data kami. Oleh kerana kami cuba memasukkan dua entiti dengan id yang sama , operasi memasukkan kedua gagal dengan membuang PersistenceException .

Prinsip di sini adalah sama jika kita menggunakan @Query Spring Data .

5. berterusan

Dalam contoh sebelumnya, kami membuat pertanyaan sisipan, tetapi kami harus membuat pertanyaan literal untuk setiap entiti. Pendekatan ini tidak begitu cekap dan menghasilkan banyak kod plat boiler.

Sebagai gantinya, kita boleh menggunakan kaedah berterusan dari EntityManager .

Seperti contoh sebelumnya, mari kembangkan kelas repositori kami dengan kaedah tersuai:

@Transactional public void insertWithEntityManager(Person person) { this.entityManager.persist(person); }

Sekarang, kita dapat menguji pendekatan kita lagi :

@Test public void givenPersonEntity_whenInsertedTwiceWithEntityManager_thenEntityExistsExceptionIsThrown() { assertThatExceptionOfType(EntityExistsException.class).isThrownBy(() -> { personInsertRepository.insertWithEntityManager(new Person(1L, "firstname", "lastname")); personInsertRepository.insertWithEntityManager(new Person(1L, "firstname", "lastname")); }); }

Berbeza dengan menggunakan pertanyaan asli, kita tidak perlu menentukan nama lajur dan nilai yang sesuai . Sebaliknya, EntityManager mengendalikannya untuk kita.

Dalam ujian di atas, kami juga mengharapkan EntityExistsException dilemparkan dan bukannya superclass PersistenceException yang lebih khusus dan dilemparkan secara berterusan .

Sebaliknya, dalam contoh ini, kita harus memastikan bahawa kita memanggil kaedah sisipan kita setiap kali dengan contoh Orang yang baru. Jika tidak, ia akan dikendalikan oleh EntityManager, menghasilkan operasi kemas kini.

6. Kesimpulannya

Dalam artikel ini, kami menggambarkan cara melakukan operasi memasukkan pada objek JPA. Kami melihat contoh penggunaan pertanyaan asli, dan juga menggunakan EntityManager # berterusan untuk membuat penyataan INSERT tersuai.

Seperti biasa, kod lengkap yang digunakan dalam artikel ini terdapat di GitHub.