有人在启用外键支持的情况下成功地让 sqlite 和 spring 工作吗?默认情况下,sqlite 中禁用外键支持。 http://www.sqlite.org/foreignkeys.html 的文档提到您必须分别为每个数据库连接启用它。我确信我拥有的 sqlite 版本支持外键(上周才下载)。
测试:如果我输入 PRAGMAforeign_keys;我返回 0。这意味着外键已关闭,但存在对其的支持。
我的数据源在 spring 中定义为:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverclass}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
如何通过spring配置启用外键?
这是一个老问题,但我最近对同样的问题感到有点困惑。
据我所知,至少有 2 个使用 Spring Boot 的解决方案(我假设常规 Spring 也有类似的解决方案)。 Sqlite 外键支持的要点是“PRAGMAforeign_keys = ON;”在*每个连接的基础上*有效。 (即,如果我有两个打开的数据库连接,并且我在第一个连接中将外键支持设置为“On”,则第一个连接将具有外键支持,但第二个连接不会。
解决方案1
来自Spring Boot参考手册:
如果您使用
或spring-boot-starter-jdbc
“starters”,您会自动获得对 HikariCP 的依赖。spring-boot-starter-data-jpa
Spring Boot 使用
DataSource
作为默认驱动程序自动为您创建一个 HikariCP
bean。 HikariCP
本身委托给适当的驱动程序基于其配置。
Spring Boot 期望至少将
spring.datasource.url
设置为 application.properties
。当 spring.datasource.hikari.<config-key>
是 Hikari 配置键之一时,还可以在属性文件中的
config-key
下设置 Hikari 配置设置。知道了这一点,使用 Spring Boot 我们可以使用以下application.properties
:
spring.datasource.url=jdbc:sqlite:path/to/db/database_file.db
spring.datasource.hikari.connectionInitSql=PRAGMA foreign_keys=1
以及以下 DAO(我正在使用
JdbcTemplate
):
@Repository
public class MyDaoImpl implements MyDao {
private final JdbcTemplate JDBC_TEMPLATE;
@Autowired
public SimpleArticleDao(DataSource dataSource) {
this.JDBC_TEMPLATE = new JdbcTemplate(dataSource);
}
@Override
public void insertObject(MyObject object) {
JDBC_TEMPLATE.update(
*...insert object into some table*
)
}
}
Spring Boot 将使用 Hikari 作为数据源创建并注入
dataSource
bean,Hikari 将为它创建的每个连接执行 PRAGMA foreign_keys = ON;
,确保始终启用外键支持。
解决方案2
您可以在 Spring Boot 的
DataSource
类中定义 @Configuration
bean,并通过直接使用 Xerial JDBC 驱动程序以编程方式设置外键支持:
@Configuration
public class MyApplicationConfig {
@Bean
public DataSource dataSource() {
SQLiteDataSource ds = new SQLiteDataSource();
ds.setUrl("jdbc:sqlite:path/to/db/database_file.db");
SQLiteConfig config = ds.getConfig();
config.enforceForeignKeys(true);
ds.setConfig(config);
return ds;
}
@Bean
...other bean definitions
}
在春季论坛之一找到答案:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name = "connectionInitSqls">
<list><value>**PRAGMA foreign_keys = ON**</value></list>
</property>
...
</bean>
我今天使用带有 SQLite 的 Spring Boot 2.2.2 和普通的
JdbcTemplate
也遇到了同样的问题。
实施 Patrick Tyler 的答案中的解决方案 2 破坏了我测试中的所有问题。我仍然不确定为什么,因为验证外键支持的非常简单的测试已启用并成功了。
或者,我尝试配置
spring.datasource.hikari.connection-init-sql
,但这也不起作用。
唉,最终起作用的是添加以下内容到
application.yml
:
spring:
datasource:
hikari:
data-source-properties:
foreign_keys: true
这可以通过一个简单的测试用例来验证:
@SpringBootTest
class SqliteTests {
@Autowired
private JdbcTemplate jdbcTemplate;
@DisplayName("Check for foreign key support in the SQLite backend")
@Test
void testSqliteForEnabledForeignKeySupport() {
final var result = jdbcTemplate.queryForObject("PRAGMA foreign_keys", Integer.class);
assertEquals(1, result);
}
}
解决方案3
使用 Hikari 时(默认在 Spring Boot 2+ 中),我们可以简单地在 application.properties 中使用以下条目配置 Xerial JDBC 驱动程序:
spring.datasource.hikari.data-source-properties.foreign_keys=true
“连接”=> [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
'foreign_keys' => true,
],
]