3

任何人在启用外键支持的情况下获得sqlite和spring的成功吗?默认情况下,外键支持在 sqlite 中被禁用。http://www.sqlite.org/foreignkeys.html上的文档提到您必须分别为每个数据库连接启用它。我确信我得到的 sqlite 版本支持外键(上周才下载)。

测试:如果我键入 PRAGMA foreign_keys;我返回 0。这意味着外键已关闭,但存在对它的支持。

我的数据源在春季定义为:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverclass}"/>
<property name="url" value="${jdbc.url}"/>
</bean>

如何通过spring配置启用外键?

4

4 回答 4

3

这是一个老问题,但我最近对同样的问题有点困惑。

我知道至少有两种使用 Spring Boot 的解决方案(我假设常规 Spring 的解决方案类似)。Sqlite 外键支持的重点是 `PRAGMA foreign_keys = ON;` 在*每个连接的基础上*有效。(即,如果我有两个打开的数据库连接,并且我在第一个连接中将外键支持设置为“开”,则第一个连接将支持外键,但第二个连接不会。

解决方案 1
来自Spring Boot 参考手册

如果你使用spring-boot-starter-jdbcor spring-boot-starter-data-jpa “starters”,你会自动获得对 HikariCP 的依赖。

Spring Boot 会自动DataSource为您创建一个 bean,并将HikariCP其用作默认驱动程序。本身根据其配置HikariCP委托给适当的驱动程序。

Spring Boot 至少spring.datasource.url需要在application.properties. Hikari 配置设置也可以在属性文件中进行设置,在 下spring.datasource.hikari.<config-key>,当config-keyHikari 配置键之一。知道了这一点,使用 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*
        )
    }
}

dataSourceSpring Boot 将使用 Hikari 作为 DataSource创建和注入bean,Hikari 将为PRAGMA foreign_keys = ON;它创建的每个连接执行,确保始终启用外键支持。

解决方案 2
您可以在您的类中为 Spring Boot 定义一个DataSourcebean ,并通过直接使用Xerial JDBC 驱动程序@Configuration以编程方式设置外键支持:

@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
}
于 2019-07-10T05:08:14.080 回答
0

在其中一个春季论坛上找到了答案:

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name = "connectionInitSqls">
    <list><value>**PRAGMA foreign_keys = ON**</value></list>
    </property>
    ...
    </bean>
于 2012-09-29T20:33:42.197 回答
0

我今天在使用带有 SQLite 和 plain 的 Spring Boot 2.2.2 时遇到了同样的问题JdbcTemplate

从帕特里克泰勒的回答中实施解决方案 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);
  }
}

于 2020-01-02T18:01:32.060 回答
0

解决方案 3

当使用 Hikari 时(默认情况下在 Spring Boot 2+ 中),我们可以简单地在 application.properties 中使用以下条目配置 Xerial JDBC Driver:

spring.datasource.hikari.data-source-properties.foreign_keys=true
于 2021-05-04T11:06:51.550 回答