Spring MVC配置多个数据源可能遇到的坑

由于业务需要连接多个数据源,在进行配置的过程中遇到了一些坑,在此做一下记录和分享。
jdbc.properties文件中多个数据源的基本信息:

# 数据源1
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8
jdbc.username=root
jdbc.password=123456

#数据源2
jdbc.driver1=com.mysql.cj.jdbc.Driver
jdbc.url1=jdbc:mysql://localhost:4444/newsclient?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8
jdbc.username1=root
jdbc.password1=123456

在applicationContext.xml文件中对数据源进行配置:

    
        
        
        
        
        
    

    
        
        
        
        
        
    

在applicationContext.xml文件中配置mybatisSqlSessionFactoryBean:


        
        
        


        
        
        

应该注意两个sqlSessionFactory的mapperLocations应该是不一样的;

在applicationContext.xml文件中配置SqlSessionTemplate:


        


        

在applicationContext.xml文件中配置mybatis mapper接口,扫描所有dao:


        
        


        
        

应该注意两者的basePackage对应的value要不一致,否则可能会造成 本来去数据源2获取数据,但是真实的请求是从数据源1中获取数据,报错,提示数据源1中不存在某表。

如果是按照以上的配置的,应该是可以成功的。

遇到的问题:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)错误
具体报错信息:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.study.server.mapper.UserMapper.insert
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:227)
    at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:49)
    at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)
    at com.sun.proxy.$Proxy88.insert(Unknown Source)

分析

public boolean hasStatement(String statementName, boolean validateIncompleteStatements) {
    if (validateIncompleteStatements) {
      buildAllStatements();
    }
    return mappedStatements.containsKey(statementName);
}

可以看出有2个会发生该异常的情况:
mappedStatements为{} (跟踪debug发现,我出现这里为空)
containsKey(statementName),没有找到
mappedStatements为空的原因是由于在spring容器启动时,会解析spring配置文件,这时将去加载资源文件,解析并以key,value的形式缓存在mappedStatements中。而在实际情况下,发现打包时*Mapper.xml并没有自动复制到class输出目录的mapper类包下。从而导致mappedStatements为空。

网上总结的一般原因

Mapper interface和xml文件的定义对应不上,需要检查包名,namespace,函数名称等能否对应上。
按以下步骤一一执行:
1、检查xml文件所在的package名称是否和interface对应的package名称一一对应
2、检查xml文件的namespace是否和xml文件的package名称一一对应
3、检查函数名称能否对应上
4、去掉xml文件中的中文注释
5、随意在xml文件中加一个空格或者空行然后保存
6、路径问题

项目中的解决方法

在使用IDEA开发时,如果打包时*Mapper.xml没有自动复制到class输出目录的mapper类包下,则需要在pom文件中添加mybatis加载配置文件的配置!
如下:


  
    
        src/main/java
      
        **/*.xml
      
    
    
      src/main/resources
    
  

通过在pom文件中添加mybatis加载配置文件,完美解决遇到的问题了。

你可能感兴趣的:(Spring MVC配置多个数据源可能遇到的坑)