前言:
本文為springboot結合mybatis配置多數據源,在項目當中很多情況是使用主從數據源來讀寫分離,還有就是操作多庫,本文介紹如何一個項目同時使用2個數據源。
也希望大家帶着思考去學習!博主是最近才學的配置寫成博文分享心得和技巧,文中有不足的歡迎留言指正,謝謝!
思考:
1、如果從傳統的單數據源轉換為多數據源,以前使用boot只用導包寫配置文件boot會幫我們自動配置,如果不用自動配置我們改怎么配呢?
2、怎么結合mybatis分頁插件一起使用呢?
.................
項目目錄結構
對主從數據庫分區,不同的數據源在不同的文件下易區分
創建2個數據庫
DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id', `userName` varchar(32) DEFAULT NULL COMMENT '用戶名', `passWord` varchar(32) DEFAULT NULL COMMENT '密碼', `user_sex` varchar(32) DEFAULT NULL, `nick_name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;
INSERT INTO `users` VALUES ('28', 'asd', 'asda', '1', 'asd');
使用一個表結構創建2個數據源 test1、test2
重要部分pom
<!-- mysql包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 用於springboot熱部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- 阿里alibaba數據源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.6</version> </dependency> <!-- 添加JDBC依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version> </dependency>pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>top.cmnbgy</groupId> <artifactId>spring-boot-ibatis-mulidatasource</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-ibatis-mulidatasource</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.17.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 用於springboot熱部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- 阿里alibaba數據源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.6</version> </dependency> <!-- 添加JDBC依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
創建application.yml 文件
# 指定項目端口 server: port: 8080 spring: datasource:
#主數據源 master: driverClassName : com.mysql.jdbc.Driver url : jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8 username : root password : 1234
#從數據源 slave: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8 username: root password: 1234 #配置分頁插件 pagehelper: helperDialect: mysql # 設置數據庫類型 reasonable: true #開啟合理化:頁碼<=0 查詢第一頁,頁碼>=總頁數查詢最后一頁 supportMethodsArguments: true #支持通過 Mapper 接口參數來傳遞分頁參數 params: count=countSql # 參數 成員變量 = ${ xx}使用spring boot官方推薦的yml文件配置,結構更清晰!
創建主數據源配置類 MasterDataSource
package top.cmnbgy.springbootibatismulidatasource.dataSource; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; 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 org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; import java.io.IOException; /** * 主數據源配置 * @ClassName MasterDataSource * @Cescription TODO * @Author .朱孝輝 * @Blog http://www.cmnbgy.top * @Datae 2018/11/14 0014 13:45 **/ @Configuration // basePackages :設置為你的 mapper(主數據源)接口路徑 @MapperScan(basePackages = "top.cmnbgy.springbootibatismulidatasource.mapper.master", sqlSessionTemplateRef = "master-SqlSessionTemplate") // ConfigurationProperties:讀取application文件 @ConfigurationProperties(prefix = "spring.datasource.master") public class MasterDataSource { private String url; private String username; private String password; private String driverClassName; /* ....... 忽略其他配置參數*/ public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 創建主數據源 * @return */ @Bean(name = "master-DataSource") @Primary // @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource testDataSource() { /** * @Bean:創建bean組件,可設置bean的name,如果不寫name默認為方法名 * @Primary:設置為優先注入,如果Bean類型有多個,設置@Primary后會將該Bean優先注入,否則會報錯 * @ConfigurationProperties:讀取application.properties 屬性封裝成實體類 * * DataSourceBuilder.create().build() :SpringBoot為我們提供了簡便的創建數據源方式 */ DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); dataSource.setDriverClassName(driverClassName); return dataSource; } /** * 創建SqlSession工廠 */ @Primary @Bean(name = "master-SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("master-DataSource") DataSource dataSource) throws Exception { /** * @Qualifier:正常情況下,注入bean時,如果存在多個資源,就會出錯,可以用@Qualifier指定名字 */ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/master/*/*.xml")); return bean.getObject(); } /** * 事務管理 */ @Primary @Bean(name="master-TransactionManager") public DataSourceTransactionManager masterTransactionManager(@Qualifier("master-DataSource") DataSource dataSource){ DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); return dataSourceTransactionManager; } /** * 配置sqlsession模板 */ @Primary @Bean("master-SqlSessionTemplate") public SqlSessionTemplate masterSQLSessionTemplate(@Qualifier("master-SqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } }
從數據源 SlaveDataSource
package top.cmnbgy.springbootibatismulidatasource.dataSource; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; 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 org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /** * 從數據源配置 * @ClassName SlaveDataSource * @Cescription TODO * @Author .朱孝輝 * @Blog http://www.cmnbgy.top * @Datae 2018/11/14 0014 13:46 **/ @Configuration @MapperScan(basePackages = "top.cmnbgy.springbootibatismulidatasource.mapper.slave", sqlSessionTemplateRef = "slave-SqlSessionTemplate") @ConfigurationProperties(prefix = "spring.datasource.slave") public class SlaveDataSource { private String url; private String username; private String password; private String driverClassName; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } /** * 創建主數據源 * @return */ @Bean(name = "slave-DataSource") // @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource testDataSource() { /** * @Bean:創建bean組件,可設置bean的name,如果不寫name默認為方法名 * @Primary:設置為優先注入,如果Bean類型有多個,設置@Primary后會將該Bean優先注入,否則會報錯 * @ConfigurationProperties:讀取application.properties 屬性封裝成實體類 * * DataSourceBuilder.create().build() :SpringBoot為我們提供了簡便的創建數據源方式 */ System.out.println("================================"+url); DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(url); dataSource.setUsername(username);// 用戶名 dataSource.setPassword(password);// 密碼 dataSource.setDriverClassName(driverClassName); return dataSource; } /** * 創建SqlSession工廠 */ @Bean(name = "slave-SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("slave-DataSource") DataSource dataSource) throws Exception { /** * @Qualifier: */ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/slave/*/*.xml")); return bean.getObject(); } /** * 事務管理 */ @Bean(name="slave-TransactionManager") public DataSourceTransactionManager masterTransactionManager(@Qualifier("slave-DataSource") DataSource dataSource){ DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); return dataSourceTransactionManager; } /** * 配置sqlsession模板 */ @Bean("slave-SqlSessionTemplate") public SqlSessionTemplate masterSQLSessionTemplate(@Qualifier("slave-SqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } }
@Configuration :用於定義配置類,告訴springboot這是配置類。@ConfigurationProperties:讀取application配置文件@Bean:創建bean組件,可設置bean的name,如果不寫name默認為方法名@Primary:設置為優先注入,如果Bean類型有多個,設置@Primary后會將該Bean優先注入,否則會報錯@ConfigurationProperties:讀取application.properties 屬性封裝成實體類@Qualifier:正常情況下,注入bean時,如果存在多個資源,就會出錯,可以用@Qualifier指定名字 @MapperScan:ibatis提供的注解,注解包路徑 package org.mybatis.spring.annotation;
basePackages:要掃描mapper類包的路徑sqlSessionTemplateRef:sqlSessionTemplateRef Bean的名稱注意:關於bean的命名 masterDataSource 以前我是這樣命名的,最后一直報錯,排查后發現spring容器中也有一個 名稱為masterDataSource的bean,所以起沖突了。
創建mapper接口和xml
創建文件夾 top.cmnbgy.springbootibatismulidatasource.mapper.master
用於放 主數據源 mapper接口類 UsersMapper.java
package top.cmnbgy.springbootibatismulidatasource.mapper.master; import java.util.List; /** * @ClassName UsersMapper * @Cescription TODO * @Author .朱孝輝 * @Blog http://www.cmnbgy.top * @Datae 2018/11/15 0015 9:57 **/ public interface UsersMapper { List selectAll(); }
創建文件夾 top.cmnbgy.springbootibatismulidatasource.mapper.slave
再創建一個從數據源 mapper接口 Users1Mapper.java
package top.cmnbgy.springbootibatismulidatasource.mapper.slave; import java.util.List; /** * @ClassName UsersMapper * @Cescription TODO * @Author .朱孝輝 * @Blog http://www.cmnbgy.top * @Datae 2018/11/15 0015 9:57 **/ public interface Users1Mapper { List selectAll(); }
創建mapperXMl
創建 master 文件夾下面 的 UsersMapper.xml 文件
為了省步驟,我直接用HashMap 做載體,就不用寫實體類了
<?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="top.cmnbgy.springbootibatismulidatasource.mapper.master.UsersMapper" > <select id="selectAll" resultType="map"> select * from users </select> </mapper>創建 slave文件夾下面 的 UsersMapper.xml 文件
<?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="top.cmnbgy.springbootibatismulidatasource.mapper.slave.Users1Mapper" > <select id="selectAll" resultType="map"> select * from users </select> </mapper>
resultType="map" 映射返回類型可以使用別名
我在貼一份別名的表,這些都是mybatis 自帶的 別名配置,你也可以自定義別名
https://blog.csdn.net/qq_28885149/article/details/51694733
【ღ( ´・ᴗ・` )比心】
別名 映射的類型 _byte byte _long long _short short _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal bigdecimal BigDecimal object Object map Map hashmap HashMap list List arraylist ArrayList collection Collection iterator Iterator
★華麗分割線 ★ 注意點
注意:
檢查下 數據源配置文件(Master | SlaveDataSource)的
看看有沒有對應上,Master 和 Slave 別混淆,如果報 哪個XML的某個 sql 沒匹配上,請仔細檢查一下以上的路徑是否正確!
★華麗分割線 ★ 最后的測試環節
package top.cmnbgy.springbootibatismulidatasource; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import org.apache.ibatis.annotations.Select; import org.junit.Test; import org.junit.runner.RunWith; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import top.cmnbgy.springbootibatismulidatasource.mapper.master.UsersMapper; import top.cmnbgy.springbootibatismulidatasource.mapper.slave.Users1Mapper; import javax.annotation.Resource; import javax.sql.DataSource; import java.awt.image.Kernel; import java.sql.SQLException; @RunWith(SpringRunner.class) @SpringBootTest public class SpringBootIbatisMulidatasourceApplicationTests { @Resource(name = "master-DataSource") DataSource masterDataSource; @Resource(name = "slave-DataSource") DataSource slaveDataSource; /** * 主數據源 */ @Autowired UsersMapper usersMapper; /** * 從數據源 */ @Autowired Users1Mapper users1Mapper; @Test public void contextLoads() throws SQLException { System.out.println("=========================================================="); System.out.println("主數據源:"+masterDataSource); System.out.println("從數據源:"+slaveDataSource); // 開啟分頁 System.out.println("主數據源:"); Page page = PageHelper.startPage(1,10); System.out.println(usersMapper.selectAll()); usersMapper.selectAll().forEach(item->System.out.println(item)); System.out.println("總頁數:"+page.getTotal()); //----------------------------------------------------------- System.out.println("從數據源:"); Page page1 = PageHelper.startPage(1,10); System.out.println(users1Mapper.selectAll().toString()); System.out.println(page1.getTotal()); System.out.println("總頁數:"+page1.getTotal()); users1Mapper.selectAll().forEach(item->System.out.println(item)); System.out.println("=========================================================="); } }
ok 測試!!!!!!!
PageHelper文檔: https://pagehelper.github.io/
某個大神的SpringBoot 技術博客 :http://tengj.top/2017/02/26/springboot1/
★華麗分割線 ★ 結尾
教程結束!
喜歡該博文的同學和點贊關注ღ( ´・ᴗ・` )比心
文中如有不足,歡迎指正和討論!❤
作者QQ:1983127490
代碼以上傳碼雲
碼雲:https://gitee.com/gezi441/spring-boot-ibatis-mulidatasource









