【SpringBoot】Spring data JPA整合ShardingSphere-JDBC静态读写分离实现

大佬栽树,我乘凉

许大仙老师:【yuque.com/fairy-era/yg511q/ud9uli67b6gxgdh7】

开整

数据库准备

一主两从
在这里插入图片描述

数据库脚本

CREATE DATABASE IF NOT EXISTS dbtest CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';
USE dbtest;
-- 创建表
CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, uname VARCHAR (30)
);

创建SpringBoot工程

  • SpringBoot 2.7.3
  • ShardingSphere 5.2.1

项目结构

在这里插入图片描述

依赖引入

父工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>pers.kw</groupId><artifactId>ShardingSphere</artifactId><version>1.0-SNAPSHOT</version><modules><module>ShardingSphere-hello</module><module>ShardingSphere-mybatis-plus</module></modules><packaging>pom</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><skipTests>true</skipTests><spring-boot.version>2.7.3</spring-boot.version><minio.version>8.2.2</minio.version></properties><!-- 依赖声明 --><dependencyManagement><dependencies><!-- SpringBoot 依赖配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--服务监控--><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.0</version></dependency><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-jwt</artifactId><version>1.0.9.RELEASE</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.20</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><!--链路追踪--><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>8.8.0</version></dependency><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.8.0</version></dependency><!--数据源依赖-->
<!--            <dependency>-->
<!--                <groupId>com.alibaba</groupId>-->
<!--                <artifactId>druid-spring-boot-starter</artifactId>-->
<!--                <version>1.2.6</version>-->
<!--            </dependency>--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.7</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.8</version><scope>compile</scope></dependency><!--swagger配置--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.3</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.5.20</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.5.20</version></dependency><!--bean转换--><dependency><groupId>net.sf.dozer</groupId><artifactId>dozer-spring</artifactId><version>5.5.1</version></dependency><dependency><groupId>net.sf.dozer</groupId><artifactId>dozer</artifactId><version>5.5.1</version></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.6</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><artifactId>commons-lang3</artifactId><groupId>org.apache.commons</groupId><version>3.12.0</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.0</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.7</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></pluginManagement></build></project>
子工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>ShardingSphere</artifactId><groupId>pers.kw</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><packaging>jar</packaging><artifactId>ShardingSphere-hello</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId></dependency><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency><dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.33</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.2.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency></dependencies></project>

yaml配置

server:port: 8080
spring:application:name: ShardingSphere-hellojpa:database-platform: org.hibernate.dialect.MySQL8Dialectshow-sql: truehibernate:ddl-auto: noneshardingsphere:mode:type: Standalone # 单机模式repository:type: JDBC # JDBCdatasource:names: m1,s1,s2m1: # 配置第一个主机type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: jdbc:mysql://10.211.55.88:3306/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: 123456s1: # 配置第一个从机type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: jdbc:mysql://10.211.55.88:3307/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: 123456s2: # 配置第二个从机type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: jdbc:mysql://10.211.55.88:3309/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: 123456rules:readwrite-splitting:data-sources:readwrite_ds: # 读写分离逻辑数据源名称staticStrategy: # 读写分离类型为静态读写分离writeDataSourceName: m1readDataSourceNames:- s1- s2loadBalancerName: alg_round # 负责均衡算法的名称load-balancers:alg_round: # 负载均衡算法的名称type: ROUND_ROBIN # 轮询负载均衡算法props:sql-show: true # 打印 SQL#分页插件
#pagehelper:
#  helper-dialect: mysql
#  reasonable: true
#  support-methods-arguments: true
#  params: count=countSql
#mybatis:
#  type-aliases-package: pers.kw.**.dto
#  mapper-locations: classpath*:mapper/**/*.xml
#  configuration:
#    map-underscore-to-camel-case: true
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

实体类

package pers.kw.persist.entity;import lombok.Data;import javax.persistence.*;@Data
@Entity
@Table(name = "t_user")
public class User {@Basic@Column(name = "id")@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "uname")private String uname;
}

dao

package pers.kw.persist.dao;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import pers.kw.persist.entity.User;import java.util.List;public interface UserDao extends JpaRepository<User, Long> {@Query("from User")List<User> listUser();
}

service

package pers.kw.service;import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.kw.persist.dao.UserDao;
import pers.kw.persist.entity.User;import javax.annotation.Resource;
import java.util.List;@Slf4j
@Service
public class UserService {@Resourceprivate UserDao userDao;@Transactional(rollbackFor = Exception.class)public void addUser() {User user = new User();user.setUname("kw");userDao.save(user);}public void readWrite1() {User user = new User();user.setUname("杜甫");userDao.save(user);List<User> all = userDao.listUser();log.info("list:{}", JSON.toJSONString(all));}@Transactional(rollbackFor = Exception.class)public void readWrite2() {User user = new User();user.setUname("李白");userDao.save(user);List<User> all = userDao.listUser();log.info("list:{}", JSON.toJSONString(all));}public void readLb() {List<User> all = userDao.listUser();log.info("list1 listUser:{}", JSON.toJSONString(all));List<User> l2 = userDao.listUser();log.info("list2 listUser:{}", JSON.toJSONString(l2));List<User> l3 = userDao.listUser();log.info("list3 listUser:{}", JSON.toJSONString(l3));}public void readLb2() {//查询的还是主库 SimpleJpaRepositoryList<User> all = userDao.findAll();log.info("list1 listUser:{}", JSON.toJSONString(all));List<User> l2 = userDao.findAll();log.info("list2 listUser:{}", JSON.toJSONString(l2));List<User> l3 = userDao.findAll();log.info("list3 listUser:{}", JSON.toJSONString(l3));}}

controller

package pers.kw.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pers.kw.service.UserService;import javax.annotation.Resource;@RestController
public class UserController {@Resourceprivate UserService userService;@RequestMapping("/addUser")public String addUser() {userService.addUser();return "ok";}@RequestMapping("/readWrite1")public String readWrite1() {userService.readWrite1();return "ok";}@RequestMapping("/readWrite2")public String readWrite2() {userService.readWrite2();return "ok";}@RequestMapping("/readLb")public String readLb() {userService.readLb();return "ok";}@RequestMapping("/readLb2")public String readLb2() {userService.readLb2();return "ok";}
}

http脚本

### 读写分离
POST http://localhost:8080/addUser
Content-Type: application/x-www-form-urlencoded### 无事务,读写
POST http://localhost:8080/readWrite1
Content-Type: application/x-www-form-urlencoded### 有事务读写
POST http://localhost:8080/readWrite2
Content-Type: application/x-www-form-urlencoded### 自写查询方法,负载均衡
POST http://localhost:8080/readLb
Content-Type: application/x-www-form-urlencoded### jpa自带查询方法,负载均衡
POST http://localhost:8080/readLb2
Content-Type: application/x-www-form-urlencoded###

测试

读写分离

在这里插入图片描述

事务

无事务注解

没加事务注解的情况,save方法是主库,查询方法是从库
在这里插入图片描述

有事务注解

加事务注解的情况,save方法是主库,查询方法也是主库
在这里插入图片描述

负载均衡

自写查询方法

可以看到,分别查询了s1,s2,s1
在这里插入图片描述

Jpa自带的查询方法

查询的均是主库
在这里插入图片描述
原因是自带的查询方法是SimpleJpaRepository实现的,此类默认开启只读事务。
在这里插入图片描述

自写查询方法,增加事务注解

@Transactional(readOnly = true)public void readLb() {List<User> all = userDao.listUser();log.info("list1 listUser:{}", JSON.toJSONString(all));List<User> l2 = userDao.listUser();log.info("list2 listUser:{}", JSON.toJSONString(l2));List<User> l3 = userDao.listUser();log.info("list3 listUser:{}", JSON.toJSONString(l3));}

测试查下看是否还是从库?
查询的均为主库
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/295070.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文查重率高如何快速降重 papergpt

大家好&#xff0c;今天来聊聊论文查重率高如何快速降重&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文查重率高如何快速降重 当论文查重率过高时&#xff0c;需要快…

骑砍战团MOD开发(24)-module_particle_system粒子系统

一.粒子实现方式 创建2D平面模型作为粒子基本单元,系统预制平面在particle_meshes.brf文件中,通过particle_blend着色器实现粒子透明度和着色效果. #雨点粒子平面 prtcl_rain #雪粒子平面 prtcl_snow #烟尘粒子平面(马匹奔跑时产生) prtcl_dust_a prtcl_dust_b #火焰粒子平面 …

汽车级EEPROM 存储器 M24C64-DRMN3TP/K是电可擦除可编程只读存储器?它的功能特性有哪些?

M24C64-DRMN3TP/K是一款64 Kbit串行EEPROM汽车级设备&#xff0c;工作温度高达125C。符合汽车标准AEC-Q100 1级规定的极高可靠性。 该设备可通过一个高达1MHz的简单串行I2C兼容接口访问。 存储器阵列基于先进的真EEPROM技术&#xff08;电可擦除可编程存储器&#xff09;。M2…

DETR++: Taming Your Multi-Scale Detection Transformer论文解读

文章目录 前言一、摘要二、引言三、相关研究四、模型方法1、Removing the Encoder方法2、Multi-Head方法3、Shifted Windows方法4、Bi-directional Feature Pyramid方法5、DETR方法 五、实验结果总结 前言 今天查看了一篇DETR论文&#xff0c;本想网络上找博客大概浏览一下&am…

智能优化算法应用:基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.骑手优化算法4.实验参数设定5.算法结果6.…

【飞凌 OK113i-C 全志T113-i开发板】一些有用的常用的命令测试

一些有用的常用的命令测试 一、系统信息查询 可以查询板子的内核信息、CPU处理器信息、环境变量等 二、CPU频率 从上面的系统信息查询到&#xff0c;这是一颗具有两个ARMv7结构A7内核的处理器&#xff0c;主频最高1.2GHz 可以通过命令查看当前支持的频率以及目前所使用主频 …

C++ 之LeetCode刷题记录(一)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 从今天开始cpp刷题之旅&#xff0c;多学多练&#xff0c;尽力而为。 先易后难&#xff0c;先刷简单的。 1、两数之和 给定一个整数数组 nums 和一个整数目标值…

【笔记】Spring的循环依赖

Spring的循环依赖 ObjectFactory:函数式接口&#xff0c;可以将lambda表达式作为参数放在方法的实参种&#xff0c;在方法执行的时候&#xff0c;并不会实际的调用当前lambda表达式&#xff0c;只有在调用getObject方法的时候才回去调用lambda表达式 为什么spring要用三级缓存…

青少年CTF-qsnctf-Web-include01include02(多种方法-知识点较多-建议收藏!)

PHP常见伪协议 php://filter是PHP中独有的一种协议&#xff0c;它是一种过滤器&#xff0c;可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据&#xff0c;且在读取和写入之前对数据进行一些过滤&#xff0c;例如base64编码处理&#xff0c;rot13处…

TrustZone之与非安全虚拟化交互

到目前为止&#xff0c;我们在示例中忽略了非安全状态中可能存在的虚拟化程序。当存在虚拟化程序时&#xff0c;虚拟机与安全状态之间的许多通信将通过虚拟化程序进行。 例如&#xff0c;在虚拟化环境中&#xff0c;SMC用于访问固件功能和可信服务。固件功能包括诸如电源管理之…

maven完结,你真的学完了吗

书接上文&#xff1a;必学的maven的起步-CSDN博客 分模块开发与设计 分模块开发&#xff1a; 创建模块书写代码模块 模块中需要其他的模块&#xff0c;就将他安装到仓库然后再dep中导入依赖通过maven指令安装模块到本地仓库&#xff08;install&#xff09; 聚合与继承 聚合…

安捷伦Agilent 8720ES网络分析仪

Agilent安捷伦8720ES S-参数矢量网络分析仪 50MHz至20GHz 100 dB 的动态范围 优异的测量精度 2个测量通道 4个显示通道 频率和功率扫描 快扫描和数据传输速度 通过/失败测试&#xff0c;强大的标记功能 电校准&#xff08;ECal&#xff09; 内部使用测试序列的自动化 可选时域…