Spring 数据 JDBC 和 SQLite
Spring Data JDBC and SQLite
我必须编写一个有现有 SQLite 数据源的新项目。
我基本上有两个问题:
- Spring数据JDBC是否支持SQLite?此处的清单并未明确说明:https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#requirements
- 因为它不是开箱即用的“官方”支持,是否建议通过自己的方言使用它 (SQLite)?
我可以从 sqlite 到比方说 postgres 做一些 import/export 的工作,完全没有问题。
SQLite 不支持开箱即用。
我不熟悉 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,所以我使用了 .
我必须编写一个有现有 SQLite 数据源的新项目。
我基本上有两个问题:
- Spring数据JDBC是否支持SQLite?此处的清单并未明确说明:https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#requirements
- 因为它不是开箱即用的“官方”支持,是否建议通过自己的方言使用它 (SQLite)?
我可以从 sqlite 到比方说 postgres 做一些 import/export 的工作,完全没有问题。
SQLite 不支持开箱即用。
我不熟悉 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,所以我使用了