Sharding-JDBC 實戰
阿新 • • 發佈:2020-07-15
Sharding-JDBC簡單使用
1.Sharding-JDBC之環境搭建
1.1 建立一個Maven專案 mysql-example,父工程專案pom.xml如下
<?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>org.example</groupId> <artifactId>mysql-example</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>sharding-jdbc-example</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.compile.sourceEncoding>UTF-8</project.compile.sourceEncoding> <shardingsphere.version>4.1.0</shardingsphere.version> <springboot.version>2.2.5.RELEASE</springboot.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <version>${springboot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>${springboot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${springboot.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.48</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>${shardingsphere.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <testSource>1.8</testSource> <testTarget>1.8</testTarget> </configuration> <version>3.8.1</version> </plugin> </plugins> </build> </project>
1.2 建立子模組sharding-jdbc-example,子模組專案pom.xml如下
<?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>mysql-example</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>sharding-jdbc-example</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> </dependency> </dependencies> </project>
2.Sharding-JDBC之職位分庫業務
2.1資料庫準備
- 使用的mysql 5.5.54
- 由於資源限制,我就在一個服務裡建兩個資料庫lagou1,lagou2,建立相同的職位表,職位詳情表
- 建表語句如下
#position表 CREATE TABLE `position` ( `id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT, `name` VARCHAR ( 255 ) DEFAULT NULL, `salary` VARCHAR ( 50 ) DEFAULT NULL, `city` VARCHAR ( 255 ) DEFAULT NULL, PRIMARY KEY ( `id` ) ) ENGINE = INNODB AUTO_INCREMENT = 490171537622564865 DEFAULT CHARSET = utf8; #position_detail表 CREATE TABLE `position_detail` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `pid` bigint(11) DEFAULT NULL, `description` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=490171537891000321 DEFAULT CHARSET=utf8;
2.2.2 建立實體類與Repository
# Position
package com.lagou.entity;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "position")
public class Position implements Serializable{
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "salary")
private String salary;
@Column(name = "city")
private String city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Position{" +
"id=" + id +
", name='" + name + '\'' +
", salary='" + salary + '\'' +
", city='" + city + '\'' +
'}';
}
}
#PositionDetail
package com.lagou.entity;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "position_detail")
public class PositionDetail implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "pid")
private Long pid;
@Column(name = "description")
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
## PositionRepository
package com.lagou.repository;
import com.lagou.entity.Position;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface PositionRepository extends JpaRepository<Position,Long> {
@Query(nativeQuery = true,value = "select p.id,p.name,p.salary,p.city,pd.description from position p join position_detail pd on(p.id =pd.pid) where p.id=:id")
public Object findPositionsById(@Param("id") long id);
}
## PositionDetailRepository
package com.lagou.repository;
import com.lagou.entity.PositionDetail;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PositionDetailRepository extends JpaRepository<PositionDetail,Long> {
}
## 啟動類
package com.lagou;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RunBoot {
}
2.2.3 配置檔案
- application.properties
spring.profiles.active=sharding-database
spring.shardingsphere.props.sql.show=true
- application-sharding-database.properties
#datasource
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/lagou1
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
#連線池型別jpa預設的是HikariDataSource
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/lagou2
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root
#sharding-database
#position表名, database-strategy :按庫切分 , inline:行表示式格式, sharding-column:指明分片鍵
spring.shardingsphere.sharding.tables.position.database-strategy.inline.sharding-column=id
# algorithm-expression:指明表示式什麼時候定位到ds0ds1
spring.shardingsphere.sharding.tables.position.database-strategy.inline.algorithm-expression=ds$->{id % 2}
#position_detail的配置
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.sharding-column=pid
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.algorithm-expression=ds$->{pid % 2}
# 主鍵生成策略
#指定主鍵id的欄位名 #指定type型別如UUID ,SNOWFLAKE 注意使用jpa中entity的id主鍵生成需開啟
spring.shardingsphere.sharding.tables.position.key-generator.column=id
spring.shardingsphere.sharding.tables.position.key-generator.type=SNOWFLAKE
#spring.shardingsphere.sharding.tables.position.key-generator.type=LAGOUKEY
#position_detail的主鍵生成策略
spring.shardingsphere.sharding.tables.position_detail.key-generator.column=id
spring.shardingsphere.sharding.tables.position_detail.key-generator.type=SNOWFLAKE
2.2.4 測試類TestShardingDatabase
import javax.annotation.Resource;
import java.util.Date;
import java.util.Random;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RunBoot.class)
public class TestShardingDatabase {
@Resource
private PositionRepository positionRepository;
@Resource
private PositionDetailRepository positionDetailRepository;
@Test
public void testAdd() {
for (int i = 1; i <= 20; i++) {
Position position = new Position();
position.setName("lagou" + i);
position.setSalary("10000");
position.setCity("beijing");
positionRepository.save(position);
PositionDetail positionDetail = new PositionDetail();
positionDetail.setPid(position.getId());
positionDetail.setDescription("this is a pig" + i);
positionDetailRepository.save(positionDetail);
}
}
}
2.2.5 執行效果
2.2.6 自定義主鍵生成策略實現 ShardingKeyGenerator介面即可
package com.lagou.id;
import org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator;
import org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator;
import java.util.Properties;
/**
* 自定義主鍵生成器
*/
public class MyLagouId implements ShardingKeyGenerator {
/**
* 用同一個主鍵生成器物件 就會分配均勻
*/
private SnowflakeShardingKeyGenerator snowflakeShardingKeyGenerator = new SnowflakeShardingKeyGenerator();
/**
* 返回我們生成的主鍵值 由於這個演算法比較複雜,就還是使用SNOWFLAKE,也可以自己寫
* @return
*/
@Override
public Comparable<?> generateKey() {
System.out.println("---執行了自定義主鍵生成器MyLagouId");
return snowflakeShardingKeyGenerator.generateKey();
}
/**
* 返回配置檔案中那個的type
* @return
*/
@Override
public String getType() {
return "LAGOUKEY";
}
@Override
public Properties getProperties() {
return null;
}
@Override
public void setProperties(Properties properties) {
}
}
2.2.6.1 修改配置檔案並在resources下建一下檔案(檔名需一致)
- org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator內容如下
com.lagou.id.MyLagouId
- 注意:resource檔案下的目錄分級為/
2.2.7修改application-sharding-database.properties的主鍵生成策略的type為自定義主鍵生成策略返回的type
spring.shardingsphere.sharding.tables.position.key-generator.type=LAGOUKEY