commit 8cc2fef1c3ddeefd7750eab53059169dead2ddf2 Author: qyx <565485304@qq.com> Date: Fri Oct 22 17:04:52 2021 +0800 [新增功能](master): 新建项目 建立项目 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efb4aab --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen diff --git a/README.md b/README.md new file mode 100644 index 0000000..61349b1 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +
sharding JDBC的一般性 DEMO
+ + +## 具体实践 + +### 0. 业务场景 + 解决问题: 同一项目在多数据源场景下, 订单,会员,价格统计都在不同的库里, 综合 JPA + ShardingJDBC + 动态数据源(跨库) + 怎么实现数据源切换及跨库查询? + + 跨库查询: 用户 (用户信息库) 有及相关的总价统计在price表里(业务库),来实现跨库查询 + + 跨库查询结合分表: 短期业务场景下对用户及总价对关联订单进行查询,订单采用分表进行存储 + + 跨库结合分表分库: 长期业务场景下不能满足分表的场景,然后进行分表分库进行查询 + + + +### 1. 多数据源下对其中一个数据源进行分表分库 + + 查看配置文件 + +### 2. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7da5459 --- /dev/null +++ b/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + com.baiye + sharding-demo + 1.0-SNAPSHOT + + sharding-multiple-data-sources + sharding-multiple-data-sources + + + + 8 + 8 + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.2.RELEASE + + + pom + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.apache.shardingsphere + sharding-jdbc-spring-boot-starter + + + + + org.apache.shardingsphere + sharding-jdbc-spring-namespace + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + mysql + mysql-connector-java + + + + com.baomidou + dynamic-datasource-spring-boot-starter + + + + org.projectlombok + lombok + 1.18.20 + + + + junit + junit + 4.13.2 + test + + + + org.springframework.boot + spring-boot-starter-test + + + + + com.alibaba + druid-spring-boot-starter + + + + \ No newline at end of file diff --git a/sharding-multiple-data-sources/.gitignore b/sharding-multiple-data-sources/.gitignore new file mode 100644 index 0000000..efb4aab --- /dev/null +++ b/sharding-multiple-data-sources/.gitignore @@ -0,0 +1,46 @@ +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen diff --git a/sharding-multiple-data-sources/pom.xml b/sharding-multiple-data-sources/pom.xml new file mode 100644 index 0000000..2722891 --- /dev/null +++ b/sharding-multiple-data-sources/pom.xml @@ -0,0 +1,74 @@ + + + + sharding-demo + com.baiye + 1.0-SNAPSHOT + + 4.0.0 + + sharding-multiple-data-sources + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.apache.shardingsphere + sharding-jdbc-spring-boot-starter + + + + + org.apache.shardingsphere + sharding-jdbc-spring-namespace + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + mysql + mysql-connector-java + + + + + + org.projectlombok + lombok + + + + junit + junit + + + + org.springframework.boot + spring-boot-starter-test + + + + com.alibaba + druid-spring-boot-starter + + + + + \ No newline at end of file diff --git a/sharding-multiple-data-sources/sql/init.sql b/sharding-multiple-data-sources/sql/init.sql new file mode 100644 index 0000000..e69de29 diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java b/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java new file mode 100644 index 0000000..45cbfd8 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java @@ -0,0 +1,15 @@ +package com.baiye; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author q + */ +@SpringBootApplication +public class ShardingMultipleDataSourceApplication { + + public static void main(String[] args) { + SpringApplication.run(ShardingMultipleDataSourceApplication.class, args); + } +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/dao/OrderRepository.java b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/OrderRepository.java new file mode 100644 index 0000000..c2be6ba --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/OrderRepository.java @@ -0,0 +1,8 @@ +package com.baiye.dao; + + +import com.baiye.domain.Order; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrderRepository extends JpaRepository { +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/dao/PriceRepository.java b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/PriceRepository.java new file mode 100644 index 0000000..37cab7d --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/PriceRepository.java @@ -0,0 +1,7 @@ +package com.baiye.dao; + +import com.baiye.domain.Price; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PriceRepository extends JpaRepository { +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/dao/UserRepository.java b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/UserRepository.java new file mode 100644 index 0000000..58a441b --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/UserRepository.java @@ -0,0 +1,14 @@ +package com.baiye.dao; + +import com.baiye.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * 对应user表 -> 存储在库 test_sharding_1 + * + * 代表业务主库 + * + * @author q + */ +public interface UserRepository extends JpaRepository { +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Order.java b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Order.java new file mode 100644 index 0000000..381049b --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Order.java @@ -0,0 +1,21 @@ +package com.baiye.domain; + +import lombok.Data; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + +@Entity +@Data +@Table(name = "order") +public class Order implements Serializable { + + @Id + private Integer id; + + private Integer userid; + + private String ordername; +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java new file mode 100644 index 0000000..4a699c2 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java @@ -0,0 +1,19 @@ +package com.baiye.domain; + +import lombok.Data; + +import javax.persistence.Id; +import javax.persistence.Table; +import java.math.BigDecimal; + +@Data +@Table(name = "price") +public class Price { + + @Id + private Integer id; + + private Integer userId; + + private BigDecimal cost; +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java new file mode 100644 index 0000000..c94a0a7 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java @@ -0,0 +1,19 @@ +package com.baiye.domain; + + +import lombok.Data; + +import javax.persistence.Id; +import javax.persistence.Table; + +@Data +@Table(name = "user") +public class User { + + @Id + private Integer id; + + private String name; + + private String city; +} diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java b/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java new file mode 100644 index 0000000..317bf10 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java @@ -0,0 +1,56 @@ +package com.baiye.service; + + +import com.baiye.dao.OrderRepository; +import com.baiye.domain.Order; +import com.baiye.domain.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author q + */ +@Service +public class ShardService { + + @Autowired + private OrderRepository orderRepository; + + /** + * 增 + */ + public Order insertOne(Order order){ + return orderRepository.save(order); + } + + /** + * 批量增加 + */ + public List batchInsert(List orders){ + return orderRepository.saveAll(orders); + } + + /** + * 查 + */ + public List queryByCondition(){ + return orderRepository.findAll(); + } + + /** + * 修改 + */ + public Order updateByCondition(Order order){ + return orderRepository.save(order); + } + + /** + * 删除 + */ + public void deleterByCondition(Order order){ + orderRepository.delete(order); + } + +} diff --git a/sharding-multiple-data-sources/src/main/resources/application-dev.yml b/sharding-multiple-data-sources/src/main/resources/application-dev.yml new file mode 100644 index 0000000..b9d0bb0 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/resources/application-dev.yml @@ -0,0 +1,53 @@ + +spring: + datasource: + # 动态数据源配置 + dynamic: + primary: ${db.db1-name} # 指定默认数据源名称 + strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 + datasource: + ${db.db1-name}: + url: jdbc:mysql://127.0.0.1:3306/test_sharding_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true + #driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 + username: root + password: root + ${db.db2-name}: + url: jdbc:mysql://127.0.0.1:3306/test_sharding_2?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true + #driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 + username: root + password: root +# 分表配置 + shardingsphere: + datasource: + # 分库 + names: ${db.db3-name}, ${db.db4-name} + ${db.db3-name}: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.jdbc.Driver + jdbc-url: jdbc:mysql://127.0.0.1:3306/test_sharding_3?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true + username: root + password: root + ${db.db4-name}: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.jdbc.Driver + jdbc-url: jdbc:mysql://127.0.0.1:3306/test_sharding_4?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true + username: root + password: root + props: + # 日志显示SQL + sql.show: true + sharding: + tables: + # 订单表 分表:20 + order: + # 真实表 order_0 + actualDataNodes: ${db.db3-name}.order_$->{0..19} + # 分库策略 + databaseStrategy: + none: + # 分表策略 + tableStrategy: + inline: + shardingColumn: id + # 分片算法行表达式,需符合groovy语法 '& Integer.MAX_VALUE' 位运算使hash值为正数 + algorithmExpression: order_$->{(order_key.hashCode() & Integer.MAX_VALUE) % 20} \ No newline at end of file diff --git a/sharding-multiple-data-sources/src/main/resources/application-sharddatabase.yml b/sharding-multiple-data-sources/src/main/resources/application-sharddatabase.yml new file mode 100644 index 0000000..83ace4c --- /dev/null +++ b/sharding-multiple-data-sources/src/main/resources/application-sharddatabase.yml @@ -0,0 +1,47 @@ +db: + # 多数据源1 +# db1-name: master + # 多数据源2 +# db2-name: 'slave_1' + # 分表分库1 + db3-name: 'ds1' + # 分表分库2 + db4-name: 'ds2' +tb: + name1: order + + +# 分库 +spring: + shardingsphere: + datasource: + names: ${db.db3-name}, ${db.db4-name} + ${db.db3-name}: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://127.0.0.1:3306/shard-3?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true + username: root + password: root + ${db.db4-name}: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://127.0.0.1:3306/shard-4?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true + username: root + password: root + # 设置分片策略 + sharding: + default-database-strategy: + inline: + sharding-column: userid + algorithm-expression: ds$->{userid % 10} + # 表分片策略 + tables: + ${tb.name1}: + actual-data-nodes: ds$->{0..1}.order + key-generator: + column: userid + type: SNOWFLAKE + props: + worker: + id: 33 + diff --git a/sharding-multiple-data-sources/src/main/resources/application-shardtable.yml b/sharding-multiple-data-sources/src/main/resources/application-shardtable.yml new file mode 100644 index 0000000..fabd96c --- /dev/null +++ b/sharding-multiple-data-sources/src/main/resources/application-shardtable.yml @@ -0,0 +1,35 @@ +db: + # 多数据源1 + db1-name: master + # 多数据源2 + db2-name: 'slave_1' + # 分表分库1 + db3-name: ds1 + # 分表分库2 + db4-name: ds2 +tb: + name1: order + + + + +# 分表相关的逻辑 +spring: + shardingsphere: + datasource: + names: ${db.db3-name} + ${db.db3-name}: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://127.0.0.1:3306/shard-3?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true + username: root + password: root + sharding: + tables: + ${tb.name1}: + table-strategy: + inline: + sharding-column: id + algorithm-expression: order$-> {id % 10} + +# todo 设置了绑定表和广播表 提供性能 \ No newline at end of file diff --git a/sharding-multiple-data-sources/src/main/resources/application.yml b/sharding-multiple-data-sources/src/main/resources/application.yml new file mode 100644 index 0000000..5190ba3 --- /dev/null +++ b/sharding-multiple-data-sources/src/main/resources/application.yml @@ -0,0 +1,15 @@ +# 配置环境分离 +application-all: + app-properties-name-1: shardtable # 分表 + app-properties-name-2: sharddatabase # 分库 + + +server: + port: 8080 +spring: + application: + name: sharding-multiple-data-sources + profiles: + active: sharddatabase + + diff --git a/sharding-multiple-data-sources/src/test/java/com/baiye/service/ShardServiceTest.java b/sharding-multiple-data-sources/src/test/java/com/baiye/service/ShardServiceTest.java new file mode 100644 index 0000000..895d564 --- /dev/null +++ b/sharding-multiple-data-sources/src/test/java/com/baiye/service/ShardServiceTest.java @@ -0,0 +1,49 @@ +package com.baiye.service; + + +import com.baiye.ShardingMultipleDataSourceApplication; +import com.baiye.domain.Order; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ShardingMultipleDataSourceApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ShardServiceTest { + + @Autowired + private ShardService shardService; + + @Test + public void insertOne() { + Order order = new Order(); + order.setUserid(9999); + order.setOrdername("testOrder" + 9999); + Order order1 = shardService.insertOne(order); + System.out.println("order1 = " + order1); + } + + @Test + public void batchInsert() { + for (int i = 1; i < 1000; i++) { + Order order = new Order(); + order.setUserid(i); + order.setOrdername("testOrder" + i); + } + + } + + @Test + public void queryByCondition() { + } + + @Test + public void updateByCondition() { + } + + @Test + public void deleterByCondition() { + } +} \ No newline at end of file