Пакет org.springframework.jdbc.datasource.embedded
забезпечує підтримку вбудованих підсистем зберігання
на Java. Підтримка HSQL, H2 та Derby забезпечується нативно. Також можна
використовувати розширюваний API-інтерфейс для підключення нових вбудованих типів баз даних та реалізацій DataSource
.
Навіщо використовувати вбудовану базу даних?
Вбудована база даних може бути корисна на етапі розробки проєкту завдяки своїй спрощеності. Серед переваг — простота налаштування, швидкий час запуску, тестованість і можливість швидкого доопрацювання SQL у процесі розробки.
Створення вбудованої бази даних за допомогою Spring XML
Якщо вам потрібно подати екземпляр вбудованої бази даних як бін у ApplicationContext
у Spring, можна
використовувати тег embedded-database
у просторі імен spring-jdbc
:
<jdbc:embedded-database id="dataSource" generate-name ="true">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
Попередня конфігурація створює вбудовану базу даних HSQL, яка заповнюється SQL з ресурсів
schema.sql
і test-data.sql
в корені classpath. До того ж, як оптимальний метод роботи
вбудованій базі даних дається унікальне ім'я. Вбудована база даних стає доступною для контейнера Spring як бін
типу javax.sql.DataSource
, який потім можна впроваджувати до об'єктів доступу до даних у разі
необхідності.
Створення вбудованої бази даних програмним способом
Клас EmbeddedDatabaseBuilder
надає
вільний API-інтерфейс для створення вбудованої бази даних програмним шляхом. Це можна використовувати, якщо потрібно
створити вбудовану базу даних в автономному оточенні або в автономному інтеграційному тесті, як у наступному
прикладі:
EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build();
// виконуємо дії з базою даних (EmbeddedDatabase розширює javax.sql.DataSource) db.shutdown()
db.shutdown()
val db = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build()
// виконуємо дії з базою даних (EmbeddedDatabase розширює javax.sql.DataSource)
db.shutdown()
Див. javadoc EmbeddedDatabaseBuilder
для отримання більш детальної інформації про
всі опції, що підтримуються.
Також можна використовувати EmbeddedDatabaseBuilder
для створення вбудованої бази даних за допомогою
конфігурації Java, як показано в наступному прикладі:
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build();
}
}
@Configuration
class DataSourceConfig {
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build()
}
}
Вибір типу вбудованої бази даних
У цьому розділі розповідається про те, як обрати одну з трьох вбудованих баз даних, що підтримує Spring. Розділ включає наступні теми:
Використання HSQL
Використання H2
Використання Derby
Використання HSQL
Spring підтримує HSQL 1.8.0 і вище. HSQL є вбудованою базою даних за замовчуванням, якщо тип не зазначений явно.
Щоб явно встановити HSQL, встанови для атрибуту type
тега embedded-database
значення
HSQL
. Якщо ти використовуєш API-інтерфейс системи збірки, виклич метод setType(EmbeddedDatabaseType)
з параметром EmbeddedDatabaseType.HSQL
.
Використання H2
Spring підтримує базу даних H2. Щоб активувати H2, встанови для атрибуту type
тега embedded-database
значення
H2
. Якщо ти використовуєш API-інтерфейс засобу збирання, виклич метод setType(EmbeddedDatabaseType)
із параметром EmbeddedDatabaseType.H2
.
Використання Derby
Spring підтримує Apache Derby 10.5 і вище. Щоб активувати Derby, встанови для атрибуту type
тега embedded-database
значення DERBY
. Якщо ти використовуєш API-інтерфейс засобу збирання, виклич метод setType(EmbeddedDatabaseType)
із параметром EmbeddedDatabaseType.DERBY
.
Тестування логіки доступу до даних із використанням вбудованої бази даних
Вбудовані бази даних забезпечують легкий спосіб тестування коду
для отримання вибірки даних. Наступний приклад — шаблон інтеграційного тесту доступу до даних, у якому
використовується вбудована база даних. Використання такого шаблону може бути корисним для разових випадків, якщо
вбудовану базу даних не потрібно повторно використовувати у всіх тестових класах. Однак, якщо потрібно створити
вбудовану базу даних, яка буде використовуватися спільно в тестовому комплекті, використовуй Spring TestContext Framework
та налаштуй вбудовану базу даних як бін у ApplicationContext
з Spring, як це описано вище. У
наступному лістингу показаний тестовий шаблон:
public class DataAccessIntegrationTestTemplate {
private EmbeddedDatabase db;
@BeforeEach
public void setUp() {
// створює резидентну (зі зберіганням в оперативній пам'яті) базу даних HSQL, заповнену стандартними скриптами
// classpath:schema.sql і classpath:data.sql
db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true )
.addDefaultScripts()
.build();
}
@Test
public void testDataAccess() {
JdbcTemplate template = new JdbcTemplate(db);
template.query( /* ... */ );
}
@AfterEach
public void tearDown() {
db.shutdown();
}
}
class DataAccessIntegrationTestTemplate {
private lateinit var db: EmbeddedDatabase
@BeforeEach
fun setUp() {
// створює резидентну (зі зберіганням в оперативній пам'яті) базу даних HSQL, заповнену стандартними скриптами
// classpath:schema.sql and classpath:data.sql
db = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.addDefaultScripts()
.build()
}
@Test
fun testDataAccess() {
val template = JdbcTemplate(db)
template.query( /* ... */)
}
@AfterEach
fun tearDown() {
db.shutdown()
}
}
Створення унікальних імен для вбудованих баз даних
Команди розробників часто стикаються з помилками під час роботи з вбудованими базами даних, якщо їх тестовий комплект
випадково намагається відтворити додаткові екземпляри однієї і тієї ж бази даних. Це досить легко може статися,
якщо файл конфігурації XML або клас з анотацією @Configuration
відповідає за створення вбудованої
бази даних, а відповідна конфігурація потім повторно використовується в кількох сценаріях тестування в межах
одного тестового комплекту (тобто в рамках одного процесу JVM) — наприклад, інтеграційні тести щодо вбудованих
баз даних, конфігурація ApplicationContext
яких відрізняється лише тим, які профілі визначення
бінів активні.
Першопричиною таких помилок є той факт, що фабрика EmbeddedDatabaseFactory
зі Spring
(використовується внутрішнім способом як елементом простору імен XML <jdbc:embedded-database>
,
так і конфігурацією EmbeddedDatabaseBuilder
встановлює ім'я вбудованої бази даних на
testdb
, якщо не встановлено інше. У випадку <jdbc:embedded-database>
, вбудованій
базі даних зазвичай присвоюється ім'я, що дорівнює id
біна (часто на кшталт dataSource
).
Таким чином, подальші спроби створити вбудовану базу даних не призводять до створення нової бази даних.
Натомість повторно використовується та сама URL-адреса підключення JDBC, а спроби створити нову вбудовану базу
даних фактично вказують на існуючу вбудовану базу даних, створену на основі тієї ж конфігурації.
Для вирішення цієї поширеної проблеми в Spring Framework 4.2 передбачено засоби підтримки генерації унікальних імен для вбудованих баз даних. Щоб активувати функцію використання згенерованих імен, використовуй один із наступних параметрів.
EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
EmbeddedDatabaseBuilder.generateUniqueName()
<jdbc:embedded-database generate-name="true" … >
Розширення підтримки вбудованих баз даних
Можна розширити засоби підтримки вбудованих баз даних JDBC у Spring двома способами:
Шляхом реалізації
EmbeddedDatabaseConfigurer
для забезпечення підтримки нового типу вбудованої бази даних.Шляхом реалізації
DataSourceFactory
для забезпечення підтримки нової реалізаціїDataSource
, наприклад, пула з'єднань, щоб керувати підключеннями до вбудованої бази даних.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ