在本文中使用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的查詢。
讀寫分離的好處就是在並發量比較大的情況下,將查詢數據庫的壓力分擔到多個從庫中,能夠滿足高並發的要求。如下圖