springboot整合shardingjdbc(三种方式)

创建两个数据库order1,order2创建语句如下:

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整合

这种方式比较简单只要加入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);
	}
	
}

第二种  硬编码方式:

这种方式使用Java config的方式,数据源,分片策略都要编码,这种方式比较灵活,但是所有策略都要硬编码,不方便维护

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);
	}
	
}

第三种yml方式:

数据源分片策略使用单独yml文件配置,通过Java config方式定义数据源,这种方式比较推荐

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

你可能感兴趣的:(shardingjdbc)