shardingsphere-jdbc 分库分表+ springboot +MySQL

该博客介绍了如何在SpringBoot项目中集成ShardingSphere-JDBC,实现数据库的分库分表功能。配置了多个数据源,并定义了分库分表策略,包括自定义分片算法,以及数据源、表的逻辑和实际数据节点映射。同时,展示了相关配置文件,如application.properties和MyConfig类,用于管理数据源、分片规则和读写分离。此外,还包含了MyPreciseShardingAlgorithm和MyPreciseShardingAlgorithm1两个自定义分片算法类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

shardingsphere-jdbc 分库分表+ springboot +MySQL

maven依赖

<?xml version="1.0"?>
<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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!--<version>2.2.5.RELEASE</version>-->
        <version>1.5.5.RELEASE</version>
        <relativePath/>
    </parent>



	<groupId>com.example</groupId>
    <artifactId>test-shardingsphere</artifactId>
    <version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
    <description>Demo project for Spring Boot</description>



    <properties>
    </properties>

    <dependencies>
        <!--swagger ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--springboot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <!--sharding-jdbc-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>
        <!--mybatis starter-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.41</version>
        </dependency>
        <!--alibaba数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.12</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

springboot配置 application.properties

server.port=8090
spring.application.name=test-shardingSphere
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
spring.profiles.active=xml_config
#spring.profiles.active=class_config

springboot配置 application-class_config.properties

###如果使用这种方式,需要在启动类中加上exclude={DataSourceAutoConfiguration.class},如果使用配置文件方式,这个可加可不加
###奇怪的是我在MyConfig类上加@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})还是不行
spring.shardingsphere.enabled=false

springboot配置 application-xml_config.properties

# 数据源名称 是逻辑名称,不一定和数据库名一样
spring.shardingsphere.datasource.names=dsmsxf, dst001, dst002

# 第一个数据源
spring.shardingsphere.datasource.dsmsxf.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.dsmsxf.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dsmsxf.url=jdbc:mysql://127.0.0.1:3306/order_db0?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.dsmsxf.username=root
spring.shardingsphere.datasource.dsmsxf.password=123456


# 第二个数据源
spring.shardingsphere.datasource.dst001.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.dst001.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dst001.url=jdbc:mysql://127.0.0.1:3306/order_db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.dst001.username=root
spring.shardingsphere.datasource.dst001.password=123456

# 第三个数据源
spring.shardingsphere.datasource.dst002.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.dst002.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dst002.url=jdbc:mysql://127.0.0.1:3306/order_db2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.dst002.username=root
spring.shardingsphere.datasource.dst002.password=123456

# 默认数据源,不涉及分表的表会使用这个数据源,假设表t_user没有tenant_name字段,且不和其他表进行关联查询(如果和其他表要进行关联查询,则应该设置成广播表)
spring.shardingsphere.sharding.default-data-source-name=dsmsxf



# 默认的分库策略,分库字段和自定义分库类。下例中是按照表字段tenant_name,使用自定义方式MyPreciseShardingAlgorithm进行
spring.shardingsphere.sharding.default-database-strategy.standard.sharding-column=tenant_name
spring.shardingsphere.sharding.default-database-strategy.standard.precise-algorithm-class-name=com..config.MyPreciseShardingAlgorithm
# 默认分表策略,分表字段和自定义分表类。下例按照表字段id,使用自定义方式进行
spring.shardingsphere.sharding.default-table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.default-table-strategy.standard.precise-algorithm-class-name=com..config.MyPreciseShardingAlgorithm1


# 由数据源名 +"."+ 表名组成,多个表以逗号分隔,支持inline表达式。
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=dsmsxf.t_order$->{0..1},dst001.t_order$->{0..1},dst002.t_order$->{0..1}

# 表级分片策略
#spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
#spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order$->{order_id % 2}
#spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.sharding-column=id
#spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.precise-algorithm-class-name=com..config.MyPreciseShardingAlgorithm1
# 表对应的库的分片策略,如果不配置,将走默认配置
#spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.sharding-column=tenant_name
#spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.precise-algorithm-class-name=com..config.MyPreciseShardingAlgorithm
# 表的主键id 使用雪花算法生成,因此在insert语句里可以不用写主键列id
spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE

spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=dsmsxf.t_order_item$->{0..1},dst001.t_order_item$->{0..1},dst002.t_order_item$->{0..1}
# 这里不能走默认配置,因为分片列不是默认的ID字段,sharding-column和precise-algorithm-class-name必须成对出现
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.standard.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.standard.precise-algorithm-class-name=com..config.MyPreciseShardingAlgorithm1
# 表的主键id 使用雪花算法生成,因此在insert语句里可以不用写主键列id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.type=SNOWFLAKE


# 绑定表,t_order和t_order_item 使用相同的分片策略,都是用order_id进行分片,提升查询效率
spring.shardingsphere.sharding.binding-tables[0]=t_order,t_order_item
# 广播表:所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。且通过程序向表中插入数据时,会插入到所有库
spring.shardingsphere.sharding.broadcast-tables=t_dict,t_config

# 开启sql显示
spring.shardingsphere.props.sql.show=true


# 读写分离 <ds> 为逻辑名称,各个主从配置不重复即可
#spring.shardingsphere.sharding.master-slave-rules.ds01.master-data-source-name=主库对应的数据源名称
#spring.shardingsphere.sharding.master-slave-rules.ds01.slave-data-source-names=从库对应的数据源名称,多个从库以逗号分隔
#spring.shardingsphere.sharding.master-slave-rules.ds01.load-balance-algorithm-type=round_robin

#spring.shardingsphere.sharding.master-slave-rules.ds02.master-data-source-name=主库对应的数据源名称
#spring.shardingsphere.sharding.master-slave-rules.ds02.slave-data-source-names=从库对应的数据源名称,多个从库以逗号分隔
#spring.shardingsphere.sharding.master-slave-rules.ds02.load-balance-algorithm-type=round_robin

#分片策略总结:
#   分片策略分类:标准分片策略standard、复合分片策略complex、Hint分片策略hint、行表达式分片策略inline、不分片none。
#   库级分片策略:
#       全局默认配置:
#       spring.shardingsphere.sharding.default-database-strategy.<分片策略分类,如standard>.<分片策略分类对应的相关配置项>=xxxx
#       表级配置:
#       spring.shardingsphere.sharding.tables.<表名>.database-strategy.<分片策略分类,如standard>.<分片策略分类对应的相关配置项>=xxxx
#   表级分片策略:
#       全局默认配置:
#       spring.shardingsphere.sharding.default-table-strategy.<分片策略分类,如standard>.<分片策略分类对应的相关配置项>=xxxx
#       表级配置:
#       spring.shardingsphere.sharding.tables.<表名>.table-strategy.<分片策略分类,如standard>.<分片策略分类对应的相关配置项>=xxxx

#分库不分表总结:
#  全局配置:
#    1. 数据源名称(逻辑名称)配置:spring.shardingsphere.datasource.names。注意:名称不能有中划线或者下划线
#    2. 数据源配置,每个数据源名称都需要配置对应的数据源
#    3. 默认的分库策略配置:包括分库字段和分库算法
#    5. 绑定表:spring.shardingsphere.sharding.binding-tables
#    6. 广播表配置:spring.shardingsphere.sharding.broadcast-tables
#    7. 是否开启sql日志显示配置:spring.shardingsphere.props.sql.show
#  表级配置:
#    1. 表分库策略配置:包括分库字段和分库算法。当全局默认的分库策略不满足某表的分库策略时。
#    2. 表主键配置:如果主键是在代码中获取而不是在sql插入时自动生成,则不需要这个配置。包括主键列和主键生成策略配置。

#分表不分库总结:
#  全局配置:
#    1. 数据源名称(逻辑名称)配置:spring.shardingsphere.datasource.names。注意:名称不能有中划线或者下划线
#    2. 数据源配置,每个数据源名称都需要配置对应的数据源
#    4. 默认的分表策略配置:包括分表字段和分表算法
#    5. 绑定表:spring.shardingsphere.sharding.binding-tables
#    6. 广播表配置:spring.shardingsphere.sharding.broadcast-tables
#    7. 是否开启sql日志显示配置:spring.shardingsphere.props.sql.show
#  表级配置:
#    1. 表数据节点配置:spring.shardingsphere.sharding.tables.<tableName>.actual-data-nodes 必须配置
#    3. 表分表策略配置:包括分表字段和分表算法。当全局默认的分表策略不满足某表的分表策略时。如上述的t_order_item表
#    3. 表主键配置:如果主键是在代码中获取而不是在sql插入时自动生成,则不需要这个配置。包括主键列和主键生成策略配置。

#分库分表总结:
#  全局配置:
#    1. 数据源名称(逻辑名称)配置:spring.shardingsphere.datasource.names。注意:名称不能有中划线或者下划线
#    2. 数据源配置,每个数据源名称都需要配置对应的数据源
#    3. 默认的分库策略配置:包括分库字段和分库算法
#    4. 默认的分表策略配置:包括分表字段和分表算法
#    5. 绑定表:spring.shardingsphere.sharding.binding-tables
#    6. 广播表配置:spring.shardingsphere.sharding.broadcast-tables
#    7. 是否开启sql日志显示配置:spring.shardingsphere.props.sql.show
#  表级配置:
#    1. 表数据节点配置:spring.shardingsphere.sharding.tables.<tableName>.actual-data-nodes 必须配置
#    2. 表分库策略配置:包括分库字段和分库算法。当全局默认的分库策略不满足某表的分库策略时。
#    3. 表分表策略配置:包括分表字段和分表算法。当全局默认的分表策略不满足某表的分表策略时。如上述的t_order_item表
#    3. 表主键配置:如果主键是在代码中获取而不是在sql插入时自动生成,则不需要这个配置。包括主键列和主键生成策略配置。

#读写分离总结:
# 可以是分库不分表且读写分离,可以是分表不分库且读写分离,可以是分库分表且读写分离。
# 不管哪种场景,都只需要在原有场景中,添加读写分离配置即可


init.sql

CREATE TABLE `t_order0` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `config_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `order_name` varchar(111) NOT NULL COMMENT '',
  `tenant_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);
CREATE TABLE `t_order1` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `config_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `order_name` varchar(111) NOT NULL COMMENT '',
  `tenant_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);
CREATE TABLE `t_order_item0` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `order_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `dict_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `item_name` varchar(111) NOT NULL COMMENT '',
  `tenant_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);
CREATE TABLE `t_order_item1` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `order_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `dict_id`  bigint(20) unsigned NOT NULL  COMMENT '',
  `item_name` varchar(111) NOT NULL COMMENT '',
  `tenant_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);
CREATE TABLE `t_config` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `config_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);

CREATE TABLE `t_dict` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `dict_name` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);

CREATE TABLE `t_user` (
  `id`  bigint(20) unsigned NOT NULL  COMMENT '主键id',
  `username` varchar(111) NOT NULL COMMENT '',
  PRIMARY KEY (`id`)
);

insert into t_config values (1,'配置1');
insert into t_config values (2,'配置2');
insert into t_dict values (1,'字典1');
insert into t_dict values (2,'字典2');
insert into t_user values (1,'用户1');
insert into t_user values (2,'用户2');

MyConfig


@Configuration
@ConditionalOnProperty(prefix = "spring.shardingsphere", name = "enabled", havingValue = "false")
public class MyConfig {

    @Bean("dsmsxf")
    public DataSource dsmsxf(){
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl("jdbc:mysql://127.0.0.1:3306/order_db0?useUnicode=true&characterEncoding=utf-8&useSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        return ds;
    }
    @Bean("dst001")
    public DataSource dst001(){
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl("jdbc:mysql://127.0.0.1:3306/order_db1?useUnicode=true&characterEncoding=utf-8&useSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        return ds;
    }
    @Bean("dst002")
    public DataSource dst002(){
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl("jdbc:mysql://127.0.0.1:3306/order_db2?useUnicode=true&characterEncoding=utf-8&useSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        return ds;
    }
    @Bean("dataSource")
    public DataSource shardingDataSource(@Qualifier("dsmsxf")DataSource dsmsxf,@Qualifier("dst001") DataSource dst001,@Qualifier("dst002")DataSource dst002) throws SQLException {
        // 配置真实数据源
        Map<String, DataSource> dataSourceMap = new HashMap<>(3);
        dataSourceMap.put("dsmsxf", dsmsxf);
        dataSourceMap.put("dst001", dst001);
        dataSourceMap.put("dst002", dst002);
        // 配置分片规则
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.setDefaultDataSourceName("dsmsxf");
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("tenant_name", new MyPreciseShardingAlgorithm()));
        shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", new MyPreciseShardingAlgorithm1()));

        shardingRuleConfig.getTableRuleConfigs().add(orderRuleConfig());
        shardingRuleConfig.getTableRuleConfigs().add(orderItemRuleConfig());

        shardingRuleConfig.getBindingTableGroups().add("t_order,t_order_item");
        shardingRuleConfig.getBroadcastTables().add("t_dict,t_config");

        Properties p = new Properties();
        p.setProperty("sql.show",Boolean.TRUE.toString());
        // 获取数据源对象
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, p);
        return dataSource;
    }



    private TableRuleConfiguration orderRuleConfig() {
        TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order","dsmsxf.t_order$->{0..1},dst001.t_order$->{0..1},dst002.t_order$->{0..1}");
        tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id"));
//        tableRuleConfig.setTableShardingStrategyConfig();
//        tableRuleConfig.setDatabaseShardingStrategyConfig();
       return tableRuleConfig;
    }


    private TableRuleConfiguration orderItemRuleConfig() {
        TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order_item","dsmsxf.t_order_item$->{0..1},dst001.t_order_item$->{0..1},dst002.t_order_item$->{0..1}");
        tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id"));
        tableRuleConfig.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new MyPreciseShardingAlgorithm1()));
//        tableRuleConfig.setDatabaseShardingStrategyConfig();
        return tableRuleConfig;
    }

}

MyPreciseShardingAlgorithm

public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        String dbName = "ds";
        String val = shardingValue.getValue();
        dbName += val;
        for (String each : availableTargetNames) {
            if (each.equals(dbName)) {
                return each;
            }
        }
        throw new IllegalArgumentException();
    }
}

MyPreciseShardingAlgorithm1

public class MyPreciseShardingAlgorithm1 implements PreciseShardingAlgorithm<Long> {
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        String tbname=shardingValue.getLogicTableName();
        Long value = shardingValue.getValue();
        tbname+=value%2;
        return tbname;
    }
}

SwaggerConfig

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("分库分表").apiInfo(apiInfo())
                .protocols(Sets.newHashSet("http"))
                .select().apis(RequestHandlerSelectors.basePackage("com..controller"))
                .build().enable(true);
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("分库分表 - API").description("").termsOfServiceUrl("").version("5.0.0").build();
    }
}

OrderController

@RestController
@RequestMapping("/order")
@Api(description = "分库分表-订单模块")
public class OrderController {

    @Resource
    private OrderService orderService;


    @PostMapping("/createOrder")
    @ApiOperation(value = "创建订单", notes = "创建订单。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<String> createOrder(@RequestBody Order order){
        orderService.createOrder(order);
        return ResponseData.success("订单插入成功");
    }

    @PostMapping("/findAll")
    @ApiOperation(value = "查询全部", notes = "查询全部。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<String> findAll(){
        return ResponseData.success(orderService.findOrders());
    }

    @PostMapping("/findByTenantName")
    @ApiOperation(value = "根据租户查询全部", notes = "根据租户查询全部。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<String> findByTenantName(@RequestParam("tenantName") String tenantName){
        return ResponseData.success(orderService.findOrders(tenantName));
    }
    

    @PostMapping("/createDictAndConfig")
    @ApiOperation(value = "字典表新增", notes = "字典表新增。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<String> createDictAndConfig(@RequestParam("id") Long id,@RequestParam("dictName") String dictName,@RequestParam("configName") String configName){
        orderService.createDictAndConfig(id,dictName,configName);
        return ResponseData.success("插入成功");
    }

    @PostMapping("/findAllUser")
    @ApiOperation(value = "默认数据源,不涉及分表的表会使用这个数据源,查询用户", notes = "默认数据源,不涉及分表的表会使用这个数据源,查询用户。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<List<User>> findAllUser(){
        return ResponseData.success(orderService.findAllUser());
    }

    @PostMapping("/saveUser")
    @ApiOperation(value = "默认数据源,不涉及分表的表会使用这个数据源,保存用户", notes = "默认数据源,不涉及分表的表会使用这个数据源,保存用户。", produces = "application/json",
            extensions = {@Extension(properties = {@ExtensionProperty(name = "x-version", value = "5.0.0")})})
    public ResponseData<String> saveUser(@RequestParam("id") Long id,@RequestParam("userName") String userName){
        orderService.saveUser(id, userName);
        return ResponseData.success("保存用户成功");
    }

}

OrderService

@Service
@Transactional
public class OrderService {
    //这里建议用resource,如果用@Autowired注入,idea会报找不到对应的bean的错
    @Resource
    private OrderMapper orderMapper;

    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {

        List<OrderItem> orderItems = order.getOrderItems();
        // 保存订单记录
        orderMapper.insert(order);
        for (OrderItem o : orderItems) {

            o.setOrderId(order.getId());
            o.setTenantName(order.getTenantName());
            // 保存订单项记录
            orderMapper.insertItem(o);
        }

    }

    public List<OrderVo> findOrders() {
        return orderMapper.findAll();
    }

    public List<OrderVo> findOrders(String tenantName) {
        return orderMapper.findByTenantName(tenantName);
    }

    public void createDictAndConfig(Long id,String dictName, String configName) {
        orderMapper.createDict(id,dictName);
        orderMapper.createConfig(id,configName);
    }

    public List<User> findAllUser() {
        return orderMapper.findAllUser();
    }

    public void saveUser(Long id,String userName) {
        orderMapper.saveUser(id,userName);
    }
}

OrderMapper

@Mapper
public interface OrderMapper {
    /**
     * 这里需要返回主键,如果参数用@Param修饰,那么主键返回不回来,这个坑有点深
     * 如果没有使用shardingsphere 有没有@Param修饰都能返回
     * @param order
     * @return
     */
    int insert(Order order);
    int insertItem(@Param("data")OrderItem orderItem);
    List<OrderVo> findAll();
    List<OrderVo> findByTenantName(@Param("tenantName")String tenantName);
    void createDict(@Param("id")Long id,@Param("dictName")String dictName);
    void createConfig(@Param("id")Long id,@Param("configName")String configName);
    List<User> findAllUser();
    void saveUser(@Param("id")Long id,@Param("username")String username);
}

OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace参数为对应的mapper类的全路径-->
<mapper namespace="com..mapper.OrderMapper">
    <!--resultMap定义数据库表字段和Java对象属性映射关系,如果是多表操作或者数据库字段和Java属性字段不一致时必须配置-->
    <resultMap id="orderMap" type="com..model.Order">
        <id column="id" property="id"/>
        <result column="order_name" property="orderName"/>
        <result column="tenant_name" property="tenantName"/>
    </resultMap>
    <insert id="insert" parameterType="com..model.Order" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into t_order(order_name,tenant_name,config_id) values (#{orderName},#{tenantName},#{configId})
    </insert>
    <insert id="insertItem" parameterType="com..model.OrderItem">
        insert into t_order_item(order_id,item_name,tenant_name,dict_id) values
        (#{data.orderId},#{data.itemName},#{data.tenantName},#{data.dictId})
    </insert>
    <insert id="createDict">
      insert into t_dict(id,dict_name) values (#{id},#{dictName})
    </insert>
    <insert id="createConfig">
        insert into t_config(id,config_name)values(#{id},#{configName})
    </insert>
    <insert id="saveUser">
        insert into t_user(id,username) values (#{id},#{username})
    </insert>

    <sql id="selectField">
        o.id as orderId,toi.id as id,o.tenant_name as tenantName,o.order_name as orderName,
        toi.item_name as itemName,tc.config_name as configName,td.dict_name as dictName
    </sql>
    <select id="findAll" resultType="com..model.OrderVo">
        select <include refid="selectField"/>
         from t_order o left join  t_order_item toi on o.id=toi.order_id
         left join  t_config tc on o.config_id=tc.id
         left join  t_dict td on toi.dict_id=td.id order by toi.id desc
    </select>
    <select id="findByTenantName" resultType="com..model.OrderVo">
        select <include refid="selectField"/>
        from t_order o left join  t_order_item toi on o.id=toi.order_id
         left join  t_config tc on o.config_id=tc.id
         left join  t_dict td on toi.dict_id=td.id
        where o.tenant_name=#{tenantName} order by toi.id desc
    </select>
    <select id="findAllUser" resultType="com..model.User">
        select * from t_user
    </select>

</mapper>

Application

/**
 * 注意:不加exclude={DataSourceAutoConfiguration.class}使用class方式进行配置时,启动要报错
 */
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@MapperScan("com.test.mybatis")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

model

@Data
public class Order implements Serializable {
    private Long id;
    private Long configId;
    private String orderName;
    // 订单项
    List<OrderItem> orderItems;
    private String tenantName;
}
@Data
public class OrderItem implements Serializable {
    private Long orderId;
    private Long id;
    private Long dictId;
    private String itemName;
    private String tenantName;
}
@Data
public class OrderVo {
    private Long orderId;
    private String orderName;
    private String tenantName;
    private String dictName;
    private String configName;
    private Long id;
    private String itemName;
}
@Data
public class ResponseData<T> {
    private String code;
    private String message;
    private T data;
    public static ResponseData success(){
        ResponseData result = new ResponseData();
        result.code="0";
        return result;
    }

    public static <T> ResponseData success(T object){
        ResponseData result = new ResponseData();
        result.code="0";
        result.data=object;
        return result;
    }
}
@Data
public class User {
    private Long id;
    private String username;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值