SpringBoot与mybatis整合返回map时key全是小写解决方案(多数据源)

  • Post author:
  • Post category:其他


首先说下多数据源的配置吧

properties.yml

##postgresql #####################################################################
spring:
  datasource:
    manage:
      url: jdbc:postgresql://你的IP地址:5432/db_admin_manage?autoReconnect=true
      username: postgres
      password: postgres
      driverClassName: org.postgresql.Driver
    template:
      url: jdbc:postgresql://你的IP地址:5432/db_work_template?autoReconnect=true
      username: postgres
      password: postgres
      driverClassName: org.postgresql.Driver
    # 下面为连接池的补充设置,应用到上面所有数据源中
    #指定连接池最大的连接数,包括使用中的和空闲的连接.
    maximum-pool-size: 100
    #最大等待连接中的数量,设 0 为没有限制
    max-idle: 10
    #最大等待毫秒数, 单位为 ms, 超过时间会出错误信息
    max-wait: 30000
    min-idle: 5
    initial-size: 5
    #在空闲时 每个1小时 访问一下数据库,避免连接池中的连接因超时而失效
    time-between-eviction-runs-millis: 3600000

上面我配置了两个数据源,一个manage,另一个template ,(ps:我用的数据库是postgresql)

然后创建两个数据源类

package com.wulianwang.manage.config.datasource;

import com.wulianwang.manage.config.mybatis.MapWrapperFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import tk.mybatis.spring.annotation.MapperScan;

import javax.sql.DataSource;

/**
 * Created by 甘银道 on 2019/3/26.
 * 主数据源
 */
@Configuration
@MapperScan(basePackages = "com.wulianwang.manage.mapper.system", sqlSessionFactoryRef = "manageSqlSessionFactory")
public class ManageConfig {

    @Bean(name = "manageDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.manage")
    @Primary
    public DataSource manageDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "manageSqlSessionFactory")
    @Primary
    public SqlSessionFactory manageSqlSessionFactory(@Qualifier("manageDataSource") DataSource dataSource) throws Exception {
        org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
//开启驼峰命名
        config.setMapUnderscoreToCamelCase(true);
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setObjectWrapperFactory(new MapWrapperFactory());//这里的MapWrapperFactory是后面创建的
        bean.setConfiguration(config);
        //读取mybatis小配置文件
        bean.setMapperLocations(new         PathMatchingResourcePatternResolver().getResources("classpath:mappers/system/*.xml"));
         return bean.getObject();
    }

@Bean(name = "manageSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate manageSqlSessionTemplate(@Qualifier("manageSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
package com.wulianwang.manage.config.datasource;

import com.wulianwang.manage.config.mybatis.MapWrapperFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import tk.mybatis.spring.annotation.MapperScan;

import javax.sql.DataSource;

/**
 * Created by 甘银道 on 2019/3/26.
 * 次数据源
 */
@Configuration
@MapperScan(basePackages = "com.wulianwang.manage.mapper.template", sqlSessionFactoryRef = "templateSqlSessionFactory")
public class TemplateConfig {

    @Bean(name = "templateDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.template")
    public DataSource templateDataSource() {
        return DataSourceBuilder.create().build();
    }


    @Bean(name = "templateSqlSessionFactory")
    public SqlSessionFactory templateSqlSessionFactory(@Qualifier("templateDataSource") DataSource dataSource) throws Exception {
        org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
        //开启驼峰命名
        config.setMapUnderscoreToCamelCase(true);
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setConfiguration(config);
        bean.setObjectWrapperFactory(new MapWrapperFactory());//这里的MapWrapperFactory是后面创建的
        //读取mybatis小配置文件
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/template/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "templateSqlSessionTemplate")
    public SqlSessionTemplate templateSqlSessionTemplate(@Qualifier("templateSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

目录结构

别忘了扫描

@SpringBootApplication
//开启事务
@EnableTransactionManagement
@ComponentScan(value={"com.wulianwang.manage.controller",
        "com.wulianwang.manage.service",
        "com.wulianwang.manage.config"})
@MapperScan(value = "com.wulianwang.manage.mapper.*")
public class Application {

    public static void main(String[] args){

        SpringApplication.run(Application.class,args);
    }
}

下面回归正题,解决springboot怎么在查询一个数据时返回map并且key是驼峰命名的

添加CustomWrapper

package com.wulianwang.manage.config.mybatis;

import com.google.common.base.CaseFormat;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;

import java.util.Map;

/**
 * Created by 甘银道 on 2019/4/2.
 */
public class CustomWrapper extends MapWrapper {

    public CustomWrapper(MetaObject metaObject, Map<String, Object> map) {
        super(metaObject, map);
    }

    @Override
    public String findProperty(String name, boolean useCamelCaseMapping) {
        if(useCamelCaseMapping){
             //CaseFormat是引用的 guava库,里面有转换驼峰的,免得自己重复造轮子,pom添加
            /**
             *<dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <version>24.1-jre</version>
             </dependency>
             **/
          return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,name);
        }
        return name;
    }

}

添加MapWrapperFactory

package com.wulianwang.manage.config.mybatis;


import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * Created by 甘银道 on 2019/4/2.
 */
@Configuration
public class MapWrapperFactory implements ObjectWrapperFactory {

    @Override
    public boolean hasWrapperFor(Object object) {
        return object != null && object instanceof Map;
    }

    @Override
    public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
        return new CustomWrapper(metaObject,(Map)object);
    }
}

目录结构的话上面的结构包括了这两个文件

借鉴与

https://blog.51cto.com/dengshuangfu/2130010


https://my.oschina.net/u/2278977/blog/1795969