Springboot整合Shardingjdbc实现读写分离
AI-摘要
Zpeng GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
本文最后更新于 2024-04-18,欢迎来到我的Blog! https://www.zpeng.site/
Springboot整合Shardingjdbc实现读写分离
1、pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2、application.yml
server:
port: 8080
spring:
application:
name: readwritesplitting
main:
allow-bean-definition-overriding: true
shardingsphere:
# 参数配置,显示sql
props:
sql:
show: true
# 配置数据源
datasource:
# 给每个数据源取别名,下面的ds1,ds2任意取名字
names: master, slave0, slave1
# 给master-ds1每个数据源配置数据库连接信息
master:
# 配置druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/master_db?useUnicode=true&characterEncoding=utf-8
username: root
password: root
maxPoolSize: 100
minPoolSize: 5
# 配置ds2-slave
slave0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/slave0_db?useUnicode=true&characterEncoding=utf-8
username: root
password: root
maxPoolSize: 100
minPoolSize: 5
# 配置ds3-slave
slave1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/slave1_db?useUnicode=true&characterEncoding=utf-8
username: root
password: root
maxPoolSize: 100
minPoolSize: 5
# 配置默认数据源ds1
sharding:
# 默认数据源,主要用于写,注意一定要配置读写分离 ,注意:如果不配置,那么就会把三个节点都当做从slave节点,新增,修改和删除会出错。
default-data-source-name: master
# 配置数据源的读写分离,但是数据库一定要做主从复制
masterslave:
# 配置主从名称,可以任意取名字
name: ms
# 配置主库master,负责数据的写入
master-data-source-name: master
# 配置从库slave节点
slave-data-source-names: slave0,slave1
# 配置slave节点的负载均衡均衡策略,采用轮询机制
load-balance-algorithm-type: round_robin
#mybatis配置信息
mybatis:
# xml映射文件所在的路径,一般用模糊匹配来指定最终的xml文件
mapper-locations: classpath:/mapper/*.xml
configuration:
#采用驼峰形式将数据表中以‘_’分隔的字段映射到java类的某个属性,比如表字段user_name可以映射为类里面的userName属性
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3、sql
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`user_name` varchar(30) NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
`user_type` varchar(2) DEFAULT '00' COMMENT '用户类型(00系统用户)',
`email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
`phonenumber` varchar(11) DEFAULT '' COMMENT '手机号码',
`sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
`avatar` varchar(100) DEFAULT '' COMMENT '头像地址',
`password` varchar(100) DEFAULT '' COMMENT '密码',
`status` char(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb3 COMMENT='用户信息表';
4、code
SysUser
package com.example.readwritesplitting.demo;
import lombok.Data;
import java.util.Date;
/**
* @ClassName SysUser
* @Description:
* @Author: zpeng
* @CreateDate: 2024/4/17 11:56
*/
@Data
public class SysUser {
private Long userId;
private Long deptId;
private String userName;
private String nickName;
private String userType;
private String email;
private String phonenumber;
private String sex;
private String avatar;
private String password;
private String status;
private String delFlag;
private String loginIp;
private Date loginDate;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private String remark;
// Getters and Setters
// Optionally, add constructors, validation annotations, and/or toString() method
}
SysUserController
package com.example.readwritesplitting.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName SysUserController
* @Description:
* @Author: zpeng
* @CreateDate: 2024/4/17 12:01
*/
@RestController
@RequestMapping("/api/sys/users")
public class SysUserController {
private final SysUserService sysUserService;
@Autowired
public SysUserController(SysUserService sysUserService) {
this.sysUserService = sysUserService;
}
@PostMapping("/add")
public int insert(@RequestBody SysUser sysUser) {
return sysUserService.insert(sysUser);
}
@DeleteMapping("/delete/{userId}")
public int deleteByPrimaryKey(@PathVariable("userId") Long userId) {
return sysUserService.deleteByPrimaryKey(userId);
}
@PutMapping("/update")
public int updateByPrimaryKeySelective(@RequestBody SysUser sysUser) {
return sysUserService.updateByPrimaryKeySelective(sysUser);
}
@GetMapping("/select/{userId}")
public SysUser selectByPrimaryKey(@PathVariable("userId") Long userId) {
return sysUserService.selectByPrimaryKey(userId);
}
@GetMapping("/selectAll")
public List<SysUser> selectAll() {
return sysUserService.selectAll();
}
// Add additional controller methods for more complex operations if needed
}
SysUserService
package com.example.readwritesplitting.demo;
/**
* @ClassName SysUserService
* @Description:
* @Author: zpeng
* @CreateDate: 2024/4/17 12:00
*/
import java.util.List;
public interface SysUserService {
int insert(SysUser sysUser);
int deleteByPrimaryKey(Long userId);
int updateByPrimaryKeySelective(SysUser sysUser);
SysUser selectByPrimaryKey(Long userId);
List<SysUser> selectAll();
// Additional service methods if needed
}
SysUserServiceImpl
package com.example.readwritesplitting.demo;
/**
* @ClassName SysUserServiceImpl
* @Description:
* @Author: zpeng
* @CreateDate: 2024/4/17 12:01
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysUserServiceImpl implements SysUserService {
private final SysUserMapper sysUserMapper;
@Autowired
public SysUserServiceImpl(SysUserMapper sysUserMapper) {
this.sysUserMapper = sysUserMapper;
}
@Override
public int insert(SysUser sysUser) {
return sysUserMapper.insert(sysUser);
}
@Override
public int deleteByPrimaryKey(Long userId) {
return sysUserMapper.deleteByPrimaryKey(userId);
}
@Override
public int updateByPrimaryKeySelective(SysUser sysUser) {
return sysUserMapper.updateByPrimaryKeySelective(sysUser);
}
@Override
public SysUser selectByPrimaryKey(Long userId) {
return sysUserMapper.selectByPrimaryKey(userId);
}
@Override
public List<SysUser> selectAll() {
return sysUserMapper.selectAll();
}
// Implement additional service methods if needed
}
SysUserMapper.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="com.example.readwritesplitting.demo.SysUserMapper">
<insert id="insert" parameterType="com.example.readwritesplitting.demo.SysUser">
INSERT INTO sys_user
(dept_id, user_name, nick_name, user_type, email, phonenumber, sex, avatar, password,
status, del_flag, login_ip, login_date, create_by, create_time, update_by, update_time, remark)
VALUES (#{deptId}, #{userName}, #{nickName}, #{userType}, #{email}, #{phonenumber},
#{sex}, #{avatar}, #{password}, #{status}, #{delFlag}, #{loginIp},
#{loginDate}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{remark})
</insert>
<delete id="deleteByPrimaryKey" parameterType="long">
DELETE
FROM sys_user
WHERE user_id = #{userId}
</delete>
<update id="updateByPrimaryKeySelective" parameterType="com.example.readwritesplitting.demo.SysUser">
UPDATE sys_user
<set>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="userName != null">user_name = #{userName},</if>
<!-- Add similar conditions for other fields -->
<if test="updateTime != null">update_time = #{updateTime}</if>
</set>
WHERE user_id = #{userId}
</update>
<select id="selectByPrimaryKey" parameterType="long" resultType="com.example.readwritesplitting.demo.SysUser">
SELECT *
FROM sys_user
WHERE user_id = #{userId}
</select>
<select id="selectAll" resultType="com.example.readwritesplitting.demo.SysUser">
SELECT *
FROM sys_user
</select>
<!-- Additional query mappings if needed -->
</mapper>
测试
启动
2024-04-17 15:18:47.109 INFO 4924 --- [ main] o.a.s.core.log.ConfigurationLogger : MasterSlaveRuleConfiguration:
loadBalanceAlgorithmType: round_robin
masterDataSourceName: master
name: ms
slaveDataSourceNames:
- slave0
- slave1
2024-04-17 15:18:47.111 INFO 4924 --- [ main] o.a.s.core.log.ConfigurationLogger : Properties:
sql.show: 'true'
读
http://localhost:8080/api/sys/users/select/1
使用的轮询测略
写
http://localhost:8080/api/sys/users/add
写走master
{
"userId": "9999",
"userName": "tempor",
"nickName": "nick_name"
}
数据一致性
MySQL数据库的主从复制是一种常见的数据备份和高可用性解决方案。通过配置主从复制,可以实现将数据从一个MySQL服务器(主服务器)同步到另一个(从服务器),从而提高数据库的可用性和性能。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zpeng
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果