近期做了个小项目,需要在运行时实时创建或使用多个数据库(多个线程创建一对一数据库),然后对这个数据库进行操作,踩坑颇多,总结记录一下
关联版本:mybatis:3.5.9,sqlite-jdbc:3.36.0.3
一、分析
因为数据库不固定,无法使用配置文件配置,这里使用java代码中配置获取,需要新增数据源时在程序逻辑中执行多次配置即可
参考Mybatis官方文档:https://mybatis.org/mybatis-3/zh/java-api.html#sqlSessions
DataSource dataSource = BaseDataTest.createBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.setLazyLoadingEnabled(true);
configuration.setEnhancementEnabled(true);
configuration.getTypeAliasRegistry().registerAlias(Blog.class);
configuration.getTypeAliasRegistry().registerAlias(Post.class);
configuration.getTypeAliasRegistry().registerAlias(Author.class);
configuration.addMapper(BoundBlogMapper.class);
configuration.addMapper(BoundAuthorMapper.class);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
二、配置步骤
常见spring项目相关的mybatis配置xml中,常见有以下字段:
mybatis.datasource.type = POOLED
mybatis.datasource.driver = org.sqlite.JDBC
mybatis.datasource.username = ""
mybatis.datasource.password = ""
mybatis.datasource.url = "jdbc:sqlite:...."
在java中配置,即使用datasorce后面的参数进行构建就可以了,此处要注意的是type参数不需要传入,将由后续的DataSourceFactory实现类来指定
这里我封装为一个工具类方便其他服务调用, file
为指定连接的数据库文件
public class DatabaseConfigUtil {
public static DataSource getNormalSqliteDatasource(File file) {
Properties properties= new Properties();
properties.put("driver", "org.sqlite.JDBC");
properties.put("username", "");
properties.put("password", "");
properties.put("url", "jdbc:sqlite:"+file.getAbsolutePath());
DataSourceFactory dataSourceFactory = new PooledDataSourceFactory();
dataSourceFactory.setProperties(properties);
return dataSourceFactory.getDataSource();
}
}
private void initFileDatabaseConnectFactory(File nowUsageDatabaseFile) {
DataSource dataSource = DatabaseConfigUtil.getNormalSqliteDatasource(nowUsageDatabaseFile);
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment(nowUsageDatabaseFile.getName(), transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.setLazyLoadingEnabled(true);
configuration.getTypeAliasRegistry().registerAlias(DanMuUserInfoModel.class);
configuration.getTypeAliasRegistry().registerAlias(DanMuDataModel.class);
configuration.getTypeAliasRegistry().registerAlias(DanMuFormatModel.class);
configuration.addMappers("com.github.cuteluobo.livedanmuarchive.mapper.danmu");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
nowUsageSqlSessionFactory = sqlSessionFactoryBuilder.build(configuration);
}
注意的要点
最后通过 SqlSessionFactory.openSession()
获取sql对话即可
try (SqlSession sqlSession = nowUsageSqlSessionFactory.openSession()) {
DanMuDatabaseTableMapper danMuDatabaseTableMapper = sqlSession.getMapper(DanMuDatabaseTableMapper.class);
}
不需要手动创建,只需要在配置时配置好文件路径,并 创建这个文件的所有目录路径,驱动会自动生成文件。如果没有创建好文件的前置目录,抛出目录不存在的错误
之前建表的SQL使用了 CREATE INTO {tableName} IF EXISIT {tableName} .....
的判断,报错提示缺少database属性。后面换为直接从sqlite库中验证table是否存在,再创建。
以下提供两种表验证方式(Sqlite)
a.使用的验证表名SQL语句,返回符合当前名的数量
SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND tbl_name =
b.或使用编程验证(返回表的字段信息)
PRAGMA table_info(
后面发现a语句运行时有问题,对于新创建的数据库文件,sqlite_master表是不存在的,直接执行也会报错,所以给新创建的数据库文件加了个标识变量,新创建场景时,直接执行创建表SQL
关于b语句,在创建表后是正常的,数据库初始无表时没有进行验证,可以自行尝试
Original: https://blog.csdn.net/qq_41046428/article/details/124013158
Author: Cute_LuoBo
Title: Mybatis项目实时配置多个Sqlite数据源
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815415/
转载文章受原作者版权保护。转载请注明原作者出处!