赞
踩
建议去使用mybatis-plus 集成 多数据源
一直在趟坑,从未被超越。
借鉴文章
个人觉得我算是整理的比较详细的了,有些博客老是缺斤少两的。最恶心的是竟然会有人写到,如需下文请关注什么什么公众号。
结构
pom文件
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- druid数据源驱动 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency> <!-- 通用mapper --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>1.1.5</version> </dependency> <!-- druid监控依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.28</version> </dependency> </dependencies>
连接池配置
package com.example.demo.config; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration @SuppressWarnings("AlibabaRemoveCommentedCode") //该注解主要用在取消一些编译器产生的警告 public class DruidConfig { /** * http://localhost:8080/druid/login.html * 注册一个StatViewServlet * * @return */ @Bean public ServletRegistrationBean DruidStatViewServle() { //org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); //白名单: servletRegistrationBean.addInitParameter("allow", "127.0.0.1"); //登录查看信息的账号密码. servletRegistrationBean.addInitParameter("loginUsername", "admin"); servletRegistrationBean.addInitParameter("loginPassword", "123456"); //是否能够重置数据. servletRegistrationBean.addInitParameter("resetEnable", "false"); return servletRegistrationBean; } /** * 注册一个:filterRegistrationBean * * @return */ @Bean public FilterRegistrationBean druidStatFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); //添加过滤规则. filterRegistrationBean.addUrlPatterns("/*"); //添加不需要忽略的格式信息. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource() { return new DruidDataSource(); } }
首先配置两个数据源连接,格式如下(网上url连接大多用jdbc-url连接,经测试并不好使,也可能是我测试的有问题。如果有兴趣你们也可以多种方式自测一下)
记得启动类不要加@MapperScan("")扫描你的mapper层,因为多数据源连接的核心配置就在于自己创建自己的mappe层,自己扫描自己的。
server.port=8081 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.0.1:3306/game?useUnicode=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=root spring.datasource.url2=jdbc:mysql://192.168.0.2:3306/vip?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong spring.datasource.username2=root spring.datasource.password2=root spring.jpa.open-in-view=false #数据库连接池初始化连接个数 spring.datasource.druid.initial-size=5 #最小连接个数 spring.datasource.druid.min-idle=5 #最大的连接数 spring.datasource.druid.max-active=20 #等待连接获取的最大等待时间 spring.datasource.druid.max-wait=6000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=30000 #检测连接是否有效的sql spring.datasource.validationQuery=SELECT 1 FROM DUAL #申请连接时检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效(不影响性能) spring.datasource.testWhileIdle=true #申请连接时不检测连接是否有效 spring.datasource.testOnBorrow=false #归还连接时不检测连接是否有效 spring.datasource.testOnReturn=false #打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 #配置监控统计拦截的filters(不配置则监控界面sql无法统计),监控统计filter:stat,日志filter:log4j,防御sql注入filter:wall spring.datasource.druid.filters=stat,log4j,wall #支持合并多个DruidDataSource的监控数据 spring.datasource.druid.use-global-data-source-stat=true #通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
各自配置扫描文件
注解 | 备注 |
---|---|
@Primary | 优先方案,被注解的实现,优先被注入 。主要用来标注哪个数据源为主数据源,有且只能标注一个 |
@Qualifier | 先声明后使用,相当于多个实现起多个不同的名字,注入时候告诉我你要注入哪个 |
主数据源配置
package com.example.demo.config; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; 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 org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = MasterDbConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDbConfig { //定义mapperscan需要扫描的mapper层 static final String PACKAGE = "com.example.demo.mapper.master"; //定义需要扫描的对应的xml层,在定义好的目录下各自创建文件就可以了 private static final String MAPPER_LOCATION = "classpath*:mappers/master/*.xml"; @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.driverClassName}") private String driverClassName; @Bean(name = "masterDataSource") //声明其为Bean实例 @Primary //在同样的DataSource中,首先使用被标注的DataSource public DataSource masterDataSource() { DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(this.dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); return datasource; } @Bean(name = "masterTransactionManager") @Primary public DataSourceTransactionManager masterTransactionManager() { return new DataSourceTransactionManager(masterDataSource()); } @Bean(name = "masterSqlSessionFactory") @Primary public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(masterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(MasterDbConfig.MAPPER_LOCATION)); //mybatis 数据库字段与实体类属性驼峰映射配置 sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); return sessionFactory.getObject(); } }
备数据源配置
package com.example.demo.config; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = ClusterDbConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory") public class ClusterDbConfig { // 精确到 cluster 目录,以便跟其他数据源隔离 static final String PACKAGE = "com.example.demo.mapper.cluster"; private static final String MAPPER_LOCATION = "classpath*:mappers/cluster/*.xml"; @Value("${spring.datasource.url2}") private String dbUrl; @Value("${spring.datasource.username2}") private String username; @Value("${spring.datasource.password2}") private String password; @Value("${spring.datasource.driverClassName}") private String driverClassName; @Bean(name = "clusterDataSource") //声明其为Bean实例 public DataSource clusterDataSource() { DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(this.dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); return datasource; } @Bean(name = "clusterTransactionManager") public DataSourceTransactionManager clusterTransactionManager() { return new DataSourceTransactionManager(clusterDataSource()); } @Bean(name = "clusterSqlSessionFactory") public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource culsterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(culsterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(ClusterDbConfig.MAPPER_LOCATION)); //mybatis 数据库字段与实体类属性驼峰映射配置 sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); return sessionFactory.getObject(); } }
创建各自的mappe层和xml文件
自己注意一下namespace就可以了,别把命名空间搞错了
package com.example.demo.mapper.master;
import java.util.HashMap;
import java.util.List;
public interface MasterMapper {
List<HashMap<String,Object>> queryBooks();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.master.MasterMapper">
<select id="queryBooks" resultType="java.util.HashMap">
select * from books
</select>
</mapper>
Service层,在这个地方就可以自己处理各自的业务啦
package com.example.demo.service; import com.example.demo.mapper.cluster.ClusterMapper; import com.example.demo.mapper.master.MasterMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; @Service public class TestService { @Resource private ClusterMapper clusterMapper; @Resource private MasterMapper masterMapper; public List<HashMap<String, Object>> queryBooks() { return masterMapper.queryBooks(); } public List<HashMap<String, Object>> queryOrders() { return clusterMapper.queryOrders(); } }
Controller层
package com.example.demo.controller; import com.example.demo.service.TestService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; @RestController @RequestMapping(value = "/test", method = RequestMethod.POST) public class TestController { @Resource private TestService testService; @RequestMapping("/books") public List<HashMap<String, Object>> queryBooks() { return testService.queryBooks(); } @RequestMapping("/orders") public List<HashMap<String, Object>> queryOrders() { return testService.queryOrders(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。