Panduan Pantas untuk Memuatkan Data Awal dengan Spring Boot

1. Gambaran keseluruhan

Spring Boot menjadikannya sangat mudah untuk menguruskan perubahan pangkalan data kami dengan cara yang mudah. Sekiranya kita meninggalkan konfigurasi lalai, ia akan mencari entiti dalam pakej kita dan membuat jadual masing-masing secara automatik.

Tetapi kadang-kadang kita memerlukan kawalan yang lebih baik terhadap perubahan pangkalan data. Bahawa apabila kita boleh menggunakan data.sql dan schema.sql fail dalam Spring.

2. Fail data.sql

Mari kita membuat andaian di sini bahawa kita bekerjasama dengan JPA - dan tentukan entiti Negara sederhana dalam projek kami:

@Entity public class Country { @Id @GeneratedValue(strategy = IDENTITY) private Integer id; @Column(nullable = false) private String name; //... }

Sekiranya kami menjalankan aplikasi kami, Spring Boot akan membuat jadual kosong untuk kami, tetapi tidak akan mengisi apa-apa.

Cara mudah untuk melakukannya adalah dengan membuat fail bernama data.sql:

INSERT INTO country (name) VALUES ('India'); INSERT INTO country (name) VALUES ('Brazil'); INSERT INTO country (name) VALUES ('USA'); INSERT INTO country (name) VALUES ('Italy');

Apabila kita menjalankan projek dengan fail ini di classpath, Spring akan mengambilnya dan menggunakannya untuk mengisi pangkalan data.

3. Fail schema.sql

Kadang-kadang, kita tidak mahu bergantung pada mekanisme pembuatan skema lalai. Dalam kes sedemikian, kita dapat membuat fail schema.sql tersuai :

CREATE TABLE country ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(128) NOT NULL, PRIMARY KEY (id) );

Spring akan mengambil fail ini dan menggunakannya untuk membuat skema.

Penting juga untuk diingat untuk mematikan pembuatan skema automatik untuk mengelakkan konflik:

spring.jpa.hibernate.ddl-auto=none

4. Mengawal Pembuatan Pangkalan Data Menggunakan Hibernate

Spring menyediakan harta khusus JPA yang Hibernate gunakan untuk generasi DDL: spring.jpa.hibernate.ddl-auto .

Nilai harta tanah Hibernate standard adalah: buat , kemas kini , buat-jatuhkan , sahkan dan tidak ada :

  • create - Hibernate terlebih dahulu menjatuhkan jadual yang ada, kemudian membuat jadual baru
  • kemas kini - model objek yang dibuat berdasarkan pemetaan (anotasi atau XML) dibandingkan dengan skema yang ada, dan kemudian Hibernate mengemas kini skema mengikut perbezaan. Ia tidak akan menghapus jadual atau lajur yang ada walaupun tidak diperlukan lagi oleh aplikasi
  • create-drop - serupa dengan create , dengan penambahan bahawa Hibernate akan menjatuhkan pangkalan data setelah semua operasi selesai. Biasanya digunakan untuk ujian unit
  • validate - Hibernate hanya mengesahkan sama ada jadual dan lajur ada, jika tidak, ia memberikan pengecualian
  • tiada - nilai ini mematikan generasi DDL dengan berkesan

Spring Boot secara lalai menetapkan nilai parameter ini untuk membuat-drop jika tidak ada pengurus skema yang dikesan, jika tidak ada untuk semua kes lain.

Kita harus menetapkan nilainya dengan berhati-hati atau menggunakan salah satu mekanisme lain untuk memulakan pangkalan data.

5. @Sql

Spring juga menyediakan anotasi @Sql - cara deklaratif untuk memulakan dan mengisi skema ujian kami.

Mari lihat bagaimana menggunakan anotasi @Sql untuk membuat jadual baru dan juga memuatkan jadual dengan data awal untuk ujian integrasi kami:

@Sql({"/employees_schema.sql", "/import_employees.sql"}) public class SpringBootInitialLoadIntegrationTest { @Autowired private EmployeeRepository employeeRepository; @Test public void testLoadDataForTestClass() { assertEquals(3, employeeRepository.findAll().size()); } }

Atribut anotasi @Sql adalah:

  • config - konfigurasi tempatan untuk skrip SQL. Kami menerangkannya secara terperinci di bahagian seterusnya
  • eksekusiFasa - kita juga dapat menentukan kapan untuk melaksanakan skrip, sama ada BEFORE_TEST_METHOD atau AFTER_TEST_METHOD
  • pernyataan - kita boleh menyatakan pernyataan SQL sebaris untuk dilaksanakan
  • skrip - kita dapat menyatakan jalan ke fail skrip SQL untuk dilaksanakan. Ini adalah alias untuk atribut nilai

The @Sql anotasi boleh digunakan di peringkat kelas atau tahap kaedah . Kami dapat memuatkan data tambahan yang diperlukan untuk kes ujian tertentu dengan memberi penjelasan mengenai kaedah tersebut:

@Test @Sql({"/import_senior_employees.sql"}) public void testLoadDataForTestCase() { assertEquals(5, employeeRepository.findAll().size()); }
6. @SqlConfig

Kami dapat mengkonfigurasi cara kami menguraikan dan menjalankan skrip SQL dengan menggunakan anotasi @SqlConfig .

@SqlConfig dapat dinyatakan di peringkat kelas, di mana ia berfungsi sebagai konfigurasi global. Atau boleh digunakan untuk mengkonfigurasi anotasi @Sql tertentu .

Mari kita lihat contoh di mana kita menentukan pengekodan skrip SQL kita serta mod transaksi untuk melaksanakan skrip:

@Test @Sql(scripts = {"/import_senior_employees.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED)) public void testLoadDataForTestCase() { assertEquals(5, employeeRepository.findAll().size()); }

Dan mari kita lihat pelbagai sifat @SqlConfig :

  • blockCommentStartDelimiter - pembatas untuk mengenal pasti permulaan komen blok dalam fail skrip SQL
  • blockCommentEndDelimiter - pembatas untuk menunjukkan akhir komen blok dalam fail skrip SQL
  • commentPrefix - awalan untuk mengenal pasti komen satu baris dalam fail skrip SQL
  • dataSource - nama kacang javax.sql.DataSource yang akan digunakan skrip dan pernyataan
  • pengekodan - pengekodan untuk fail skrip SQL, lalai adalah pengekodan platform
  • errorMode - mod yang akan digunakan ketika ralat ditemui semasa menjalankan skrip
  • pemisah - tali yang digunakan untuk memisahkan pernyataan individu, lalai adalah "-"
  • transaksiManager - nama kacang PlatformTransactionManager yang akan digunakan untuk transaksi
  • transaksiMode - mod yang akan digunakan ketika menjalankan skrip dalam transaksi

7. @SqlGroup

Java 8 and above allow the use of repeated annotations. This feature can be utilized for @Sql annotations as well. For Java 7 and below, there is a container annotation — @SqlGroup. Using the @SqlGroup annotation, we can declare multiple @Sql annotations:

@SqlGroup({ @Sql(scripts = "/employees_schema.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)), @Sql("/import_employees.sql")}) public class SpringBootSqlGroupAnnotationIntegrationTest { @Autowired private EmployeeRepository employeeRepository; @Test public void testLoadDataForTestCase() { assertEquals(3, employeeRepository.findAll().size()); } }

8. Conclusion

In this quick article, we saw how we can leverage schema.sql and data.sql files for setting up an initial schema and populating it with data. We also saw how we can use @Sql, @SqlConfig, and @SqlGroup annotations to load test data for tests.

Perlu diingat bahawa pendekatan ini lebih sesuai untuk senario asas dan sederhana, setiap pengendalian pangkalan data lanjutan memerlukan perkakas yang lebih maju dan halus seperti Liquibase atau Flyway.

Coretan kod, seperti biasa, terdapat di GitHub.