Springboot,Mybatis-Plus,shardingjdbc实现单列分库,多租户整合

1,查看相关官方文档

https://shardingsphere.apache.org/document/legacy/3.x/document/cn/manual/sharding-jdbc/configuration/config-spring-boot/

https://baomidou.gitee.io/mybatis-plus-doc/#/tenant

https://gitee.com/baomidou/mybatisplus-spring-boot/blob/master/src/main/java/com/baomidou/springboot/config/MybatisPlusConfig.java

2,新建Maven项目,添加相关依赖



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.2.RELEASE
         
    
    com.example
    sharding-demo
    0.0.1-SNAPSHOT
    demo
    Demo project for Spring Boot

    
        1.8
        3.1.0
        1.1.12
        3.1.2
        1.2.58
    

    
        
            com.baomidou
            mybatis-plus-boot-starter
            compile
            ${mybatis-plus.version}
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            io.shardingsphere
            sharding-jdbc-spring-boot-starter
            ${sharding-sphere.version}
        
        
            io.shardingsphere
            sharding-transaction-spring-boot-starter
            ${sharding-sphere.version}
        

        
            org.projectlombok
            lombok
        
        
            org.springframework.boot
            spring-boot-test
            test
        
        
            com.alibaba
            druid
            ${druid.version}
        
        
            junit
            junit
            test
        
        
            com.alibaba
            fastjson
            ${fastjson.version}
        
        
            mysql
            mysql-connector-java
        
        
            org.apache.commons
            commons-lang3
        
        
            org.springframework
            spring-test
            5.1.8.RELEASE
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


3,目录结构

Springboot,Mybatis-Plus,shardingjdbc实现单列分库,多租户整合_第1张图片

4,application.yml

server:
  port: 9999

sharding:
  jdbc:
    datasource:
      names: ds0,ds1
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8
        username: root
        password: even
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8
        username: root
        password: even
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20
    config:
      sharding:
        binding-tables: t_order,t_order_item
        tables:
          t_order:
            actual-data-nodes: ds$->{0..1}.t_order
          t_order_item:
            actual-data-nodes: ds$->{0..1}.t_order_item
        default-database-strategy:
          complex:
            shardingColumns: user_id
            algorithmClassName: com.example.demo.mybatis.sharding.WarehouseComplexShardingDB
      props:
        sql.show: true
  # 自定义路由配置, 格式:     数据库 :分片id
  db-sharding-config:
    shardingColumn: user_id
    shardingDbConfs:
      -  {"ds0": ["0","2"]}
      -  {"ds1": ["1","3"]}

mybatis-plus:
  mapper-locations: classpath*:sqlmap/**/*.xml
  type-aliases-package: com.example.demo.mybatis.entity

logging:
  level:
    com.baomidou.mybatisplus.samples: debug
  

service,mapper,entity代码用mybatis-plus自动生成

5,config

Springboot,Mybatis-Plus,shardingjdbc实现单列分库,多租户整合_第2张图片

package com.example.demo.mybatis.config;

/*
 * Copyright (c) 2011-2020, baomidou ([email protected]).
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *

* https://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer; import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS; import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import io.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource; import io.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.mapping.DatabaseIdProvider; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.mapper.ClassPathMapperScanner; import org.mybatis.spring.mapper.MapperFactoryBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import javax.sql.DataSource; import java.util.List; /** * {@link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a * {@link SqlSessionFactory} and a {@link SqlSessionTemplate}. *

* If {@link org.mybatis.spring.annotation.MapperScan} is used, or a * configuration file is specified as a property, those will be considered, * otherwise this auto-configuration will attempt to register mappers based on * the interface definitions in or under the root auto-configuration package. *

* * @author Eddú Meléndez * @author Josh Long * @author Kazuki Shimizu * @author Eduardo Macarrón */ @Configuration @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) //@ConditionalOnSingleCandidate(ShardingDataSource.class) @EnableConfigurationProperties(MybatisPlusProperties.class) @AutoConfigureAfter(SpringBootConfiguration.class) public class MybatisPlusAutoConfiguration implements InitializingBean { private static final Logger logger = LoggerFactory.getLogger(com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration.class); private final MybatisPlusProperties properties; private final Interceptor[] interceptors; private final ResourceLoader resourceLoader; private final DatabaseIdProvider databaseIdProvider; private final List configurationCustomizers; private final List mybatisPlusPropertiesCustomizers; private final ApplicationContext applicationContext; public MybatisPlusAutoConfiguration(MybatisPlusProperties properties, ObjectProvider interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider databaseIdProvider, ObjectProvider> configurationCustomizersProvider, ObjectProvider> mybatisPlusPropertiesCustomizerProvider, ApplicationContext applicationContext) { this.properties = properties; this.interceptors = interceptorsProvider.getIfAvailable(); this.resourceLoader = resourceLoader; this.databaseIdProvider = databaseIdProvider.getIfAvailable(); this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable(); this.mybatisPlusPropertiesCustomizers = mybatisPlusPropertiesCustomizerProvider.getIfAvailable(); this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() { if (!CollectionUtils.isEmpty(mybatisPlusPropertiesCustomizers)) { mybatisPlusPropertiesCustomizers.forEach(i -> i.customize(properties)); } checkConfigFileExists(); } private void checkConfigFileExists() { if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) { Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation()); Assert.state(resource.exists(), "Cannot find config location: " + resource + " (please add config file or check your Mybatis configuration)"); } } @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Bean @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { // TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setVfs(SpringBootVFS.class); if (StringUtils.hasText(this.properties.getConfigLocation())) { factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation())); } applyConfiguration(factory); if (this.properties.getConfigurationProperties() != null) { factory.setConfigurationProperties(this.properties.getConfigurationProperties()); } if (!ObjectUtils.isEmpty(this.interceptors)) { factory.setPlugins(this.interceptors); } if (this.databaseIdProvider != null) { factory.setDatabaseIdProvider(this.databaseIdProvider); } if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); } if (this.properties.getTypeAliasesSuperType() != null) { factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType()); } if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) { factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); } if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { factory.setMapperLocations(this.properties.resolveMapperLocations()); } // TODO 自定义枚举包 if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) { factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage()); } // TODO 此处必为非 NULL GlobalConfig globalConfig = this.properties.getGlobalConfig(); // TODO 注入填充器 if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class, false, false).length > 0) { MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class); globalConfig.setMetaObjectHandler(metaObjectHandler); } // TODO 注入主键生成器 if (this.applicationContext.getBeanNamesForType(IKeyGenerator.class, false, false).length > 0) { IKeyGenerator keyGenerator = this.applicationContext.getBean(IKeyGenerator.class); globalConfig.getDbConfig().setKeyGenerator(keyGenerator); } // TODO 注入sql注入器 if (this.applicationContext.getBeanNamesForType(ISqlInjector.class, false, false).length > 0) { ISqlInjector iSqlInjector = this.applicationContext.getBean(ISqlInjector.class); globalConfig.setSqlInjector(iSqlInjector); } // TODO 设置 GlobalConfig 到 MybatisSqlSessionFactoryBean factory.setGlobalConfig(globalConfig); return factory.getObject(); } // TODO 入参使用 MybatisSqlSessionFactoryBean private void applyConfiguration(MybatisSqlSessionFactoryBean factory) { // TODO 使用 MybatisConfiguration MybatisConfiguration configuration = this.properties.getConfiguration(); if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) { configuration = new MybatisConfiguration(); } if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) { for (ConfigurationCustomizer customizer : this.configurationCustomizers) { customizer.customize(configuration); } } factory.setConfiguration(configuration); } @Bean @ConditionalOnMissingBean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { ExecutorType executorType = this.properties.getExecutorType(); if (executorType != null) { return new SqlSessionTemplate(sqlSessionFactory, executorType); } else { return new SqlSessionTemplate(sqlSessionFactory); } } /** * This will just scan the same base package as Spring Boot does. If you want * more power, you can explicitly use * {@link org.mybatis.spring.annotation.MapperScan} but this will get typed * mappers working correctly, out-of-the-box, similar to using Spring Data JPA * repositories. */ public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware { private BeanFactory beanFactory; private ResourceLoader resourceLoader; @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (!AutoConfigurationPackages.has(this.beanFactory)) { logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled."); return; } logger.debug("Searching for mappers annotated with @Mapper"); List packages = AutoConfigurationPackages.get(this.beanFactory); if (logger.isDebugEnabled()) { packages.forEach(pkg -> logger.debug("Using auto-configuration base package '{}'", pkg)); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); if (this.resourceLoader != null) { scanner.setResourceLoader(this.resourceLoader); } scanner.setAnnotationClass(Mapper.class); scanner.registerFilters(); scanner.doScan(StringUtils.toStringArray(packages)); } @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } } /** * {@link org.mybatis.spring.annotation.MapperScan} ultimately ends up * creating instances of {@link MapperFactoryBean}. If * {@link org.mybatis.spring.annotation.MapperScan} is used then this * auto-configuration is not needed. If it is _not_ used, however, then this * will bring in a bean registrar and automatically register components based * on the same component-scanning path as Spring Boot itself. */ @Configuration @Import({com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class}) @ConditionalOnMissingBean(MapperFactoryBean.class) public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean { @Override public void afterPropertiesSet() { logger.debug("No {} found.", MapperFactoryBean.class.getName()); } } }
package com.example.demo.mybatis.config;

import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author jiangxinjun
 * @date 2019/06/12
 */
@Configuration
@MapperScan({"com.example.demo.mybatis.mapper"})
public class MybatisPlusConfig {

    private static Map map = new HashMap<>();

    /**
     * 分页插件+多租户(自动注入user_id)
     *
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        /*
         * 【测试多租户】 SQL 解析处理拦截器
* 这里固定写成租户 1
*/ List sqlParserList = new ArrayList<>(); TenantSqlParser tenantSqlParser = new TenantSqlParser(); tenantSqlParser.setTenantHandler(new TenantHandler() { @Override public Expression getTenantId() { return new LongValue(1L); } @Override public String getTenantIdColumn() { return "user_id"; } @Override public boolean doTableFilter(String tableName) { // 这里可以判断是否过滤表 /*if ("user".equals(tableName)) { return true; }*/ return false; } }); sqlParserList.add(tenantSqlParser); paginationInterceptor.setSqlParserList(sqlParserList); return paginationInterceptor; } }
package com.example.demo.mybatis.sharding;

import com.google.common.collect.Sets;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author :     yuqin
 * @version :    1.0
 * @date :    2019/6/28 10:35
 */
@Component
@Data
@ConfigurationProperties(prefix = "sharding.db-sharding-config")
@ToString
public class ShardingConf {
    private static String SHARDING_COLUMN = "user_id";
    private static Map> SHARDING_DB_CONF = new HashMap<>();

    public void setShardingColumn(String shardingColumn){
        ShardingConf.SHARDING_COLUMN = shardingColumn;
    }

    public void setShardingDbConfs(List>> confs){
        ConcurrentHashMap> map = new ConcurrentHashMap<>(confs.size());
        confs.forEach(m -> m.forEach((db , valMap)-> map.put(db, Sets.newHashSet(valMap.values()))));
        SHARDING_DB_CONF = map;
    }

    public static String getShardingColumn(){
        return ShardingConf.SHARDING_COLUMN;
    }

    public static Map> getShardingDbConf() {
        return SHARDING_DB_CONF;
    }
}
package com.example.demo.mybatis.sharding;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import io.shardingsphere.api.algorithm.sharding.ListShardingValue;
import io.shardingsphere.api.algorithm.sharding.ShardingValue;
import io.shardingsphere.api.algorithm.sharding.complex.ComplexKeysShardingAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author snowalker
 * @version 1.0
 * @date 2019/3/23 10:55
 * @className WarehouseComplexShardingDB
 * @desc 自定义复合分片规则--数据源分片规则
 */
public class WarehouseComplexShardingDB implements ComplexKeysShardingAlgorithm {

    private static final Logger log = LoggerFactory.getLogger(WarehouseComplexShardingDB.class);

    /**
     * @param availableDatabasesNames 可用数据源集合
     * @param shardingValuesInfo          分片键
     * @return sharding results for data sources or tables's names
     */
    @Override
    public Collection doSharding(Collection availableDatabasesNames, Collection shardingValuesInfo) {

        log.info("availableDatabasesNames:" + JSON.toJSONString(availableDatabasesNames) + ",shardingValuesInfo:" + JSON.toJSONString(shardingValuesInfo));
        //进入通用复杂分片算法-抽象类-数据库路由:availableDatabasesNames=["ds0","ds1","ds2","ds3"],
        //shardingValuesInfo=[{"columnName":"user_id","logicTableName":"t_order","values":["1","2"]}]
        if (shardingValuesInfo == null || shardingValuesInfo.isEmpty()) {
            return availableDatabasesNames;
        }
        HashSet availableDatabasesNameSet = Sets.newHashSet(availableDatabasesNames);
        Set shardingResults = new HashSet<>();
        for (ShardingValue shardingValueInfo : shardingValuesInfo) {
            //匹配分库列
            if (!ShardingConf.getShardingColumn().equalsIgnoreCase(shardingValueInfo.getColumnName())) {
                break;
            }
            ListShardingValue listShardingValue = (ListShardingValue) shardingValueInfo;
            Collection shardingValues = listShardingValue.getValues();
            log.info("shardingValue:" + JSON.toJSONString(shardingValues));
            if (CollectionUtils.isEmpty(shardingValues)) {
                return shardingResults;
            }
            //noinspection unchecked
            shardingValues.forEach(shardingValue ->{
                String dbName = ShardingConf.getShardingDbConf().entrySet().stream()
                        .filter(en-> en.getValue().contains("" + shardingValue) && availableDatabasesNameSet.contains(en.getKey()))
                        .findFirst()
                        .map(Map.Entry::getKey)
                        .orElseThrow(() -> new RuntimeException("sharding not find error! table : " + shardingValueInfo.getLogicTableName() + " , shardingColumn:" +shardingValueInfo.getColumnName()+" , value: " + shardingValue.toString()));
                shardingResults.add(dbName);
            });
        }
        return shardingResults;
    }
}
/*
 * Copyright 2016-2018 shardingsphere.io.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *

*/ package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; /** * @author admin */ @SpringBootApplication(scanBasePackages = {"com.example.demo"},exclude = DataSourceAutoConfiguration.class) public class SpringBootStarterExample { public static void main(String[] args) { SpringApplication.run(SpringBootStarterExample.class, args); } }

注意:1,数据源有冲突,启动类排除掉DataSourceAutoConfiguration

           2,MybatisPlusConfig 中的getTenantId自己实现(可从cookie或者ThreadLocal获取)

           3,MybatisPlusAutoConfiguration 来自mybatis-plus-boot-start-3.1.2jar

               注释掉@ConditionalOnSingleCandidate(DataSource.class)

Springboot,Mybatis-Plus,shardingjdbc实现单列分库,多租户整合_第3张图片

Springboot,Mybatis-Plus,shardingjdbc实现单列分库,多租户整合_第4张图片

0库

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `des` varchar(100) NOT NULL,
  `total_price` decimal(10,3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_order
-- ----------------------------
INSERT INTO `t_order` VALUES ('2', '2', '白菜、可乐、香蕉', '6.000');

-- ----------------------------
-- Table structure for t_order_item
-- ----------------------------
DROP TABLE IF EXISTS `t_order_item`;
CREATE TABLE `t_order_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `goods_name` varchar(100) NOT NULL,
  `price` decimal(10,3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_order_item
-- ----------------------------
INSERT INTO `t_order_item` VALUES ('4', '2', '2', '白菜', '1.000');
INSERT INTO `t_order_item` VALUES ('5', '2', '2', '可乐', '2.000');
INSERT INTO `t_order_item` VALUES ('6', '2', '2', '香蕉', '3.000');
1库
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `des` varchar(100) NOT NULL,
  `total_price` decimal(10,3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_order
-- ----------------------------
INSERT INTO `t_order` VALUES ('1', '1', '白菜、可乐、香蕉', '6.000');

-- ----------------------------
-- Table structure for t_order_item
-- ----------------------------
DROP TABLE IF EXISTS `t_order_item`;
CREATE TABLE `t_order_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `goods_name` varchar(100) NOT NULL,
  `price` decimal(10,3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_order_item
-- ----------------------------
INSERT INTO `t_order_item` VALUES ('1', '1', '1', '白菜', '1.000');
INSERT INTO `t_order_item` VALUES ('2', '1', '1', '可乐', '2.000');
INSERT INTO `t_order_item` VALUES ('3', '1', '1', '香蕉', '3.000');

 

你可能感兴趣的:(Springboot,sharding,mybatis-plus,Sptingboot,Java,Sharding)