SQLITE 和外键支持
Posted
技术标签:
【中文标题】SQLITE 和外键支持【英文标题】:SQLITE and foreign key support 【发布时间】:2012-09-26 15:51:38 【问题描述】:在启用外键支持的情况下,任何人在启用 sqlite 和 spring 方面取得了成功吗?默认情况下,外键支持在 sqlite 中被禁用。 http://www.sqlite.org/foreignkeys.html 的文档提到您必须分别为每个数据库连接启用它。我确信我得到的 sqlite 版本支持外键(上周才下载)。
测试:如果我键入 PRAGMA foreign_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配置启用外键?
【问题讨论】:
您是否尝试过在控制台上明确打开它?所以输入PRAGMA foreign_keys = ON;
然后PRAGMA foreign_keys;
看看是否真的有支持。它应该播放1
。
@Tim 我知道这是旧的,但以防万一有人在看这个,在控制台中输入 PRAGMA foreign_keys = ON;
(我假设你的意思是在 sqlite 控制台中)将不起作用,因为需要为每个单独的连接启用外键。如果我打开一个控制台,将外键设置为打开,然后打开第二个控制台,外键将在第一个控制台中启用,但不会在第二个控制台中启用。
【参考方案1】:
这是一个老问题,但我最近对同样的问题有点困惑。
我知道至少有 2 个使用 Spring Boot 的解决方案(我假设常规 Spring 的解决方案类似)。 Sqlite 外键支持的重点是 `PRAGMA foreign_keys = ON;` 在*每个连接的基础上*有效。 (即,如果我有两个打开的数据库连接,并且我在第一个连接中将外键支持设置为 `On`,则第一个连接将支持外键,但第二个连接不会。
解决方案 1 来自Spring Boot reference manual:
如果您使用
spring-boot-starter-jdbc
或spring-boot-starter-data-jpa
“starters”,你会自动获得对 HikariCP 的依赖。
Spring Boot 使用 HikariCP
作为默认驱动程序自动为您创建一个 DataSource
bean。 HikariCP
本身委托给适当的驱动程序based on its configuration。
Spring Boot 至少需要在 application.properties
中设置 spring.datasource.url
。 Hikari 配置设置也可以在属性文件中设置,在spring.datasource.hikari.<config-key>
下,当config-key
是Hikari configuration keys 之一时。知道了这一点,使用 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 创建和注入 dataSource
bean,Hikari 将为它创建的每个连接执行 PRAGMA foreign_keys = ON;
,确保始终启用外键支持。
解决方案 2
您可以在 @Configuration
类中为 Spring Boot 定义一个 DataSource
bean,并通过直接使用 Xerial JDBC driver 以编程方式设置外键支持:
@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
【讨论】:
【参考方案2】:在其中一个春季论坛上找到了答案:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name = "connectionInitSqls">
<list><value>**PRAGMA foreign_keys = ON**</value></list>
</property>
...
</bean>
【讨论】:
【参考方案3】:我今天在使用带有 SQLite 和普通 JdbcTemplate
的 Spring Boot 2.2.2 时遇到了同样的问题。
从 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);
【讨论】:
【参考方案4】:解决方案 3
当使用 Hikari 时(默认在 Spring Boot 2+ 中),我们可以简单地在 application.properties 中使用以下条目配置 Xerial JDBC Driver:
spring.datasource.hikari.data-source-properties.foreign_keys=true
【讨论】:
以上是关于SQLITE 和外键支持的主要内容,如果未能解决你的问题,请参考以下文章
SQLite Expert Professional 如何设置主键和外键
SQLite Expert Professional 如何设置主键和外键