Перейти к основному содержимому

Весенняя загрузка с SQLite

· 3 мин. чтения

1. Обзор

В этом кратком руководстве мы рассмотрим шаги по использованию базы данных SQLite в приложении Spring Boot с поддержкой JPA.

Spring Boot поддерживает несколько известных баз данных в памяти из коробки, но SQLite требует от нас немного большего.

Давайте посмотрим, что для этого нужно.

2. Настройка проекта

Для нашей иллюстрации мы начнем с приложения Spring Data Rest, которое мы использовали в прошлых руководствах.

В pom нам нужно добавить зависимость sqllite-jdbc :

<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.25.2</version>
</dependency>

Эта зависимость дает нам то, что нам нужно для использования JDBC для связи с SQLite. Но если мы собираемся использовать ORM, этого недостаточно.

3. Диалект SQLite

Видите ли, Hibernate не поставляется с диалектом для SQLite . Нам нужно создать его самим.

3.1. Расширение диалекта

Наш первый шаг — расширить класс org.hibernate.dialect.Dialect для регистрации типов данных, предоставляемых SQLite:

public class SQLiteDialect extends Dialect {

public SQLiteDialect() {
registerColumnType(Types.BIT, "integer");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.INTEGER, "integer");
// other data types
}
}

Их несколько, поэтому обязательно ознакомьтесь с примером кода для остальных.

Далее нам нужно переопределить некоторые варианты поведения диалекта по умолчанию.

3.2. Поддержка столбца идентификации

Например, нам нужно сообщить Hibernate, как SQLite обрабатывает столбцы @Id , что мы можем сделать с помощью пользовательской реализации IdentityColumnSupport :

public class SQLiteIdentityColumnSupport extends IdentityColumnSupportImpl {

@Override
public boolean supportsIdentityColumns() {
return true;
}

@Override
public String getIdentitySelectString(String table, String column, int type)
throws MappingException {
return "select last_insert_rowid()";
}

@Override
public String getIdentityColumnString(int type) throws MappingException {
return "integer";
}
}

Чтобы не усложнять, давайте оставим тип столбца идентификаторов только Integer . И чтобы получить следующее доступное значение идентификатора, мы укажем соответствующий механизм.

Затем мы просто переопределяем соответствующий метод в нашем растущем классе SQLiteDialect :

@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return new SQLiteIdentityColumnSupport();
}

3.3. Отключить обработку ограничений

Кроме того, SQLite не поддерживает ограничения базы данных, поэтому нам нужно отключить их , снова переопределив соответствующие методы как для первичных, так и для внешних ключей:

@Override
public boolean hasAlterTable() {
return false;
}

@Override
public boolean dropConstraints() {
return false;
}

@Override
public String getDropForeignKeyString() {
return "";
}

@Override
public String getAddForeignKeyConstraintString(String cn,
String[] fk, String t, String[] pk, boolean rpk) {
return "";
}

@Override
public String getAddPrimaryKeyConstraintString(String constraintName) {
return "";
}

И через мгновение мы сможем ссылаться на этот новый диалект в нашей конфигурации Spring Boot.

4. Конфигурация источника данных

Кроме того, поскольку Spring Boot не обеспечивает поддержку конфигурации для базы данных SQLite из коробки , нам также необходимо предоставить наш собственный компонент DataSource :

@Autowired Environment env;

@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("driverClassName"));
dataSource.setUrl(env.getProperty("url"));
dataSource.setUsername(env.getProperty("user"));
dataSource.setPassword(env.getProperty("password"));
return dataSource;
}

И, наконец, мы настроим следующие свойства в нашем файле persistence.properties :

driverClassName=org.sqlite.JDBC
url=jdbc:sqlite:memory:myDb?cache=shared
username=sa
password=sa
hibernate.dialect=com.foreach.dialect.SQLiteDialect
hibernate.hbm2ddl.auto=create-drop
hibernate.show_sql=true

Обратите внимание, что нам нужно сохранить кеш как общий , чтобы обновления базы данных оставались видимыми для нескольких подключений к базе данных.

Таким образом, с указанными выше конфигурациями приложение запустится и запустит базу данных в памяти с именем myDb , которую может использовать оставшаяся конфигурация Spring Data Rest .

5. Вывод

В этой статье мы взяли пример приложения Spring Data Rest и указали его на базу данных SQLite. Однако для этого нам пришлось создать собственный диалект Hibernate.

Не забудьте проверить приложение на Github . Просто запустите mvn -Dspring.profiles.active=sqlite spring-boot:run и перейдите на http://localhost:8080 .