在本文中使用Spring Boot 2.4.1+MyBatis-plus+Druid+Sharding-JDBC+MySQL进行读写分离的案件讲解。
1、数据库准备
1、192.168.8.162 test1主
2、192.168.8.134 test1从
3、192.168.8.176 test1从
2、上代码
1、pom.xml配置引入maven依赖
<properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <druid.version>1.1.9</druid.version> <mybatis-plus.version>3.1.1</mybatis-plus.version> <mybatis-plus-stater.version>3.1.2</mybatis-plus-stater.version> <lombok.version>1.16.18</lombok.version> <mybatisplus-spring-boot-starter.version>1.0.5</mybatisplus-spring-boot-starter.version> </properties> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- Mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatisplus-spring-boot-starter</artifactId> <version>${mybatisplus-spring-boot-starter.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus-stater.version}</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency>
2、在application.yml中配置使用mybatis-plus及引用数据源
#### spring #### spring: # 配置说明地址 https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/configuration/config-spring-boot/#%E6%95%B0%E6%8D%AE%E5%88%86%E7%89%87 shardingsphere: # 数据库 datasource: # 数据库的别名 names: ds0,ds1,ds2 # 主库1 ,master数据库 ds0: ### 数据源类别 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.8.162:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8 username: root password: root # 从库1 ,slave数据库 ds1: ### 数据源类别 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.8.134:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8 username: root password: root # 从库2 ,slave数据库 ds2: ### 数据源类别 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.8.176:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8 username: root password: root # *** 数据库分库分表配置 start masterslave: # 查询时的负载均衡算法,目前有2种算法,round_robin(轮询)和random(随机), # 算法接口是io.shardingjdbc.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithm。 # 实现类有RandomMasterSlaveLoadBalanceAlgorithm 和 RoundRobinMasterSlaveLoadBalanceAlgorithm。 load-balance-algorithm-type: round_robin name: dataSource # 主数据源名称 master-data-source-name: ds0 # 从数据源名称,多个用逗号隔开 slave-data-source-names: ds1,ds2 # *** 数据库分库分表配置 end props: # 打印SQL sql: show: true check: table: metadata: true # 是否在启动时检查分表元数据一致性 enabled: true query: with: cipher: column: true #### mybatis-plus ### mybatis-plus: # 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml # 如果是放在resource目录 classpath:/mapper/*Mapper.xml mapper-locations: classpath:mapper/*.xml #实体扫描,多个package用逗号或者分号分隔 type-aliases-package: com.demo.shardingjdbc.entity configuration: map-underscore-to-camel-case: true cache-enabled: false #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; global-config: db-config: id-type: auto #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" field-strategy: not_empty #驼峰下划线转换 column-underline: true #逻辑删除配置 logic-delete-value: 0 logic-not-delete-value: 1 db-type: mysql #刷新mapper 调试神器 refresh: false
3、mybatis-plus操作数据库配置
User.jar
package com.demo.shardingjdbc.entity; import java.io.Serializable; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * @Description: (User)实体类 */ @Data @TableName("t_user") public class User implements Serializable { private static final long serialVersionUID = 358157380505039579L; /** * 用户id */ @TableField("id") private Integer id; /** * 用户名称 */ @TableField("name") private String name; /** * 性别 */ @TableField("sex") private String sex; }
mybatis-plus配置MybatisPlusConfig
package com.demo.shardingjdbc.config; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * @Description: */ //Spring boot方式 @EnableTransactionManagement @Configuration //扫描的mapper文件路径 @MapperScan(value = "com.demo.shardingjdbc.mapper") public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
mapper层
package com.demo.shardingjdbc.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.demo.shardingjdbc.entity.User; /** * (T_User)表数据库访问层 * */ public interface UserMapper extends BaseMapper<User> { }
controller控制层
package com.demo.shardingjdbc.controller; import java.util.List; import org.apache.shardingsphere.api.hint.HintManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.demo.shardingjdbc.entity.User; import com.demo.shardingjdbc.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; /** * @ClassName TestController * @Description TestController * @Version */ @RestController @Slf4j public class TestController { /** * user mapper */ @Autowired private UserMapper userMapper; /** * 用户列表 */ @RequestMapping("userList") public List<User> userList() { log.info("********TestController userList()"); List<User> users = userMapper.selectList(null); return users; } /** * 用户列表,强制路由主库 */ @RequestMapping("userListDs0") public List<User> userListDs0() { log.info("********TestController userListDs0():强制路由主库"); HintManager hintManager = HintManager.getInstance(); hintManager.setDatabaseShardingValue("ds0"); List<User> users = userMapper.selectList(null); //清除分片键值,分片键值保存在ThreadLocal中,所以需要在操作结束时调用hintManager.close()来清除ThreadLocal中的内容。hintManager实现了AutoCloseable接口,可推荐使用try with resource自动关闭。 hintManager.close(); List<User> users1 = userMapper.selectList(null); users.addAll(users1); return users; } /** * 保存用户 * * @return */ @PostMapping("save") public int save(User user) { log.info("********save User"); int insert = userMapper.insert(user); return insert; } }
完成。用Sharding-JDBC实现了数据库的读写分离,对192.168.8.162 test1中t_user的操作,对92.168.8.134 test1,92.168.8.134 test1中t_user的查询。
读写分离的好处就是在并发量比较大的情况下,将查询数据库的压力分担到多个从库中,能够满足高并发的要求。如下图