目录
介绍
代码下载
效果
数据库
代码结构
上代码
pom.xml
yml配置
建表语句
mapper.xml
mybatisplus 配置.java
logback
application.java
BaseEntity
TUser
TUserMapper
TUserService
TUserServiceImpl
TUserController
测试
介绍
这套springboot + sharding sphere + mybatis plus 代码中有很多注释的,是可有可无类型,id放到了父类中,防止save 的时候,id变成0问题 实现id自动生成,全套一个shardingspere
代码下载
https://download.csdn.net/download/weixin_42749765/87759588
效果
数据库

代码结构

上代码
pom.xml
 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/>
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <start-class>com.superbase.fintech.Application</start-class>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>yml配置
server:
  port: 8080
spring:
  main:
    allow-bean-definition-overriding: true
  shardingsphere:
    props:
      sql:
        show: true	# 开启sql日志输出
    datasource:
      names: t0,t1
      t0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test_0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: admin
      t1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test_1?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: admin
    sharding:
      tables:
        t_user:
          actual-data-nodes: t0.t_user_$->{0..1}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: t_user_$->{id % 2}
          key-generator:
            column: id
            type: SNOWFLAKE
      binding-tables: t_user
pagehelper:
  # 指定使用的数据库数据库
  helperDialect: mysql
  # reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql
mybatis-plus:
  # 扫描 mapper.xml
  mapper-locations: classpath*:mapper/**/**.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.superbase.fintech
  global-config:
    db-config:
      #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
      id-type: auto
      #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
      field-strategy: 0
      #驼峰下划线转换
      column-underline: false
      #逻辑删除配置 使用mybatis plus内置方法默认过滤配置的逻辑删除字段,其他sql需手动过滤sql语句
      logic-delete-field: deleteFlag
      logic-delete-value: 1
      logic-not-delete-value: 0
      db-type: mysql
    refresh: false
  configuration:
    jdbc-type-for-null: 'null'
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: false # 二级缓存是否开启
    lazyLoadingEnabled: true #延时加载的开关
    aggressiveLazyLoading: false #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性
    multipleResultSetsEnabled: true
建表语句
CREATE TABLE `t_user_0` (
  `id` bigint NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `t_user_1` (
  `id` bigint NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mapper.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">
<mapper namespace="com.superbase.fintech.biz.mapper.TUserMapper">
</mapper>
mybatisplus 配置.java
package com.superbase.fintech.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
logback
<?xml version="1.0" encoding="UTF-8"?>
<!-- 分级别异步文件日志输出配置 -->
<!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志 -->
<!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- logback项目名称 -->
    <property name="appName" value="super-base"/>
    <!-- 日志级别 DEBUG INFO WARN ERROR -->
    <property name="logLevel" value="INFO"/>
    <!-- 日志路径-->
    <property name="logPath" value="/export/log"/>
    <!-- 最大保存时间 30天-->
    <property name="maxHistory" value="3"/>
    <!-- 异步缓冲队列的深度,该值会影响性能.默认值为256 -->
    <property name="queueSize" value="256"/>
    <!-- lOGGER  PATTERN 根据个人喜好选择匹配  -->
    <property name="logPattern" value="%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0} %X{traceId} - %m%n"/>
    <!-- 动态日志级别 -->
    <jmxConfigurator/>
    <!-- 控制台的标准输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <appender name="consoleDetail" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/${appName}/${appName}_detail.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${appName}/detail/${appName}_detail.log.%d{yyyy-MM-dd}.zip</fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <!-- DUBUG 日志记录  -->
    <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}/${appName}_debug.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${appName}/debug/${appName}_debug.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <!-- INFO 级别的日志记录  -->
    <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}/${appName}_info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${appName}/info/${appName}_info.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <!--  WARN 级别的日志记录 -->
    <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}/${appName}_warn.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${appName}/warn/${appName}_warn.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <!-- Error 级别的日志记录 -->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}/${appName}_error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${appName}/error/${appName}_error.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>
    <appender name="ASYNC_consoleDetail" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="consoleDetail"/>
    </appender>
    <!-- ASYNC_LOG_DEBUG  -->
    <appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_DEBUG"/>
    </appender>
    <!-- ASYNC_LOG_INFO -->
    <appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_INFO"/>
    </appender>
    <!-- ASYNC_LOG_WARN -->
    <appender name="ASYNC_LOG_WARN" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_WARN"/>
    </appender>
    <!--ASYNC_LOG_ERROR  -->
    <appender name="ASYNC_LOG_ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_ERROR"/>
    </appender>
    <logger name="org.springframework.web.servlet.DispatcherServlet" level="OFF"/>
    <logger name="org.springframework.web.context.support.XmlWebApplicationContext" level="OFF"/>
    <logger name="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" level="OFF"/>
    <!-- 日志的记录级别 -->
    <!-- 在定义后引用APPENDER -->
    <root level="${logLevel}">
        <!--  控制台  -->
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ASYNC_consoleDetail"/>
        <!-- 具体的日志级别和文件的配置 -->
        <appender-ref ref="ASYNC_LOG_DEBUG"/>
        <appender-ref ref="ASYNC_LOG_INFO"/>
        <appender-ref ref="ASYNC_LOG_WARN"/>
        <appender-ref ref="ASYNC_LOG_ERROR"/>
    </root>
</configuration>appplication.properties 里边空的就不写了
application.java
package com.superbase.fintech;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
/**
 * Application
 *
 * @author  jianghaoyu 
 */
//@SpringBootApplication
@Slf4j
@MapperScan("com.superbase.fintech.biz.mapper")
@SpringBootApplication(exclude={DruidDataSourceAutoConfigure.class})
public class Application {
    public static void main(String[] args) {
        log.info("  服务端启动开始");
        SpringApplication.run(Application.class, args);
        log.info("服务端启动成功");
    }
    
}
BaseEntity
package com.superbase.fintech.biz.entity;
import lombok.Data;
@Data
public class BaseEntity {
    private long id;
}
TUser
package com.superbase.fintech.biz.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
 * @author jianghaoyu
 * @since 2023-04-28
 */
@Data
//@EqualsAndHashCode(callSuper = true)
//@Accessors(chain = true)
//@TableName("t_user")
//public class TUser extends Model<TUser> {
public class TUser extends BaseEntity{
    /**
     * 主键Id 必须注释掉,才可自动生成
     */
//    private long id;
    /**
     * 名称
     */
    private String name;
    /**
     * 年龄
     */
    private int age;
}TUserMapper
package com.superbase.fintech.biz.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.superbase.fintech.biz.entity.TUser;
/**
 * <p>
 * 系统用户表 Mapper 接口
 * </p>
 *
 * @author  jianghaoyu 
 * @since 2023-04-28
 */
public interface TUserMapper extends BaseMapper<TUser> {
}
TUserService
package com.superbase.fintech.biz.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.superbase.fintech.biz.entity.TUser;
import java.util.List;
public interface TUserService extends IService<TUser> {
    /**
     * 保存用户信息
     *
     * @param entity
     * @return
     */
    @Override
    boolean save(TUser entity);
    /**
     * 查询全部用户信息
     *
     * @return
     */
    List<TUser> getUserList();
}TUserServiceImpl
package com.superbase.fintech.biz.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.superbase.fintech.biz.entity.TUser;
import com.superbase.fintech.biz.mapper.TUserMapper;
import com.superbase.fintech.biz.service.TUserService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements TUserService {
    @Override
    public boolean save(TUser entity) {
        return super.save(entity);
    }
    @Override
    public List<TUser> getUserList() {
        return baseMapper.selectList(Wrappers.lambdaQuery());
    }
}TUserController
package com.superbase.fintech.biz.ctr;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.superbase.fintech.biz.entity.TUser;
import com.superbase.fintech.biz.mapper.TUserMapper;
import com.superbase.fintech.biz.service.TUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * TUserController
 * @author  jianghaoyu  
 * 
 */
@RestController
public class TUserController {
    @Autowired
    private TUserService userService;
    @Autowired
    private TUserMapper tUserMapper;
    @GetMapping("/page")
    public IPage<TUser> page() {
        QueryWrapper<TUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("age");
        Page<TUser> page = new Page<>(2, 5);
        IPage<TUser> pageList = userService.page(page, queryWrapper);
        return pageList;
    }
    @GetMapping("/save")
    public Boolean insert(TUser user) {
        TUser t = new TUser();
        t.setName("cccccccccccccccc");
        return userService.save(t);
    }
    @RequestMapping("/dao/save")
    public String save() {
        TUser t = new TUser();
        t.setName("SS");
        tUserMapper.insert(t);
        return "true";
    }
}测试
http://localhost:8080/save
http://localhost:8080/page
ok
持续更新


















