zoukankan      html  css  js  c++  java
  • Springboot Jpa 有关多数据源的问题

    前言

      我尽可能对自己每个遇到的问题进行总结,以致于反思自己为什么这么菜?

      这次的问题是,我需要在一个项目里面连两个数据库,多数据源操作,这个是一个很基本的操作,大概我还是花了三四天的时间吧(并不是全天在解决这个问题,但是有在想解决思路)。

    心路历程

    • 这个没做过啊,这要怎么写,就项目的单数据库连接我都不明白原理,为什么需要做这样的配置,多数据源操作本能的把他归结为一类很难的问题

        (我想这里我确实应该了解一下架构方面的东西,目前我只是停留在会使用的阶段)

    • 百度:“Spring boot Jpa 多数据源”,我的习惯向来不是看到一个就去试,而是我会把几页的百度结果都去大致的看一遍,或许我是在试图找个最简便的吧,但实际上是相同的操作不能人的博客描述是不一样的,实现方式都是类似的话,我就会找一个版面比较整齐的博客参照

            参考博文:https://www.cnblogs.com/fernfei/p/12119601.html

      我根据以上博文进行了一系列的配置,我整个项目也都运行不起来了,第一天过去了。

    java.sql.SQLException: net.sf.log4jdbc.DriverSpy
    	at com.alibaba.druid.util.JdbcUtils.createDriver(JdbcUtils.java:653)
    	at com.alibaba.druid.pool.DruidDataSource.resolveDriver(DruidDataSource.java:1212)
    	at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:887)
    	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1383)
    	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1379)
    	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:109)
    	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
    	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
    	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)

      对这个错误进行百度,基本上都是有关丢包的错误,需要加入什么的jar类似这样的,实际解决方法如下。因为在application.yml里面有相关配置,我也不知道这个问题的解决方向。(同事帮忙解决)

    • 解决了上述问题之后,项目还是没有成功运行起来,具体的错误已经不记得了。然后同事推荐一个博文“动态切换数据库”,第二天过去了

      参考博文:https://blog.csdn.net/shentan0000/article/details/116274449

    • 我根据上述博文的操作,我成功了,可以在前端对两个不同数据库的api请求都成功的获取数据了。接着就遇到致命的问题是,在一个会话中(方法中)同时做两个库的操作,就会直接报异常。第三天过去了

      报错提示:对象 名“表名”无效。这里并不是真的不存在这个表,而是连接的数据源不对,所以导致了找不到对应表。

    Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 对象名 'so_xxx' 无效。

       针对动态切换数据源的操作,在一个方法里面同时更新两个数据源数据的操作,至今没得到解决。

    • 我就想啊想,我也想不通为什么。这大概是我得出来的结论。第四天

    • 那么根据得出来的结论,要么同时两个数据库连接存在,要么切断连接建立新的连接。最终选择了回到最初的配置方式。

      参考博文:https://blog.csdn.net/taojin12/article/details/88573580

      毕竟我们是要以解决同时操作两个数据库问题为目标,所以没对动态切换数据源做更深的研究。(但其实我是很有兴趣弄明白他是为什么不能实现的)

    • 配置完后遇到的第一个问题
    Application failed to start due to an exception
    
    org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'PxxMainRepository' defined in null: Cannot register bean definition [Root bean: class [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'POMainRepository': There is already [Root bean: class [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)
    	at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:173)
    	at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:85)

      凭直觉解决,我的primary数据库配置package为“com.vxx”,数据源二的package配置为“com.vxx.uxx”,我想还是因为我把数据源二的包裹在默认数据源的包下,所以导致有些类不知道该选择哪个数据源了。所以我就把uxx移动到了com层,于是数据源二的package配置为“com.uxx”,这样两个就不会相互干扰了。

      实际上package可以进行多包配置,写的更细一些把com.vxx下的所有列出来也是可以的。如下

    basePackages = {"com.vxx.axx","com.vxx.bxx"}
    
    builder.dataSource(fosunDS).properties(vendorProperties)
           .packages("com.vxx.axx","com.vxx.bxx")

     

    • 配置完遇到的第二个问题
    [Vertex-SRM:0.0.0.0:8809] 20:24:33.681 DEBUG 17684 [main] o.s.b.d.LoggingFailureAnalysisReporter Application failed to start due to an exception
    
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xx.service.PxxMainService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1646)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1205)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166)
    	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:855)

      我百度了,参看博文:https://www.codetd.com/article/6188038

      里面有个 component-scan  的配置,这里刚好项目中有个被注释了的 @ComponentScan AppRun 这个类上(不然我可能不知道把这个配置加在哪),所以我就重新加上了

    @ComponentScan(basePackages = {"com.vxx","com.uxx"})
    public class AppRun {
    
        public static void main(String[] args) {
            SpringApplication.run(AppRun.class, args);
        }

     

    • 项目成功的运行起来,这时候又遇到了一个问题,在有些查询时候报错,列名 “createTime”无效

       正常我们是需要在字段上添加注解 @Column(name = "create_time") ,但系统有人默认配置可以将驼峰式映射成_小写的形式,即 createTime 对应 create_time

    这个默认的配置到底在哪呢?遇到这个问题的时候,描述都不好描述,自然没搜到答案。但实际上,有关这个默认配置的处理,在上述博文中又出现过(动态配置数据源博文),同事提醒了我,我需要反思自己,我其实没有认真看这些添加东西。

    Map<String, String> properties = jpaProperties.getProperties();
    //要设置这个属性,实现 CamelCase -> UnderScore 的转换
    properties.put("hibernate.physical_naming_strategy",
                    "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");

     

      至此,项目运行成功,两个数据库的操作也完美执行。

    最后日记

    现在是12.23号(第四天)的晚上九点钟,我在这个问题解决之后,肚子都有些饿了,公司的人都下班了,也本打算下班回家的我还是决定把这个过程给记录下来。下楼买了桶泡面吃,这是本周第二顿泡面(酸辣牛肉面周一觉得好好吃,今天觉得也不怎么样啦),博文竟写了两个小时,我相信没人会把这篇博文看完,包括以后的自己,哈哈哈。疑难杂症解决了,项目的开发内容也一齐做完了。加班一周了,我会因为我什么都不会而焦虑,我会因为遇到问题就不知道怎么解决而自我怀疑。我想,我总不能一直这么菜吧。祝愿,越来越优秀。

    明天是平安夜了,提前祝大家圣诞快乐!

     

  • 相关阅读:
    v:bind指令对于传boolean值的注意之处
    vue项目依赖的安装
    直接将文件存放到服务器tomcat中,就可以直接访问文件等
    什么情况下用vue.use方法
    创建Vue项目及其内容分析
    linux安装nginx以及如何启动,暂停,停止操作
    vue项目怎么搭建到云服务器上
    Nginx安装
    UNP学习笔记(第三十章 客户/服务器程序设计范式)
    UNP学习笔记(第二十六章 线程)
  • 原文地址:https://www.cnblogs.com/xqz0618/p/15725011.html
Copyright © 2011-2022 走看看