shardingJDBC分庫分表


ShardingJDBC基礎環境

pom文件配置

<?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.datang</groupId>
    <artifactId>shardingjdbc1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-core</artifactId>
            <version>4.0.0-RC2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

    </dependencies>

</project>
View Code

基礎數據

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `sd`;

/*Table structure for table `t_order` */

DROP TABLE IF EXISTS `t_order`;

CREATE TABLE `t_order` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order` */

insert  into `t_order`(`user_id`,`order_id`,`product_name`) values (1,1,'芒果1'),(2,2,'芒果2'),(3,3,'芒果3'),(4,4,'芒果4'),(5,5,'芒果5'),(6,6,'芒果6'),(7,7,'芒果7'),(8,8,'芒果8'),(9,9,'芒果9'),(10,10,'芒果10');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

不分庫,不分表

下邊代碼片段只是引入了ShardingJDBC但未分庫分表。一個簡單的查詢。

package sjfp;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//數據分片,不分庫,不分表
public class SJFPDemo1 {
    public static void main(String[] args) throws Exception {
        // 配置真實數據源
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        DruidDataSource druidDataSource1 = new DruidDataSource();
        druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource1.setUrl("jdbc:mysql://39.105.59.232:3306/sd");
        druidDataSource1.setUsername("root");
        druidDataSource1.setPassword("1");
        dataSourceMap.put("sd", druidDataSource1);


        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "sd.t_order");

        // 配置分片規則
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

        Connection connection = dataSource.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int userId = resultSet.getInt(1);
            int orderId = resultSet.getInt(2);
            String productName = resultSet.getString(3);
            System.out.println(userId + "----" + orderId + "----" + productName);
        }
    }
}
View Code

不分庫,只分表

使用ShardingJDBC分庫分表,並不能自動的幫我們創建數據庫或者表,也就是說對於生產環境已經產生的數據需要我們手動自己遷移數據。

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `sd`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order0` */

insert  into `t_order0`(`user_id`,`order_id`,`product_name`) values (1,1,'芒果1'),(2,2,'芒果2'),(3,3,'芒果3'),(4,4,'芒果4'),(5,5,'芒果5'),(6,6,'芒果6'),(7,7,'芒果7'),(8,8,'芒果8'),(9,9,'芒果9'),(10,10,'芒果10');

/*Table structure for table `t_order1` */

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order1` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

現在t_order被分成了兩個表,但是t_order0的數據還是之前的我們暫且不修改。一下代碼還是一個簡單的查詢。

package sjfp;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//數據分片,分表
public class SJFPDemo2 {
    public static void main(String[] args) throws Exception {
        // 配置真實數據源
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        DruidDataSource druidDataSource1 = new DruidDataSource();
        druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource1.setUrl("jdbc:mysql://39.105.59.232:3306/sd");
        druidDataSource1.setUsername("root");
        druidDataSource1.setPassword("1");
         dataSourceMap.put("sd", druidDataSource1);


        // 配置Order表規則
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "sd.t_order${0..1}");

        // 配置分表策略
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order${order_id % 2}"));

        // 配置分片規則
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

        Connection connection = dataSource.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int userId = resultSet.getInt(1);
            int orderId = resultSet.getInt(2);
            String productName = resultSet.getString(3);
            System.out.println(userId + "----" + orderId + "----" + productName);
        }
    }
}
View Code

需要注意的是TableRuleConfiguration配置了t_order表的分表規則,t_order被拆成了多少個小表。setTableShardingStrategyConfig則配置了新增的數據使用什么規則放到不同的小表中。按照order_id%2來區分數據放到哪個表中,order_id是int類型當然不是0就是1。

下邊我們對數據進行新增,看看效果是否和配置規則一樣。

package sjfp;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//數據分片,分表
public class SJFPDemo3 {
    public static void main(String[] args) throws Exception {
        // 配置真實數據源
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        DruidDataSource druidDataSource1 = new DruidDataSource();
        druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource1.setUrl("jdbc:mysql://39.105.59.232:3306/sd");
        druidDataSource1.setUsername("root");
        druidDataSource1.setPassword("1");
         dataSourceMap.put("sd", druidDataSource1);


        // 配置Order表規則
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "sd.t_order${0..1}");

        // 配置分表策略
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order${order_id % 2}"));

        // 配置分片規則
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

        Connection connection = dataSource.getConnection();

        PreparedStatement preparedStatement1 = connection.prepareStatement("insert into t_order (order_id,product_name) values(11,'芒果11')");
        preparedStatement1.execute();

        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int userId = resultSet.getInt(1);
            int orderId = resultSet.getInt(2);
            String productName = resultSet.getString(3);
            System.out.println(userId + "----" + orderId + "----" + productName);
        }
    }
}
View Code

數據是成功的插入了,和預計的一樣插入到了t_order1表中,但有一點意料之外但是又必然的結果,在t_order1中的插入的數據id是1,也就是說自增id這里並沒有跨表自增。所以我們需要注意,當分庫分表時,你的唯一id是否需要調整。

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `sd`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order0` */

insert  into `t_order0`(`user_id`,`order_id`,`product_name`) values (1,1,'芒果1'),(2,2,'芒果2'),(3,3,'芒果3'),(4,4,'芒果4'),(5,5,'芒果5'),(6,6,'芒果6'),(7,7,'芒果7'),(8,8,'芒果8'),(9,9,'芒果9'),(10,10,'芒果10');

/*Table structure for table `t_order1` */

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order1` */

insert  into `t_order1`(`user_id`,`order_id`,`product_name`) values (1,11,'芒果11');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

接下來我們來測試刪除,既然新增的數據有id重復的,那么我們看看刪除時,會不會把兩個表中的id相同的數據都刪除掉。

package sjfp;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//數據分片,分表
public class SJFPDemo4 {
    public static void main(String[] args) throws Exception {
        // 配置真實數據源
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        DruidDataSource druidDataSource1 = new DruidDataSource();
        druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource1.setUrl("jdbc:mysql://39.105.59.232:3306/sd");
        druidDataSource1.setUsername("root");
        druidDataSource1.setPassword("1");
         dataSourceMap.put("sd", druidDataSource1);


        // 配置Order表規則
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "sd.t_order${0..1}");

        // 配置分表策略
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order${order_id % 2}"));

        // 配置分片規則
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

        Connection connection = dataSource.getConnection();

        PreparedStatement preparedStatement1 = connection.prepareStatement("delete from t_order where user_id=1");
        preparedStatement1.execute();

        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int userId = resultSet.getInt(1);
            int orderId = resultSet.getInt(2);
            String productName = resultSet.getString(3);
            System.out.println(userId + "----" + orderId + "----" + productName);
        }
    }
}
View Code

下面是執行刪除后的數據。

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `sd`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order0` */

insert  into `t_order0`(`user_id`,`order_id`,`product_name`) values (2,2,'芒果2'),(3,3,'芒果3'),(4,4,'芒果4'),(5,5,'芒果5'),(6,6,'芒果6'),(7,7,'芒果7'),(8,8,'芒果8'),(9,9,'芒果9'),(10,10,'芒果10');

/*Table structure for table `t_order1` */

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order1` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

分庫,分表 

分庫又分表,證明我們對數據的操作來自於多個數據庫的多個表。首先我們先創建空的數據結構。以下是兩個數據庫,沒個數據庫中有兩個order表

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd0
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd0` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `sd0`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


/*Data for the table `t_order0` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code
/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd0
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `sd1`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


/*Data for the table `t_order0` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

對於分庫分表來說,首先我們需要指定兩個數據源,因為有兩個數據庫。並且我們要指定分庫分表的策略,一條數據的插入到底是根據什么規則插入到哪個庫的哪張表中。

package sjfp;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

//數據分片,不分庫,不分表
public class SJFPDemo5 {
    public static void main(String[] args) throws Exception {
        // 配置真實數據源
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        DruidDataSource druidDataSource1 = new DruidDataSource();
        druidDataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource1.setUrl("jdbc:mysql://39.105.59.232:3306/sd0");
        druidDataSource1.setUsername("root");
        druidDataSource1.setPassword("1");
        dataSourceMap.put("sd0", druidDataSource1);

        DruidDataSource druidDataSource2 = new DruidDataSource();
        druidDataSource2.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource2.setUrl("jdbc:mysql://39.105.59.232:3306/sd1");
        druidDataSource2.setUsername("root");
        druidDataSource2.setPassword("1");
        dataSourceMap.put("sd1", druidDataSource2);


        // 配置Order表規則
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "sd${0..1}.t_order${0..1}");

        // 配置分庫 + 分表策略
        orderTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "sd${user_id % 2}"));
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order${order_id % 2}"));

        // 配置分片規則
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

        Connection connection = dataSource.getConnection();

        for (int i = 1; i < 20; i++) {
            PreparedStatement preparedStatement = connection.prepareStatement("insert into t_order (user_id,order_id,product_name) values (" + i + "," + i + ",'芒果" + i + "')");
            preparedStatement.execute();
        }

        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int userId = resultSet.getInt(1);
            int orderId = resultSet.getInt(2);
            String productName = resultSet.getString(3);
            System.out.println(userId + "----" + orderId + "----" + productName);
        }
    }
}
View Code

從結果來看,這個結果將數據插入到sd0中的t_order0表和sd1中的t_order1表中,好吧我承認這個規則是從官網抄的。user_id%2為0的插入sd0庫,所以sd0中只可能有雙數id的,sd1中只能有單數。接下來就該分表了,對於order_id%2為0的數據插入t_order0中,不為0的插入t_order1中,也就是說。sd0中只會是t_order0中有數據,而sd1中只會有t_order1中有數據。

/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd0
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd0` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `sd0`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order0` */

insert  into `t_order0`(`user_id`,`order_id`,`product_name`) values (2,2,'芒果2'),(4,4,'芒果4'),(6,6,'芒果6'),(8,8,'芒果8'),(10,10,'芒果10'),(12,12,'芒果12'),(14,14,'芒果14'),(16,16,'芒果16'),(18,18,'芒果18');

/*Table structure for table `t_order1` */

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order1` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code
/*
SQLyog v10.2 
MySQL - 5.7.24 : Database - sd1
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`sd1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `sd1`;

/*Table structure for table `t_order0` */

DROP TABLE IF EXISTS `t_order0`;

CREATE TABLE `t_order0` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order0` */

/*Table structure for table `t_order1` */

DROP TABLE IF EXISTS `t_order1`;

CREATE TABLE `t_order1` (
  `user_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `product_name` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_order1` */

insert  into `t_order1`(`user_id`,`order_id`,`product_name`) values (1,1,'芒果1'),(3,3,'芒果3'),(5,5,'芒果5'),(7,7,'芒果7'),(9,9,'芒果9'),(11,11,'芒果11'),(13,13,'芒果13'),(15,15,'芒果15'),(17,17,'芒果17'),(19,19,'芒果19');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM