Spring 数据 JDBC 和 SQLite

Spring Data JDBC and SQLite

我必须编写一个有现有 SQLite 数据源的新项目。
我基本上有两个问题:

  1. Spring数据JDBC是否支持SQLite?此处的清单并未明确说明:https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#requirements
  2. 因为它不是开箱即用的“官方”支持,是否建议通过自己的方言使用它 (SQLite)?

我可以从 sqlite 到比方说 postgres 做一些 import/export 的工作,完全没有问题。

  1. SQLite 不支持开箱即用。

  2. 我不熟悉 SQLite,但是 Spring 数据 JDBC 目前不需要任何花哨的 SQL 功能。在快速查看文档后,我相信您应该能够熟练掌握自己的方言。这是使用带有 Spring 数据 JDBC 的数据库的预期方式,开箱即用不受支持。

您甚至可以将方言开源并发布到 Maven 上,这样其他人也可以从中受益。

这可能不是正确的解决方案,所以请纠正我,以防我做错了什么,因为我不完全理解这些概念。但这对我有用:

import java.util.Optional;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.relational.core.mapping.NamingStrategy;

@Configuration
public class SQLiteJdbcDialectProvider extends AbstractJdbcConfiguration {

    @Bean
    @Override
    public JdbcMappingContext jdbcMappingContext(Optional<NamingStrategy> namingStrategy,
            JdbcCustomConversions customConversions) {

        JdbcMappingContext mappingContext = super.jdbcMappingContext(namingStrategy, customConversions);
        mappingContext.setForceQuote(false);

        return mappingContext;
    }

}

然后我将 MySQL Dialect 复制到 SQLite 方言中 class:

import org.springframework.data.relational.core.dialect.AbstractDialect;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.data.relational.core.dialect.H2Dialect;
import org.springframework.data.relational.core.dialect.LimitClause;
import org.springframework.data.relational.core.dialect.LockClause;
import org.springframework.data.relational.core.sql.LockOptions;

public class SQLiteDialect extends AbstractDialect {

    public static final SQLiteDialect INSTANCE = new SQLiteDialect();

    
    private static final LimitClause LIMIT_CLAUSE = new LimitClause() {

        @Override
        public String getLimit(long limit) {
            return "LIMIT " + limit;
        }

        @Override
        public String getOffset(long offset) {
            return String.format("LIMIT %d, 18446744073709551615", offset);
        }

        @Override
        public String getLimitOffset(long limit, long offset) {

            return String.format("LIMIT %s, %s", offset, limit);
        }

        @Override
        public Position getClausePosition() {
            return Position.AFTER_ORDER_BY;
        }
    };
    
    @Override
    public LockClause lock() {
        return LOCK_CLAUSE;
    }

    @Override
    public ArrayColumns getArraySupport() {
        return ArrayColumns.Unsupported.INSTANCE;
    }

    private static final LockClause LOCK_CLAUSE = new LockClause() {

        @Override
        public String getLock(LockOptions lockOptions) {
            return "WITH LOCK";
        }

        @Override
        public Position getClausePosition() {
            return Position.AFTER_ORDER_BY;
        }
    };

    @Override
    public LimitClause limit() {
        return LIMIT_CLAUSE;
    }
}

然后我在下面创建了一个新文件:

src\main\resources\META-INF\spring.factories

用行:

org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=your.package.SQLiteDialectResolver

最后我在使用 JdbcTemplate 调用 queryForList 时得到了一个 ArrayIndexOutOfBoundsException,所以我使用了 .