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

[Help]希望提供多数据库连接的实现示例 #45

Open
ljyf5593 opened this issue Jan 26, 2025 · 6 comments
Open

[Help]希望提供多数据库连接的实现示例 #45

ljyf5593 opened this issue Jan 26, 2025 · 6 comments
Labels
help wanted Extra attention is needed

Comments

@ljyf5593
Copy link

由于项目中需要读取多个数据库,希望提供一个操作多个数据库的实现示例,目前提供的文档只说了建议实现自定义代理类,继承GaarasonDataSourceWrapper(即实现GaarasonDataSource接口), 并重写protected DataSource getRealDataSource(boolean isWriteOrTransaction)。但是具体如何实现,以及Model中如何使用,没有说明,希望给出一个示例参考。谢谢!

@ljyf5593 ljyf5593 added the help wanted Extra attention is needed label Jan 26, 2025
@xutengx
Copy link
Member

xutengx commented Jan 26, 2025

你好, 这边更新了 相关文档 可以参考下

@ljyf5593
Copy link
Author

你好, 这边更新了 相关文档 可以参考下

感谢您,我学习一下

@ljyf5593
Copy link
Author

ljyf5593 commented Feb 7, 2025

你好, 这边更新了 相关文档 可以参考下

抱歉,是我的场景没有描述清楚,您示例给的场景和我的情况有差异,我的场景是同一个程序需要操作不通的数据库表,例如用户表在用户数据库,文章表在文章数据库。在同一个接口中,需要同时从这两个数据库获取数据,目前我虽然实现了这个场景的需求,但是感觉实现的不合理,希望您帮我看看。

  1. 在配置文件中,把所有数据库的配置信息配置成一个数组,使用一个类读取这些配置信息。
  2. 编写了一个BaseModel抽象类,该类有一个抽象方法,getConnection方法,UserModel和ArticleModel都继承BaseModel,然后实现getConnection方法,UserModel返回user,ArticleModel返回article,user和article都是数据库的配置信息,BaseModel中重写getGaarasonDataSource方法,在方法内调用getConnection获取到当前应该使用哪个数据库连接,然后返回具体的连接。
  3. 经过调试测试,目前发现了以下问题:
    a. BaseModel中必须要手动配置扫描的包,才能实现关联查询,否则会报错,但是我看日志,实际上所有的Model包已经注入了,具体日志如下:
    DEBUG 1639758 --- [ main] g.database.bootstrap.ContainerBootstrap : All 16 Model has been load.
    手动配置扫描包的代码如下:
    static { // 包扫描 String[] packages = new String[]{ "gaarason.database", "cn.wujigang.fastwork.access.entity", "cn.wujigang.fastwork.business.entity", "cn.wujigang.fastwork.common.entity", "cn.wujigang.fastwork.srm.entity", }; System.setProperty("gaarason.database.scan.packages", ArrayUtil.join(packages, ",")); }
    如果不配置扫描包,会报下面这样的错误:
    `gaarason.database.exception.ObjectNewInstanceException: Error instantiating object[interface gaarason.database.config.QueryBuilderConfig] with message : Error instantiating object[interface gaarason.database.config.QueryBuilderConfig]
    at gaarason.database.provider.ContainerProvider.getBeansInside(ContainerProvider.java:144)
    at gaarason.database.provider.ContainerProvider.getBeans(ContainerProvider.java:86)
    at gaarason.database.connection.GaarasonDataSourceWrapper.getQueryBuilder(GaarasonDataSourceWrapper.java:329)
    at gaarason.database.connection.GaarasonDataSourceWrapper.getQueryBuilder(GaarasonDataSourceWrapper.java:316)
    at gaarason.database.eloquent.ModelOfQuery.theBuilder(ModelOfQuery.java:50)
    at gaarason.database.eloquent.ModelOfQuery.newQuery(ModelOfQuery.java:55)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:727)
    at cn.wujigang.fastwork.business.model.SaleOrderModel

S
p
r
i
n
g
C
G
L
I
B
SpringCGLIB

0.newQuery()
at cn.wujigang.fastwork.business.SaleOrderTest.relationQuery(SaleOrderTest.java:31)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: gaarason.database.exception.ObjectNewInstanceException: Error instantiating object[interface gaarason.database.config.QueryBuilderConfig]
at gaarason.database.util.ClassUtils.newInstance(ClassUtils.java:56)
at gaarason.database.provider.ContainerProvider.lambda$defaultNewInstance$1(ContainerProvider.java:160)
at gaarason.database.provider.ContainerProvider.getBeansInside(ContainerProvider.java:136)
... 18 more
Caused by: java.lang.NoSuchMethodException: gaarason.database.config.QueryBuilderConfig.init
at java.base/java.lang.Class.getConstructor0(Class.java:3761)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2930)
at gaarason.database.util.ClassUtils.newInstance(ClassUtils.java:52)
... 20 more`
b. 感觉关联模型查询时,关联的模型不是通过Spring Boot 注入的模型获取的,具体表现为如果定义的Model中包含了其他需要自动注入的Bean时,这些对象都是null,和手动 new 一个Model的表现一致,但是如果我在Service层,申请注入一个Model,则这个Model内部依赖的其他Bean则是正常的。
希望大佬可以帮忙解惑。

@xutengx
Copy link
Member

xutengx commented Feb 7, 2025

你好, 根据你表述的情况, 需要先确认下

  1. @SpringBootApplication 这个Spring注解所在的位置 ( 所属package ), 以及其他使用过的包扫描的 Spring 注解.
  2. 确保使用了 database-spring-boot-stater, 且 Container 有正确被 Spring 执行, 且有使用此 Container ( Spring实例化 ).

@ljyf5593
Copy link
Author

你好, 根据你表述的情况, 需要先确认下

  1. @SpringBootApplication 这个Spring注解所在的位置 ( 所属package ), 以及其他使用过的包扫描的 Spring 注解.
  2. 确保使用了 database-spring-boot-stater, 且 Container 有正确被 Spring 执行, 且有使用此 Container ( Spring实例化 ).

@SpringBootApplication 注解是在最顶层包上的,有使用 database-spring-boot-stater
Container 有正确被 Spring 执行, 且有使用此 Container ( Spring实例化 ). 这句话是什么含义,请问如何进行测试

@xutengx
Copy link
Member

xutengx commented Feb 12, 2025

如下代码示例,
在产生 GaarasonDataSource 的实例时,
应该使用 类似GaarasonDataSourceBuilder.build(Collections.singletonList(dataSource), container) 的方式,
而非 GaarasonDataSourceBuilder.build(Collections.singletonList(dataSource))

其中的 container 来自于 spring 实例


/**
 * Spring 中完成初始化的容器
 */
@Resource
Container container

/**
 * 数据源配置
 * @return 数据源
 */
@Primary
@Bean
@ConditionalOnMissingBean(GaarasonDataSource.class)
public GaarasonDataSource gaarasonDataSource(DataSource dataSource, Container container) {
    LOGGER.info("GaarasonDataSource init with " + dataSource.getClass().getName());
    // 创建 GaarasonDataSource
    return GaarasonDataSourceBuilder.build(Collections.singletonList(dataSource), container);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants