理论参考:{{MySQL 高级框架实战理论笔记}}

GitHub 代码:lane-mysql-42

单纯的 MySQL 实现

建库 lane1 和 lane2

建表 SQL

  1. CREATE TABLE `position` (
  2. `Id` bigint(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(256) DEFAULT NULL,
  4. `salary` varchar(50) DEFAULT NULL,
  5. `city` varchar(256) DEFAULT NULL,
  6. PRIMARY KEY (`Id`)
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  8. CREATE TABLE `position_detail` (
  9. `Id` bigint(11) NOT NULL AUTO_INCREMENT,
  10. `pid` bigint(11) NOT NULL DEFAULT '0',
  11. `description` text DEFAULT NULL,
  12. PRIMARY KEY (`Id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

下载并配置 sharding porxy

下载解压后如图

Sharding Proxy 实战 - 图1

添加 mysql 驱动

在 lib 下添加 mysql 的 jar 如图

Sharding Proxy 实战 - 图2

修改 conf 下 server.yaml 如下

基本默认即可,指定自己逻辑代理数据库名 lane_db

Sharding Proxy 实战 - 图3

修改 conf 下 sharding.yaml 如下

修改逻辑库名,database 信息,配置下分库规则

Sharding Proxy 实战 - 图4

启动 bin 下的 start.sh

  1. sh start.sh

出现错误

  1. Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
  2. Unrecognized VM option 'UseFastAccessorMethods'

看意思是 在 jdk 未来的版本将会 移除 UseFastAccessorMethods,而我使用的是 jdk11 超过了 9,那么应该是移除了,故而无法识别 UseFastAccessorMethods ,下载的 sharding proxy 有点老了,那就修改下 start.sh 删掉 UseFastAccessorMethods,重新启动成功

访问测试代理数据库

在终端输入,注意默认端口号是 3307

  1. mysql -uroot -h 127.0.0.1 -P 3307 -p
  2. mysql> show databases;
  3. +----------+
  4. | Database |
  5. +----------+
  6. | lane_db |
  7. +----------+
  8. 1 row in set (0.02 sec)

可以看到把两个数据库的 position 的数据都查询出来了Sharding Proxy 实战 - 图5

执行下 insert 看下

  1. mysql> insert into position (name,salary,city) values ('tom',20000,'shanghai');
  2. Query OK, 1 row affected (0.02 sec)
  3. mysql> insert into position (name,salary,city) values ('lucy',21000,'hangzhou');
  4. Query OK, 1 row affected (0.02 sec)

可以看到成功实现了分库插入数据

Sharding Proxy 实战 - 图6

附加

可以配置其他配置文件,实现读写分离,脱敏等功能

Sharding Proxy + Spring Boot 实现

创建父项目作为依赖管理

mysql-example

添加依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.galaxy</groupId>
  7. <artifactId>mysql-example</artifactId>
  8. <packaging>pom</packaging>
  9. <version>1.0-SNAPSHOT</version>
  10. <modules>
  11. <module>sharding-proxy-example</module>
  12. </modules>
  13. <properties>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. <project.compile.sourceEncoding>UTF-8</project.compile.sourceEncoding>
  16. <shardingsphere.version>4.1.0</shardingsphere.version>
  17. <springboot.version>2.2.9.RELEASE</springboot.version>
  18. </properties>
  19. <dependencyManagement>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-jdbc</artifactId>
  24. <version>${springboot.version}</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-data-jpa</artifactId>
  29. <version>${springboot.version}</version>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-starter-data-jpa</artifactId>
  34. <version>2.1.6.RELEASE</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-test</artifactId>
  39. <version>${springboot.version}</version>
  40. <scope>test</scope>
  41. </dependency>
  42. <dependency>
  43. <groupId>mysql</groupId>
  44. <artifactId>mysql-connector-java</artifactId>
  45. <version>5.1.48</version>
  46. </dependency>
  47. </dependencies>
  48. </dependencyManagement>
  49. <build>
  50. <plugins>
  51. <plugin>
  52. <groupId>org.apache.maven.plugins</groupId>
  53. <artifactId>maven-compiler-plugin</artifactId>
  54. <version>3.8.1</version>
  55. <configuration>
  56. <source>11</source>
  57. <target>11</target>
  58. <testSource>11</testSource>
  59. <testTarget>11</testTarget>
  60. </configuration>
  61. </plugin>
  62. </plugins>
  63. </build>
  64. </project>

创建模块项目

sharding-proxy-example

依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>mysql-example</artifactId>
  7. <groupId>com.galaxy</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>sharding-proxy-example</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-jdbc</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-data-jpa</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-test</artifactId>
  24. <scope>test</scope>
  25. </dependency>
  26. <dependency>
  27. <groupId>mysql</groupId>
  28. <artifactId>mysql-connector-java</artifactId>
  29. </dependency>
  30. </dependencies>
  31. </project>

Java 基本代码

entity

  1. package com.galaxy.entity;
  2. import javax.persistence.*;
  3. import java.io.Serializable;
  4. /**
  5. * @author lane
  6. * @date 2021年07月23日 下午6:05
  7. */
  8. @Entity
  9. @Table(name = "position")
  10. public class Position implements Serializable {
  11. @Id
  12. @Column(name = "id")
  13. //使用sharding jdbc指定主键生成,不指定则是数据库默认auto_increment
  14. @GeneratedValue(strategy = GenerationType.IDENTITY)
  15. private long id;
  16. @Column(name = "name")
  17. private String name;
  18. @Column(name = "salary")
  19. private String salary;
  20. @Column(name = "city")
  21. private String city;
  22. public long getId() {
  23. return id;
  24. }
  25. public void setId(long id) {
  26. this.id = id;
  27. }
  28. public String getName() {
  29. return name;
  30. }
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34. public String getSalary() {
  35. return salary;
  36. }
  37. public void setSalary(String salary) {
  38. this.salary = salary;
  39. }
  40. public String getCity() {
  41. return city;
  42. }
  43. public void setCity(String city) {
  44. this.city = city;
  45. }
  46. }

repository

  1. package com.galaxy.repository;
  2. import com.galaxy.entity.Position;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.Query;
  5. import org.springframework.data.repository.query.Param;
  6. /**
  7. * @author lane
  8. * @date 2021年07月20日 下午7:36
  9. */
  10. public interface PositionRepository extends JpaRepository<Position,Long> {
  11. }

启动类

  1. package com.galaxy;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. /**
  4. * @author lane
  5. * @date 2021年07月23日 下午6:10
  6. */
  7. @SpringBootApplication
  8. public class ProxyApplication {
  9. }

配置信息

注意库名字是代理库 lane_db 端口号是 3307

  1. #datasource
  2. spring.datasource.url=jdbc:mysql://127.0.0.1:3307/lane_db?useUnicode=true&characterEncoding=utf8
  3. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  4. spring.datasource.username=root
  5. spring.datasource.password=root
  6. spring.datasource.type=com.zaxxer.hikari.HikariDataSource

测试代码

  1. /**
  2. * @author lane
  3. * @date 2021年07月23日 下午6:16
  4. */
  5. @SpringBootTest(classes = ProxyApplication.class)
  6. @RunWith(SpringRunner.class)
  7. public class TestProxy {
  8. @Autowired
  9. PositionRepository positionRepository;
  10. @Test
  11. public void test1(){
  12. List<Position> positionList = positionRepository.findAll();
  13. positionList.forEach((position)->{
  14. System.out.println(position.getName());
  15. });
  16. }
  17. @Test
  18. @Repeat(2)
  19. public void test2(){
  20. Position position =new Position();
  21. position.setName("sky"+new Random().nextInt(12));
  22. position.setSalary("100000");
  23. position.setCity("guangzhou");
  24. positionRepository.save(position);
  25. }
  26. }

测试结果

查询好似是一个库,实际是两个库的数据

Sharding Proxy 实战 - 图7

新增按照规则实现分库 lane1 和 lane2 各添加了一条数据 1

Sharding Proxy 实战 - 图8