order1:
CREATE DATABASE `order1` DEFAULT CHARACTER SET utf8;
USE `order1`;
DROP TABLE IF EXISTS `t_address`;
CREATE TABLE `t_address` (
`id` bigint(20) NOT NULL,
`code` varchar(64) DEFAULT NULL COMMENT '编码',
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`pid` varchar(64) NOT NULL DEFAULT '0' COMMENT '父id',
`type` int(11) DEFAULT NULL COMMENT '1国家2省3市4县区',
`lit` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user0`;
CREATE TABLE `t_user0` (
`id` bigint(20) NOT NULL,
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`city_id` int(12) DEFAULT NULL COMMENT '城市',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别',
`phone` varchar(32) DEFAULT NULL COMMENT '电话',
`email` varchar(32) DEFAULT NULL COMMENT '邮箱',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`password` varchar(32) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user1`;
CREATE TABLE `t_user1` (
`id` bigint(20) NOT NULL,
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`city_id` int(12) DEFAULT NULL COMMENT '城市',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别',
`phone` varchar(32) DEFAULT NULL COMMENT '电话',
`email` varchar(32) DEFAULT NULL COMMENT '邮箱',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`password` varchar(32) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
order2:
CREATE DATABASE `order2` DEFAULT CHARACTER SET utf8;
USE `order2`;
DROP TABLE IF EXISTS `t_address`;
CREATE TABLE `t_address` (
`id` bigint(20) NOT NULL,
`code` varchar(64) DEFAULT NULL COMMENT '编码',
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`pid` varchar(64) NOT NULL DEFAULT '0' COMMENT '父id',
`type` int(11) DEFAULT NULL COMMENT '1国家2省3市4县区',
`lit` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user0`;
CREATE TABLE `t_user0` (
`id` bigint(20) NOT NULL,
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`city_id` int(12) DEFAULT NULL COMMENT '城市',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别',
`phone` varchar(32) DEFAULT NULL COMMENT '电话',
`email` varchar(32) DEFAULT NULL COMMENT '邮箱',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`password` varchar(32) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user1`;
CREATE TABLE `t_user1` (
`id` bigint(20) NOT NULL,
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`city_id` int(12) DEFAULT NULL COMMENT '城市',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别',
`phone` varchar(32) DEFAULT NULL COMMENT '电话',
`email` varchar(32) DEFAULT NULL COMMENT '邮箱',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`password` varchar(32) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这种方式比较简单只要加入sharding-jdbc-spring-boot-starter依赖,在application.yml中配置数据源,分片策略即可使用,这种方式简单,方便但是不够灵活
pom.xml文件如下:
4.0.0
shard-jdbc-starter
jar
shard-jdbc-starter
shard-jdbc-starter
com.sun
0.0.1-SNAPSHOT
UTF-8
1.8
2.0.3.RELEASE
3.0.0
1.2.0
1.1.6
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
io.shardingsphere
sharding-jdbc-spring-boot-starter
${sharding.jdbc.version}
io.shardingsphere
sharding-jdbc-spring-namespace
${sharding.jdbc.version}
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
com.alibaba
druid
${druid.version}
org.springframework.boot
spring-boot-dependencies
${spring_boot.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
application.yml
server:
port: 9900
spring:
application:
name: shard-jdbc-starter
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.sun.shard.bean
sharding:
jdbc:
datasource:
names: ds0,ds1
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/order1
username: root
password: root
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/order2
username: root
password: root
config:
sharding:
props:
sql.show: true
tables:
t_user: #t_user表
key-generator-column-name: id #主键
actual-data-nodes: ds${0..1}.t_user${0..1} #数据节点
database-strategy: #分库策略
inline:
sharding-column: city_id
algorithm-expression: ds${city_id % 2}
table-strategy: #分表策略
inline:
shardingColumn: sex
algorithm-expression: t_user${sex % 2}
t_address:
key-generator-column-name: id
actual-data-nodes: ds${0..1}.t_address
database-strategy:
inline:
shardingColumn: lit
algorithm-expression: ds${lit % 2}
启动类:
@SpringBootApplication
@MapperScan("com.sun.shard.mapper")
public class ShardApplication {
public static void main(String[] args) {
SpringApplication.run(ShardApplication.class, args);
}
}
pom.xml:
4.0.0
shard-jdbc-yb
jar
shard-jdbc-yb
shard-jdbc-yb
com.sun
0.0.1-SNAPSHOT
UTF-8
1.8
2.0.3.RELEASE
2.0.3
1.2.0
1.1.6
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
io.shardingjdbc
sharding-jdbc-core
${sharding.jdbc.version}
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
com.alibaba
druid
${druid.version}
org.springframework.boot
spring-boot-dependencies
${spring_boot.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
jdbc.properties文件:
jdbc.className1=com.mysql.jdbc.Driver
jdbc.url1=jdbc:mysql://127.0.0.1:3306/order1?characterEncoding=UTF-8
jdbc.user1=root
jdbc.password1=root
jdbc.className2=com.mysql.jdbc.Driver
jdbc.url2=jdbc:mysql://127.0.0.1:3306/order2?characterEncoding=UTF-8
jdbc.user2=root
jdbc.password2=root
jdbcconfig.java
package com.sun.shard.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@PropertySource(value = {"classpath:jdbc.properties"})
@Component
public class JdbcConfig {
private String className1;
@Value("${jdbc.url1}")
private String url1;
@Value("${jdbc.user1}")
private String user1;
@Value("${jdbc.password1}")
private String password1;
@Value("${jdbc.className2}")
private String className2;
@Value("${jdbc.url2}")
private String url2;
@Value("${jdbc.user2}")
private String user2;
@Value("${jdbc.password2}")
private String password2;
public String getClassName1() {
return className1;
}
public void setClassName1(String className1) {
this.className1 = className1;
}
public String getUrl1() {
return url1;
}
public void setUrl1(String url1) {
this.url1 = url1;
}
public String getUser1() {
return user1;
}
public void setUser1(String user1) {
this.user1 = user1;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getClassName2() {
return className2;
}
public void setClassName2(String className2) {
this.className2 = className2;
}
public String getUrl2() {
return url2;
}
public void setUrl2(String url2) {
this.url2 = url2;
}
public String getUser2() {
return user2;
}
public void setUser2(String user2) {
this.user2 = user2;
}
public String getPassword2() {
return password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
}
shardingconfig.java
package com.sun.shard.config;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.google.common.collect.Lists;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.InlineShardingStrategyConfiguration;
@Configuration
public class ShardingConfig {
@Autowired
private JdbcConfig jdbcConfig;
/**
* shardingjdbc数据源
* @return
* @throws SQLException
*/
@Bean
public DataSource dataSource() throws SQLException{
// 配置真实数据源
Map dataSourceMap = new HashMap<>();
DruidDataSource dataSource0 = createDb0();
dataSourceMap.put("ds0", dataSource0);
DruidDataSource dataSource1 = createDb1();
dataSourceMap.put("ds1", dataSource1);
TableRuleConfiguration tableRuleConfig = userRuleConfig();
// 配置分片规则
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(tableRuleConfig);
shardingRuleConfig.getTableRuleConfigs().add(addressRuleConfig());
Properties p = new Properties();
p.setProperty("sql.show",Boolean.TRUE.toString());
// 获取数据源对象
DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new ConcurrentHashMap(), p);
return dataSource;
}
/**
* user表分片策略
* @return
*/
private TableRuleConfiguration userRuleConfig() {
// 配置user表规则
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration();
tableRuleConfig.setLogicTable("t_user");
tableRuleConfig.setActualDataNodes("ds${0..1}.t_user${0..1}");
tableRuleConfig.setKeyGeneratorColumnName("id");
// 配置分库 + 分表策略
tableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("city_id", "ds${city_id % 2}"));
tableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("sex", "t_user${sex % 2}"));
return tableRuleConfig;
}
/**
* address表分片策略
* @return
*/
private TableRuleConfiguration addressRuleConfig() {
// 配置address表规则
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration();
tableRuleConfig.setLogicTable("t_address");
tableRuleConfig.setActualDataNodes("ds${0..1}.t_address");
tableRuleConfig.setKeyGeneratorColumnName("id");
// 配置分库 + 分表策略
tableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("lit", "ds${lit % 2}"));
return tableRuleConfig;
}
/**
* 第二数据源
* @return
*/
private DruidDataSource createDb0() {
// 配置第二个数据源
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbcConfig.getClassName1());
dataSource.setUrl(jdbcConfig.getUrl1());
dataSource.setUsername(jdbcConfig.getUser1());
dataSource.setPassword(jdbcConfig.getPassword1());
dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
// 每个分区最大的连接数
dataSource.setMaxActive(20);
// 每个分区最小的连接数
dataSource.setMinIdle(5);
return dataSource;
}
/**
* 第一数据源
* @return
*/
private DruidDataSource createDb1() {
// 配置第一个数据源
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbcConfig.getClassName2());
dataSource.setUrl(jdbcConfig.getUrl2());
dataSource.setUsername(jdbcConfig.getUser2());
dataSource.setPassword(jdbcConfig.getPassword2());
dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
// 每个分区最大的连接数
dataSource.setMaxActive(20);
// 每个分区最小的连接数
dataSource.setMinIdle(5);
return dataSource;
}
@Bean
public Filter statFilter(){
StatFilter filter = new StatFilter();
filter.setSlowSqlMillis(5000);
filter.setLogSlowSql(true);
filter.setMergeSql(true);
return filter;
}
@Bean
public ServletRegistrationBean statViewServlet(){
//创建servlet注册实体
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
//设置ip白名单
servletRegistrationBean.addInitParameter("allow","127.0.0.1");
//设置ip黑名单,如果allow与deny共同存在时,deny优先于allow
//servletRegistrationBean.addInitParameter("deny","192.168.0.19");
//设置控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","123456");
//是否可以重置数据
servletRegistrationBean.addInitParameter("resetEnable","false");
return servletRegistrationBean;
}
}
启动类:
@SpringBootApplication
@MapperScan("com.sun.shard.mapper")
public class ShardApplication {
public static void main(String[] args) {
SpringApplication.run(ShardApplication.class, args);
}
}
pom依赖和第二种一样
dataSource.yml文件如下:
dataSources:
ds0: !!com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/order1
username: root
password: root
ds1: !!com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/order2
username: root
password: root
shardingRule:
tables:
t_user:
actualDataNodes: ds${0..1}.t_user${0..1}
databaseStrategy:
inline:
shardingColumn: city_id
algorithmExpression: ds${city_id % 2}
tableStrategy:
inline:
shardingColumn: sex
algorithmExpression: t_user${sex % 2}
keyGeneratorColumnName: id
t_address:
actualDataNodes: ds${0..1}.t_address
databaseStrategy:
inline:
shardingColumn: lit
algorithmExpression: ds${lit % 2}
keyGeneratorColumnName: id
bindingTables:
- t_user,t_address
defaultDataSourceName: ds0
defaultDatabaseStrategy:
inline:
shardingColumn: id
algorithmExpression: ds${id % 2}
defaultTableStrategy:
none:
props:
sql.show: true
DuridConfig.java文件:
package com.sun.shard.config;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.support.http.StatViewServlet;
@Configuration
public class DuridConfig {
@Bean
public Filter statFilter(){
StatFilter filter = new StatFilter();
filter.setSlowSqlMillis(5000);
filter.setLogSlowSql(true);
filter.setMergeSql(true);
return filter;
}
@Bean
public ServletRegistrationBean statViewServlet(){
//创建servlet注册实体
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
//设置ip白名单
servletRegistrationBean.addInitParameter("allow","127.0.0.1");
//设置ip黑名单,如果allow与deny共同存在时,deny优先于allow
//servletRegistrationBean.addInitParameter("deny","192.168.0.19");
//设置控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","123456");
//是否可以重置数据
servletRegistrationBean.addInitParameter("resetEnable","false");
return servletRegistrationBean;
}
}
DataSourceConfig文件:
package com.sun.shard.config;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.Collections;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Lists;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.yaml.sharding.YamlShardingConfiguration;
@Configuration
public class DataSourceConfig {
@Autowired
private Filter statFilter;
private static final String SHARDING_YML_PATH = "sharding/dataSource.yml";
/**
* 构建dataSource
* 这里没有使用ShardingDataSourceFactory
* 因为要为durid数据源配置监听Filter
* @return
* @throws SQLException
* @throws IOException
*/
@Bean
public DataSource dataSource() throws SQLException, IOException {
YamlShardingConfiguration config = parse();
ShardingRule rule = config.getShardingRule(Collections.emptyMap());
rule.getDataSourceMap().forEach((k,v)->{
DruidDataSource d = (DruidDataSource) v;
d.setProxyFilters(Lists.newArrayList(statFilter));
});
return new ShardingDataSource(rule, config.getShardingRule().getConfigMap(), config.getShardingRule().getProps());
}
/**
* 解析yml
* @return
* @throws IOException
* @throws FileNotFoundException
* @throws UnsupportedEncodingException
*/
private YamlShardingConfiguration parse() throws IOException, FileNotFoundException, UnsupportedEncodingException {
Resource certResource = new ClassPathResource(SHARDING_YML_PATH);
try (
InputStreamReader inputStreamReader = new InputStreamReader(certResource.getInputStream(), "UTF-8")
) {
return new Yaml(new Constructor(YamlShardingConfiguration.class)).loadAs(inputStreamReader, YamlShardingConfiguration.class);
}
}
}
源码下载:https://gitee.com/sunqingzhong/springcloud_learning_course/blob/master/shardingjdbc.zip