许大仙老师:【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)
);
<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.0modelVersion>
<groupId>pers.kwgroupId>
<artifactId>ShardingSphereartifactId>
<version>1.0-SNAPSHOTversion>
<modules>
<module>ShardingSphere-hellomodule>
<module>ShardingSphere-mybatis-plusmodule>
modules>
<packaging>pompackaging>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<skipTests>trueskipTests>
<spring-boot.version>2.7.3spring-boot.version>
<minio.version>8.2.2minio.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring-boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>2.3.0version>
dependency>
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-clientartifactId>
<version>2.3.0version>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-jwtartifactId>
<version>1.0.9.RELEASEversion>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>5.7.20version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.83version>
dependency>
<dependency>
<groupId>org.apache.skywalkinggroupId>
<artifactId>apm-toolkit-logback-1.xartifactId>
<version>8.8.0version>
dependency>
<dependency>
<groupId>org.apache.skywalkinggroupId>
<artifactId>apm-toolkit-traceartifactId>
<version>8.8.0version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.4.7version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.1.8version>
<scope>compilescope>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>swagger-bootstrap-uiartifactId>
<version>1.9.3version>
dependency>
<dependency>
<groupId>io.swaggergroupId>
<artifactId>swagger-annotationsartifactId>
<version>1.5.20version>
dependency>
<dependency>
<groupId>io.swaggergroupId>
<artifactId>swagger-modelsartifactId>
<version>1.5.20version>
dependency>
<dependency>
<groupId>net.sf.dozergroupId>
<artifactId>dozer-springartifactId>
<version>5.5.1version>
dependency>
<dependency>
<groupId>net.sf.dozergroupId>
<artifactId>dozerartifactId>
<version>5.5.1version>
dependency>
<dependency>
<groupId>org.redissongroupId>
<artifactId>redissonartifactId>
<version>3.11.6version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>4.1.2version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
<dependency>
<artifactId>commons-lang3artifactId>
<groupId>org.apache.commonsgroupId>
<version>3.12.0version>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.6.0version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<encoding>${project.build.sourceEncoding}encoding>
configuration>
plugin>
plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>2.7.7version>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
pluginManagement>
build>
project>
<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>ShardingSphereartifactId>
<groupId>pers.kwgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<packaging>jarpackaging>
<artifactId>ShardingSphere-helloartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.apache.skywalkinggroupId>
<artifactId>apm-toolkit-logback-1.xartifactId>
dependency>
<dependency>
<groupId>org.apache.skywalkinggroupId>
<artifactId>apm-toolkit-traceartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
dependency>
<dependency>
<groupId>org.yamlgroupId>
<artifactId>snakeyamlartifactId>
<version>1.33version>
dependency>
<dependency>
<groupId>org.apache.shardingspheregroupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
<version>5.2.1version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.26version>
dependency>
dependencies>
project>
server:
port: 8080
spring:
application:
name: ShardingSphere-hello
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
ddl-auto: none
shardingsphere:
mode:
type: Standalone # 单机模式
repository:
type: JDBC # JDBC
datasource:
names: m1,s1,s2
m1: # 配置第一个主机
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://10.211.55.88:3306/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
s1: # 配置第一个从机
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://10.211.55.88:3307/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
s2: # 配置第二个从机
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://10.211.55.88:3309/dbtest?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
rules:
readwrite-splitting:
data-sources:
readwrite_ds: # 读写分离逻辑数据源名称
staticStrategy: # 读写分离类型为静态读写分离
writeDataSourceName: m1
readDataSourceNames:
- s1
- s2
loadBalancerName: 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;
}
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();
}
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 {
@Resource
private 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() {
//查询的还是主库 SimpleJpaRepository
List<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));
}
}
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 {
@Resource
private 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";
}
}
### 读写分离
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
###
查询的均是主库
原因是自带的查询方法是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));
}