From ae0526ce98503912fa778458b29d2cd586b2ec9d Mon Sep 17 00:00:00 2001 From: xuejiatao001 Date: Mon, 8 Mar 2021 00:36:40 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xjt/proxy/controller/UserController.java | 13 +++------ .../com/xjt/proxy/service/UserService.java | 19 ++++++------- src/main/resources/application.yml | 28 ++++++++++++++++--- .../xjt/proxy/service/UserServiceTest.java | 18 ++++++------ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/xjt/proxy/controller/UserController.java b/src/main/java/com/xjt/proxy/controller/UserController.java index c3cd432..492a2a8 100644 --- a/src/main/java/com/xjt/proxy/controller/UserController.java +++ b/src/main/java/com/xjt/proxy/controller/UserController.java @@ -20,13 +20,8 @@ public class UserController { @Autowired private UserService userService; - @RequestMapping("/list") - public List userList() { - return userService.listUser(); - } - - @RequestMapping("/update") - public int update() { - return userService.update(); - } +// @RequestMapping("/update") +// public int update() { +// return userService.update(); +// } } diff --git a/src/main/java/com/xjt/proxy/service/UserService.java b/src/main/java/com/xjt/proxy/service/UserService.java index cb29290..82a8ffc 100644 --- a/src/main/java/com/xjt/proxy/service/UserService.java +++ b/src/main/java/com/xjt/proxy/service/UserService.java @@ -1,5 +1,6 @@ package com.xjt.proxy.service; +import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -9,6 +10,8 @@ import com.xjt.proxy.dynamicdatasource.DataSourceSelector; import com.xjt.proxy.dynamicdatasource.DynamicDataSourceEnum; import com.xjt.proxy.mapper.UserMapper; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; /** * @author kevin @@ -20,24 +23,18 @@ public class UserService { @Autowired private UserMapper userMapper; - @DataSourceSelector(value = DynamicDataSourceEnum.SLAVE) - public List listUser() { - List users = userMapper.selectAll(); - return users; - } - @DataSourceSelector(value = DynamicDataSourceEnum.MASTER) - public int update() { + public int update(Long userId) { User user = new User(); - user.setUserId(Long.parseLong("1196978513958141952")); - user.setUserName("修改后的名字2"); + user.setUserId(userId); + user.setUserName("老薛"); return userMapper.updateByPrimaryKeySelective(user); } @DataSourceSelector(value = DynamicDataSourceEnum.SLAVE) - public User find() { + public User find(Long userId) { User user = new User(); - user.setUserId(Long.parseLong("1196978513958141952")); + user.setUserId(userId); return userMapper.selectByPrimaryKey(user); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5fb8d46..e5428ad 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -8,13 +8,13 @@ spring: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver master: - url: jdbc:mysql://127.0.0.1:3307/user?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true + url: jdbc:mysql://127.0.0.1:3307/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true username: root - password: + password: 123456 slave: - url: jdbc:mysql://127.0.0.1:3308/user?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true + url: jdbc:mysql://127.0.0.1:3308/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true username: root - password: + password: 123456 freemarker: template-loader-path: classpath:/templates cache: false @@ -25,3 +25,23 @@ spring: expose-session-attributes: true request-context-attribute: request suffix: .ftl + redis: + host: 127.0.0.1 + port: 6379 + password: + database: 11 + # pool: + # max-active: 100 + # max-wait: -1 + # max-idle: 20 + # min-idle: 10 + lettuce: + pool: + # 最大连接数 + max-active: 20 + # 最大能够保持idel状态的连接数 + max-idle: 20 + # 最小能够保持idel状态的连接数 + min-idle: 10 + # 当池内没有返回对象时,最大等待时间 + max-wait: 5000ms \ No newline at end of file diff --git a/src/test/java/com/xjt/proxy/service/UserServiceTest.java b/src/test/java/com/xjt/proxy/service/UserServiceTest.java index c608f69..c4bc5d7 100644 --- a/src/test/java/com/xjt/proxy/service/UserServiceTest.java +++ b/src/test/java/com/xjt/proxy/service/UserServiceTest.java @@ -22,19 +22,19 @@ class UserServiceTest { UserService userService; @Test - void listUser() { - List users = userService.listUser(); - for (User user : users) { - System.out.println(user.getUserId()); - System.out.println(user.getUserName()); - System.out.println(user.getUserPhone()); - } + void find() { + User user = userService.find(1196978513958141952L); + System.out.println("id:" + user.getUserId()); + System.out.println("name:" + user.getUserName()); + System.out.println("phone:" + user.getUserPhone()); } @Test void update() { - userService.update(); - User user = userService.find(); + Long userId = 1196978513958141952L; + userService.update(userId); + User user = userService.find(userId); System.out.println(user.getUserName()); } + } \ No newline at end of file From 64f48834c71ebf555ddc538d3c447340f6bce118 Mon Sep 17 00:00:00 2001 From: xuejiatao001 Date: Mon, 8 Mar 2021 01:14:53 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 0e71d80..ed02b07 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ ### 前言 -入职新公司到现在也有一个月了,完成了手头的工作,前几天终于有时间研究下公司旧项目的代码。在研究代码的过程中,发现项目里用到了Spring Aop来实现数据库的读写分离,本着自己爱学习(我自己都不信...)的性格,决定写个实例工程来实现spring aop读写分离的效果。 +相信有经验的同学都清楚,当db的读写量过高时,我们会备份一份或多份的从库用于做数据的读取,然后主库就主要承担写入的功能(也有读取需要,但压力不大),当db分好主从库后,我们还需要在项目实现自动连接主从库,达到读写分离的效果。实现读写分离并不困难,只要在数据库连接池手动控制好对应的db服务地址即可,但那样就会侵入业务代码,而且一个项目操作数据库的地方可能很多,如果都手动控制的话无疑会是很大的工作量,对此,我们有必要改造出一套方便的工具。 + +以Java语言来说,如今大部分的项目都是基于Spring Boot框架来搭建项目架构的,结合Spring本身自带的AOP工具,我们可以很容易就构建能实现读写分离效果的注解类,用注解的话可以达到对业务代码无入侵的效果,而且使用上也比较方便。 + +下面就简单带大家写个demo。 ### 环境部署 @@ -300,30 +304,24 @@ public class UserService { @Autowired private UserMapper userMapper; - @DataSourceSelector(value = DynamicDataSourceEnum.SLAVE) - public List listUser() { - List users = userMapper.selectAll(); - return users; - } - @DataSourceSelector(value = DynamicDataSourceEnum.MASTER) - public int update() { + public int update(Long userId) { User user = new User(); - user.setUserId(Long.parseLong("1196978513958141952")); - user.setUserName("修改后的名字2"); + user.setUserId(userId); + user.setUserName("老薛"); return userMapper.updateByPrimaryKeySelective(user); } @DataSourceSelector(value = DynamicDataSourceEnum.SLAVE) - public User find() { + public User find(Long userId) { User user = new User(); - user.setUserId(Long.parseLong("1196978513958141952")); + user.setUserId(userId); return userMapper.selectByPrimaryKey(user); } } ``` -根据方法上的注解可以看出,读的方法走从库,更新的方法走主库,更新的对象是userId为`1196978513958141953` 的数据, +根据方法上的注解可以看出,读的方法走从库,更新的方法走主库,更新的对象是userId为`1196978513958141952` 的数据, 然后我们写个测试类测试下是否能达到效果, @@ -336,18 +334,18 @@ class UserServiceTest { UserService userService; @Test - void listUser() { - List users = userService.listUser(); - for (User user : users) { - System.out.println(user.getUserId()); - System.out.println(user.getUserName()); - System.out.println(user.getUserPhone()); - } + void find() { + User user = userService.find(1196978513958141952L); + System.out.println("id:" + user.getUserId()); + System.out.println("name:" + user.getUserName()); + System.out.println("phone:" + user.getUserPhone()); } + @Test void update() { - userService.update(); - User user = userService.find(); + Long userId = 1196978513958141952L; + userService.update(userId); + User user = userService.find(userId); System.out.println(user.getUserName()); } } @@ -357,11 +355,11 @@ class UserServiceTest { 1、读取方法 -![](https://img2018.cnblogs.com/blog/1478697/201911/1478697-20191126155931637-570944204.png) +![](https://img2020.cnblogs.com/blog/1478697/202103/1478697-20210308011010913-474866408.png) 2、更新方法 -![](https://img2018.cnblogs.com/blog/1478697/201911/1478697-20191126155943958-1951310412.png) +![](https://img2020.cnblogs.com/blog/1478697/202103/1478697-20210308011019315-236391720.png) 执行之后,比对数据库就可以发现主从库都修改了数据,说明我们的读写分离是成功的。当然,更新方法可以指向从库,这样一来就只会修改到从库的数据,而不会涉及到主库。