分庫分表之_讀寫分離

前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、開始Demo

1.1、hlj-01-read-write.sql

drop database if exists ds_0;
create database `ds_0` character set 'utf8' collate 'utf8_general_ci';
use ds_0;

drop table if exists user;
create table `user`
(
  `id`        bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (`id`)
) engine = innodb
  default charset = utf8;


drop database if exists ds_1;
create database `ds_1` character set 'utf8' collate 'utf8_general_ci';
use ds_1;
drop table if exists user;
create table `user`
(
  `id`        bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (`id`)
) engine = innodb
  default charset = utf8;

1.1.1、數據庫圖文

1585554177489

1.2、依賴


<!--shardingsphere-->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</version>
</dependency>

1.3、配置文件:application.properties

server.port=8888


# 配置 mybatis的一些配置,也可以在 application.properties 中配置,如果配置了就不需要了mybatis.xml
#mybatis-plus.config-location=classpath:mybatis.xml
#Maven 多模塊項目的掃描路徑需以 classpath*: 開頭 (即加載多個 jar 包下的 XML 文件)
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
mybatis-plus.type-aliases-package=com.healerjean.proj.pojo
##主鍵類型  0:"數據庫ID自增,非常大", 1:"用戶輸入ID",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
mybatis-plus.id-type: 0
#字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
mybatis-plus.field-strategy: 2
#數據庫大寫下劃線轉換
mybatis-plus.capital-mode: true
mybatis-plus.refresh-mapper: true




# 顯示SQL
spring.shardingsphere.props.sql.show=true
# #當遇到同樣名字的時候,是否允許覆蓋註冊
spring.main.allow-bean-definition-overriding=true

# 讀寫分離 數據源定義(會向主數據庫中插入數據,但是查詢的話是從從表查的(不會出現主從複製的情況哦))
spring.shardingsphere.datasource.names=master,slave
# 主數據源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 從數據源
spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave.url=jdbc:mysql://localhost:3306/ds_1?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.slave.username=root
spring.shardingsphere.datasource.slave.password=123456

# 讀寫分離配置
spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
# 最終的數據源名稱
spring.shardingsphere.masterslave.name=dataSource
# 主庫數據源名稱
spring.shardingsphere.masterslave.master-data-source-name=master
# 從庫數據源名稱列表,多個逗號分隔
spring.shardingsphere.masterslave.slave-data-source-names=slave

1.4、具體測試方法和類

1.4.1、User.java

@Data
@Accessors(chain = true)
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 主鍵  */
    private Long id;
    private String name;
    private String city;
    private String status;
    private Date createTime;
    private Date updateTime;
}

1.4.2、UserDTO.java

@Data
@Accessors(chain = true)
@ApiModel(value = "demo實體類")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserDTO {

    @ApiModelProperty(value = "主鍵", hidden = true)
    @JsonSerialize(using = JsonLongSerializer.class )
    private Long id;

    @ApiModelProperty(value = "姓名")
    @NotBlank(message = "姓名不能爲空", groups = ValidateGroup.HealerJean.class)
    private String name;

    @ApiModelProperty(value = "城市")
    private String city;

    @ApiModelProperty(value = "狀態", hidden = true)
    private String status;

    @ApiModelProperty(value = "創建時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date createTime;

    @ApiModelProperty(value = "修改時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date updateTime;
}

1.4.3、UserMapper.java

public interface UserMapper extends BaseMapper<User> {


}

1.4.4、UserService.java

public interface UserService {


    UserDTO insert(UserDTO userDTO);

    UserDTO findById(Long id);

    List<UserDTO> list();

}

1.4.5、UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;


    @Override
    public UserDTO insert(UserDTO userDTO) {
        User user = BeanUtils.dtoToUserDTO(userDTO);
        user.setStatus(StatusEnum.生效.code);
        userMapper.insert(user);
        userDTO.setId(user.getId());
        return userDTO;
    }

    @Override
    public UserDTO findById(Long id) {
        User user = userMapper.selectById(id);
        return user == null ? null : BeanUtils.userToDTO(user);
    }

    @Override
    public List<UserDTO> list() {
        List<User> users = userMapper.selectList(null);
        List<UserDTO> list = null;
        if (!EmptyUtil.isEmpty(users)) {
            list = users.stream().map(BeanUtils::userToDTO).collect(Collectors.toList());
        }
        return list;
    }

}

1.4.6、UserController.java

@ApiResponses(value = {
        @ApiResponse(code = 200, message = "訪問正常"),
        @ApiResponse(code = 301, message = "邏輯錯誤"),
        @ApiResponse(code = 500, message = "系統錯誤"),
        @ApiResponse(code = 401, message = "未認證"),
        @ApiResponse(code = 403, message = "禁止訪問"),
        @ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/demo")
@Slf4j
public class UserController {



    @Autowired
    private UserService userService;

    @ApiOperation(value = "insert",
            notes = "insert",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @PostMapping(value = "insert", produces = "application/json; charset=utf-8")
    @ResponseBody
    public ResponseBean insert(UserDTO userDTO) {
        log.info("樣例--------mybaits-plus添加demo實體------數據信息{}", userDTO);
        String validate = ValidateUtils.validate(userDTO, ValidateGroup.HealerJean.class);
        if (!validate.equals(CommonConstants.COMMON_SUCCESS)) {
            throw new BusinessException(ResponseEnum.參數錯誤, validate);
        }
        return ResponseBean.buildSuccess(userService.insert(userDTO));
    }


    @ApiOperation(notes = "findById",
            value = "findById",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
    })
    @GetMapping("findById/{id}")
    @ResponseBody
    public ResponseBean findById(@PathVariable Long id) {
        log.info("樣例--------findById------數據:id:{}", id);
        return ResponseBean.buildSuccess(userService.findById(id));
    }

    @ApiOperation(notes = "list",
            value = "list",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("list")
    @ResponseBody
    public ResponseBean list() {
        log.info("樣例--------list------");
        return ResponseBean.buildSuccess(userService.list());
    }


}

1.5、開始測試

1.5.1、插入數據: /hlj/demo/insert

1.5.1.1、測試數據

name city
1 a
2 b
3 c
4 d
5 c
6 d

1.5.1.2、查詢數據庫中插入的數據

1.5.1.2.1、查詢數據庫ds_0、user表
sql> select * from ds_0.user
[2020-03-30 15:49:57] 6 rows retrieved starting from 1 in 431 ms (execution: 9 ms, fetching: 422 ms)
idcitynamestatuscreate_timeupdate_time
1244531596683517954a1102020-03-30 15:47:092020-03-30 15:47:09
1244531609899769858b2102020-03-30 15:47:122020-03-30 15:47:12
1244531634532917249c3102020-03-30 15:47:182020-03-30 15:47:18
1244531650509021186d4102020-03-30 15:47:222020-03-30 15:47:22
1244531672914993153c5102020-03-30 15:47:272020-03-30 15:47:27
1244531711733276673d6102020-03-30 15:47:372020-03-30 15:47:37
1.5.1.2.2、查詢數據庫ds1_1、user表
sql> select * from ds_1.user
[2020-03-30 15:50:31] 0 rows retrieved in 63 ms (execution: 8 ms, fetching: 55 ms)

發現爲空

1.5.1.3、歸納總結

我們發現所有的數據全部到了ds_0user表中,因爲是讀寫分離,ds_0是主表,用來寫的表。而讀表則是ds_1中的user表,讀寫分離測試成功

1.5.2、根據Id查詢:/hlj/demo/findById

1.5.2.1、測試數據

1.5.2.1.1、Id:1244531596683517954
http://127.0.0.1:8888/hlj/demo/findById/1244531596683517954

{
  "success": true,
  "result": null,
  "msg": "",
  "code": 200,
  "date": "1585554914827"
}


1.5.2.1.2、Id:1244531609899769858
http://127.0.0.1:8888/hlj/demo/findById/1244531596683517954


{
  "success": true,
  "result": null,
  "msg": "",
  "code": 200,
  "date": "1585554965412"
}

1.5.2.2、歸納總結

可以看到查詢出來的數據是空的,所以可以驗證我們的讀寫分離配置正確,因爲我們沒有網ds_1庫的user表放入數據,所以查不到數據 ,讀寫分離測試成功

1.5.2.2.1、驗證歸納

爲了驗證,我將id1244531596683517954的數據放到ds_1user表中進行測試,查詢成功

http://127.0.0.1:8888/hlj/demo/findById/1244531596683517954


{
  "success": true,
  "result": {
    "id": "1244531596683517954",
    "name": "1",
    "city": "a",
    "status": "10",
    "createTime": "2020-03-30 15:47:09",
    "updateTime": "2020-03-30 15:47:09"
  },
  "msg": "",
  "code": 200,
  "date": "1585555387337"
}

1.5.3、List查詢:/hlj/demo/list

1.5.3.1、測試

繼續使用1.5.2.2.1中的數據,在數據庫ds_1的表user中插入的數據,id爲:1244531596683517954

http://127.0.0.1:8888/hlj/demo/list

{
  "success": true,
  "result": [
    {
      "id": "1244531596683517954",
      "name": "1",
      "city": "a",
      "status": "10",
      "createTime": "2020-03-30 15:47:09",
      "updateTime": "2020-03-30 15:47:09"
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585555442095"
}

1.5.3.2、歸納總結

發現只有一條數據,而這條數據使我手動放到數據庫ds_1的表user中的,讀寫分離測試成功

ContactAuthor

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章