4.0.0com.wdhspringboot-read-write-split-mysql0.0.1-SNAPSHOTspringboot-read-write-split-mysqlDemo project for Spring Boot1.8UTF-8UTF-82.3.7.RELEASEorg.springframework.bootspring-boot-starter-weborg.projectlomboklomboktrueorg.apache.commonscommons-lang3org.springframework.bootspring-boot-starter-aoporg.springframework.bootspring-boot-starter-data-jdbcorg.springframework.bootspring-boot-starter-jdbcorg.mybatis.spring.bootmybatis-spring-boot-starter2.1.4mysqlmysql-connector-java8.0.22org.springframework.bootspring-boot-starter-testtestorg.junit.vintagejunit-vintage-engineorg.springframework.bootspring-boot-dependencies${spring-boot.version}pomimportorg.apache.maven.pluginsmaven-compiler-plugin3.8.11.81.8UTF-8org.springframework.bootspring-boot-maven-plugin2.3.7.RELEASEcom.wdh.springbootreadwritesplitmysql.SpringbootReadWriteSplitMysqlApplicationrepackagerepackageorg.mybatis.generatormybatis-generator-maven-plugin1.3.1src\main\resources\mybatis-generator\generatorConfig.xmlfalsetrue
MyBatisConfig.java代码如下。(这里有个坑,报错是【FileNotFoundException: class path resource [mappers/*.xml] cannot be opened because it does not exist】,原因是,要写成getResources 不要误写成getResource,见注释)
package com.wdh.springbootreadwritesplitmysql.config;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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 org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;
import javax.sql.DataSource;/*** @author WangDH* @create 2022-11-10 14:26*/
@EnableTransactionManagement
@Configuration
public class MyBatisConfig {@Resource(name="myRoutingDataSource") //@Resource默认按byName自动注入private DataSource myRoutingDataSource;@Beanpublic SqlSessionFactory sqlSessionFactory() throws Exception{///org.springframework.core.io.Resource resourceMappersXml=new PathMatchingResourcePatternResolver().getResource("classpath:mappers/*.xml");//上述代码报错:Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'class path resource [mappers/*.xml]'; nested exception is java.io.FileNotFoundException: class path resource [mappers/*.xml] cannot be opened because it does not existorg.springframework.core.io.Resource[] resourceMappersXml=new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml");//注意这里是getResources 不要误写成getResource//参考https://www.cnblogs.com/jev-0987/p/12839193.html//getResource(): //1.从类的根路径下获取文件//getResources(): //1.获取所有类路径下的指定文件SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(myRoutingDataSource);sqlSessionFactoryBean.setMapperLocations(resourceMappersXml);SqlSessionFactory sqlSessionFactory= sqlSessionFactoryBean.getObject();return sqlSessionFactory;}@Beanpublic PlatformTransactionManager platformTransactionManager(){return new DataSourceTransactionManager(myRoutingDataSource);}}
package com.wdh.springbootreadwritesplitmysql.mapper;import com.wdh.springbootreadwritesplitmysql.entity.Products;import java.util.List;public interface ProductsMapper {/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/int deleteByPrimaryKey(Integer prdId);/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/int insert(Products record);/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/int insertSelective(Products record);/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/Products selectByPrimaryKey(Integer prdId);//wdh自定义增加的查询函数,需要ProductsMapper.xml有配置selectAll查询sqlList selectAll();/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/int updateByPrimaryKeySelective(Products record);/*** This method was generated by MyBatis Generator.* This method corresponds to the database table products** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/int updateByPrimaryKey(Products record);
}
package com.wdh.springbootreadwritesplitmysql.entity;import lombok.Data;import java.util.Date;@Data
public class Products {/*** This field was generated by MyBatis Generator.* This field corresponds to the database column products.prd_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/private Integer prdId;/*** This field was generated by MyBatis Generator.* This field corresponds to the database column products.prd_name** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/private String prdName;/*** This field was generated by MyBatis Generator.* This field corresponds to the database column products.prd_price** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/private Long prdPrice;/*** This field was generated by MyBatis Generator.* This field corresponds to the database column products.prd_date** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/private Date prdDate;/*** This field was generated by MyBatis Generator.* This field corresponds to the database column products.cat_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/private Integer catId;/*** This method was generated by MyBatis Generator.* This method returns the value of the database column products.prd_id** @return the value of products.prd_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public Integer getPrdId() {return prdId;}/*** This method was generated by MyBatis Generator.* This method sets the value of the database column products.prd_id** @param prdId the value for products.prd_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public void setPrdId(Integer prdId) {this.prdId = prdId;}/*** This method was generated by MyBatis Generator.* This method returns the value of the database column products.prd_name** @return the value of products.prd_name** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public String getPrdName() {return prdName;}/*** This method was generated by MyBatis Generator.* This method sets the value of the database column products.prd_name** @param prdName the value for products.prd_name** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public void setPrdName(String prdName) {this.prdName = prdName == null ? null : prdName.trim();}/*** This method was generated by MyBatis Generator.* This method returns the value of the database column products.prd_price** @return the value of products.prd_price** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public Long getPrdPrice() {return prdPrice;}/*** This method was generated by MyBatis Generator.* This method sets the value of the database column products.prd_price** @param prdPrice the value for products.prd_price** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public void setPrdPrice(Long prdPrice) {this.prdPrice = prdPrice;}/*** This method was generated by MyBatis Generator.* This method returns the value of the database column products.prd_date** @return the value of products.prd_date** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public Date getPrdDate() {return prdDate;}/*** This method was generated by MyBatis Generator.* This method sets the value of the database column products.prd_date** @param prdDate the value for products.prd_date** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public void setPrdDate(Date prdDate) {this.prdDate = prdDate;}/*** This method was generated by MyBatis Generator.* This method returns the value of the database column products.cat_id** @return the value of products.cat_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public Integer getCatId() {return catId;}/*** This method was generated by MyBatis Generator.* This method sets the value of the database column products.cat_id** @param catId the value for products.cat_id** @mbggenerated Thu Nov 10 16:13:23 CST 2022*/public void setCatId(Integer catId) {this.catId = catId;}
}
验证读写分离
背景,主库和从库中Products表的数据行数是不一样的。主库此表内记录多,从库此表内记录少。
如果执行方法可以根据@Master或@Slave实现读写分离,目的即为达成。
验证前准备:主从两个数据库已启动且可访问。
启动springboot,IDEA控制台打印的成功日志如下
"C:\Program Files\Java\jdk1.8.0_111\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:D:\JavaDevEnv\JetBrains\IntelliJ IDEA 2018.3.6\lib\idea_rt.jar=62267:D:\JavaDevEnv\JetBrains\IntelliJ IDEA 2018.3.6\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\JavaWorkspace\IdeaProjects\SpringInAction\springboot-read-write-split-mysql\target\classes;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-web\2.3.7.RELEASE\spring-boot-starter-web-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter\2.3.7.RELEASE\spring-boot-starter-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot\2.3.7.RELEASE\spring-boot-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-autoconfigure\2.3.7.RELEASE\spring-boot-autoconfigure-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-logging\2.3.7.RELEASE\spring-boot-starter-logging-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\JavaDevEnv\maven_repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\JavaDevEnv\maven_repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;D:\JavaDevEnv\maven_repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;D:\JavaDevEnv\maven_repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\JavaDevEnv\maven_repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\JavaDevEnv\maven_repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-json\2.3.7.RELEASE\spring-boot-starter-json-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.7.RELEASE\spring-boot-starter-tomcat-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.41\tomcat-embed-core-9.0.41.jar;D:\JavaDevEnv\maven_repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\JavaDevEnv\maven_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.41\tomcat-embed-websocket-9.0.41.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-web\5.2.12.RELEASE\spring-web-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-beans\5.2.12.RELEASE\spring-beans-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-webmvc\5.2.12.RELEASE\spring-webmvc-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-context\5.2.12.RELEASE\spring-context-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-expression\5.2.12.RELEASE\spring-expression-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\projectlombok\lombok\1.18.16\lombok-1.18.16.jar;D:\JavaDevEnv\maven_repository\org\apache\commons\commons-lang3\3.10\commons-lang3-3.10.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-aop\2.3.7.RELEASE\spring-boot-starter-aop-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-aop\5.2.12.RELEASE\spring-aop-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-data-jdbc\2.3.7.RELEASE\spring-boot-starter-data-jdbc-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\data\spring-data-jdbc\2.0.6.RELEASE\spring-data-jdbc-2.0.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\data\spring-data-relational\2.0.6.RELEASE\spring-data-relational-2.0.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\data\spring-data-commons\2.3.6.RELEASE\spring-data-commons-2.3.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-tx\5.2.12.RELEASE\spring-tx-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-jdbc\2.3.7.RELEASE\spring-boot-starter-jdbc-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\com\zaxxer\HikariCP\3.4.5\HikariCP-3.4.5.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-jdbc\5.2.12.RELEASE\spring-jdbc-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\2.1.4\mybatis-spring-boot-starter-2.1.4.jar;D:\JavaDevEnv\maven_repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\2.1.4\mybatis-spring-boot-autoconfigure-2.1.4.jar;D:\JavaDevEnv\maven_repository\org\mybatis\mybatis\3.5.6\mybatis-3.5.6.jar;D:\JavaDevEnv\maven_repository\org\mybatis\mybatis-spring\2.0.6\mybatis-spring-2.0.6.jar;D:\JavaDevEnv\maven_repository\Mysql\mysql-connector-java\8.0.22\mysql-connector-java-8.0.22.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-core\5.2.12.RELEASE\spring-core-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-jcl\5.2.12.RELEASE\spring-jcl-5.2.12.RELEASE.jar" com.wdh.springbootreadwritesplitmysql.SpringbootReadWriteSplitMysqlApplication. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.3.7.RELEASE)2022-11-11 16:43:26.762 INFO 2452 --- [ main] SpringbootReadWriteSplitMysqlApplication : Starting SpringbootReadWriteSplitMysqlApplication on 14JPYI7CBESDNFK with PID 2452 (D:\JavaWorkspace\IdeaProjects\SpringInAction\springboot-read-write-split-mysql\target\classes started by Administrator in D:\JavaWorkspace\IdeaProjects\SpringInAction\springboot-read-write-split-mysql)
2022-11-11 16:43:26.762 INFO 2452 --- [ main] SpringbootReadWriteSplitMysqlApplication : No active profile set, falling back to default profiles: default
2022-11-11 16:43:28.525 INFO 2452 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-11 16:43:28.541 INFO 2452 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-11 16:43:28.541 INFO 2452 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2022-11-11 16:43:28.606 INFO 2452 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-11 16:43:28.606 INFO 2452 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1781 ms
2022-11-11 16:43:30.028 INFO 2452 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2022-11-11 16:43:30.511 INFO 2452 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-11 16:43:30.511 INFO 2452 --- [ main] SpringbootReadWriteSplitMysqlApplication : Started SpringbootReadWriteSplitMysqlApplication in 4.093 seconds (JVM running for 4.693)