Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

多数据源如何配置 #138

Closed
yaozhigangyeah opened this issue Jun 18, 2020 · 15 comments
Closed

多数据源如何配置 #138

yaozhigangyeah opened this issue Jun 18, 2020 · 15 comments

Comments

@yaozhigangyeah
Copy link

No description provided.

@bes2008
Copy link
Owner

bes2008 commented Jun 18, 2020

不需要配置,自动识别

@yaozhigangyeah
Copy link
Author

我这不识别request.getResult()返回为空

@yaozhigangyeah
Copy link
Author

PagingRequest request = new PagingRequest()
.setPageNo(consulationComplaint.getPageNo())
.setPageSize(consulationComplaint.getPageSize());
PagingRequestContextHolder.getContext().setPagingRequest(request);
consulationComplaintMapper.findApplyingInfo(consulationComplaint);

@HSPCode
Copy link

HSPCode commented Oct 21, 2020

你好,最近使用springboot+dynamic适配多数据源,但是SQLHelper好像并不支持多数据源呢。拼接分页sql语句的处理是Dialect的LimitHandler类,但是这个类是根据org.apache.ibatis.session.Configuration类的databaseId获取的,问题就在于databaseId在项目启动的时候会初始化,dynamic配置了多个数据源,默认取第一个配置的当做databaseId(问题概括,dynamic配置两个数据源,第一个是mysql,第二个是oracle。使用startPage时,全是按照第一个配置的数据源mysql的语法进行处理)。请问下,这个问题怎么处理呢?

@bes2008
Copy link
Owner

bes2008 commented Oct 21, 2020

我想的配置多数据源,其实就是创建多个sqlsessionfactory,每个sqlsession factory里对应一个configuration,自然就对应一个sqlhelper插件实例了。

你说的dynamic是mybatis-plus里提供的吗,如果是的话,我给研究一下,看看怎么配置。

@HSPCode
Copy link

HSPCode commented Oct 22, 2020 via email

@HSPCode
Copy link

HSPCode commented Oct 22, 2020 via email

@bes2008
Copy link
Owner

bes2008 commented Oct 23, 2020

@HSPCode

昨晚加了一个参数,来控制是否从org.apache.ibatis.session.Configuration类的databaseId获取

你可以再测试一下,

https://github.com/fangjinuo/sqlhelper/blob/master/sqlhelper-dialect/src/main/java/com/jn/sqlhelper/dialect/instrument/SQLInstrumentorConfig.java

如果你有现成的多数据源的测试用例,可以放到 sqlhelper-examples 下,3q
如果没有的话,我就后续加个测试用例

@HSPCode
Copy link

HSPCode commented Oct 23, 2020

@HSPCode

昨晚加了一个参数,来控制是否从org.apache.ibatis.session.Configuration类的数据库Id获取

你可以再测试一下,

https://github.com/fangjinuo/sqlhelper/blob/master/sqlhelper-dialect/src/main/java/com/jn/sqlhelper/dialect/instrument/SQLInstrumentorConfig.java

如果你有现成的多数据源的测试用例,可以放到sqlhelper-examples下,3q
如果没有的话,我就后续加个测试用例

①之前描述的有点问题,org.apache.ibatis.session.Configuration类的databaseId获取的是yml文件spring.datasource.dynamic.primary指明的默认数据源,不是第一个数据源。原因是,dynamic的com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder类的peek()方法会返回当前线程/代码使用的数据源名称,但是项目启动的时候是没有使用数据源的,peek()返回空,之后的逻辑操作使用primary指定的默认数据源,即使用primary指定的数据源处理为Configuration类的databaseId;
详见:org.mybatis.spring.SqlSessionFactoryBean类的buildSqlSessionFactory方法
image
com.jn.sqlhelper.common.utils.Connections类的getDatabaseProductName方法:
image
这一步实际获取的是primary指定的数据源的conn;

②SQLHelper获取databaseId的地方是,com.jn.sqlhelper.mybatis.MybatisUtils类的getDatabaseId方法,
image
只在红框的地方获取到了databaseId,所以导致SQLHelper分页处理(查找Dialect)都按照primary数据源类型来处理了。

其实问题就是,MybatisUtils的getDatabaseId方法,在集成dynamic多数据源的情况下前几步都没获取到databaseId。

@bes2008
Copy link
Owner

bes2008 commented Oct 23, 2020

我理解的,那我在configuration上加了开关后,确保不走configuration的方式获取,也就是走最后的方式,应该没有问题吧。因为最后的方式就是从真实的数据源获取的。

@HSPCode
Copy link

HSPCode commented Oct 23, 2020 via email

@bes2008
Copy link
Owner

bes2008 commented Oct 23, 2020

不会多连接的,如果每次都多连接一次,还要连接池有什么意义呢?你可以看到TX. getconnection的实现都是没有connection情况下才会去创建

  @Override
  public Connection getConnection() throws SQLException {
    if (connection == null) {
      openConnection();
    }
    return connection;
  }

另外你的方案我也看了,你的方案是针对 mybatis-plus 的dynamic-datasource 实现的。如果是用在 mybatis-plus上是肯定没有问题的,是个不错的想法。
但是如果有的同学不知道这玩意儿,他用了自定义的 RoutingDataSource的话,就没有办法适配了。
另外这个MyBatisUtils是在sqlhelper-mybatis模块下,这是个基础模块,会被其他的基于mybatis的框架对应的模块引用的。
在这个模块下,是拿不到DynamicDataSourceContext 类的。

@HSPCode
Copy link

HSPCode commented Oct 24, 2020 via email

@bes2008
Copy link
Owner

bes2008 commented Oct 29, 2020

虽然他们开发的 dynamic-datasource 工具比较好用,但是有一种情况处理不了。

SQL mapper 文件中,为sql 定义 指定了 databaseId 属性的场景下用不了。
原因: 
mybatis Configuration对象在初始化时,会通过默认关联的datasource, 来解析 出默认的databaseId,
然后在解析所有的 sql mapper的过程中,发现了自定义的databaseId 和 默认的databaseId 不一样的话,是不会 care的。
内部是Map结构存储了所有的SQL , key 是namespace+sqlid,所以同sqlid的,只会保留一个。

解决方案:

创建多个 Configuration , Configuration 和SQLSessionFactory是一 一对应的,所以要创建多个SqlSessionFactory,
并自定义 自己的SqlSessionTemplate ,在自定的SqlSessionTemplate 中,可以通过反射拿到注解来自动的切换 sqlsessionfactory,从而达到切换 datasource的能力

@bes2008
Copy link
Owner

bes2008 commented Jan 16, 2021

@HSPCode
@yaozhigangyeah

sqlhelper 提供了多数据源配置方案,如有需要,可以试用。升级到 3.4.3 后即可试用。

项目的 .wiki 目录下,有相关的教程

@bes2008 bes2008 closed this as completed Jan 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants