Mybatis项目实时配置多个Sqlite数据源

近期做了个小项目,需要在运行时实时创建或使用多个数据库(多个线程创建一对一数据库),然后对这个数据库进行操作,踩坑颇多,总结记录一下
关联版本: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/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球