前言
Github:https://github.com/HealerJean
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、數據庫圖文
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)
id | city | name | status | create_time | update_time |
---|---|---|---|---|---|
1244531596683517954 | a | 1 | 10 | 2020-03-30 15:47:09 | 2020-03-30 15:47:09 |
1244531609899769858 | b | 2 | 10 | 2020-03-30 15:47:12 | 2020-03-30 15:47:12 |
1244531634532917249 | c | 3 | 10 | 2020-03-30 15:47:18 | 2020-03-30 15:47:18 |
1244531650509021186 | d | 4 | 10 | 2020-03-30 15:47:22 | 2020-03-30 15:47:22 |
1244531672914993153 | c | 5 | 10 | 2020-03-30 15:47:27 | 2020-03-30 15:47:27 |
1244531711733276673 | d | 6 | 10 | 2020-03-30 15:47:37 | 2020-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_0
的user
表中,因爲是讀寫分離,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、驗證歸納
爲了驗證,我將id
爲1244531596683517954
的數據放到ds_1
的user
表中進行測試,查詢成功
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
中的,讀寫分離測試成功