当前位置: 首页 > article >正文

springboot 集成 shardingSphere 加mybatisplus 自带增加 分页查询 和源代码包 分库分表 单库 分表 使用雪花算法id

目录

介绍

代码下载

效果

数据库

 代码结构

上代码

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=utf8

mapper.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

持续更新


http://www.kler.cn/news/17361.html

相关文章:

  • node.js 处理路径问题
  • VR与AR:哪个有更大的潜力改变未来?
  • 今天面了个字节跳动拿35K出来的,真是砂纸擦屁股,给我露了一手啊
  • Skywalking
  • gtest之高级主题
  • Spring常用注解总结
  • PAT A1024 Palindromic Number
  • Java对象的创建方式以及对象的引用
  • 【Elsevier】中科院2区TOP, 高被引119篇, 稳定检索22年, 1周可见刊,5月15截稿~
  • Simulink 自动代码生成电机控制:弱磁控制从仿真到硬件开发板验证实验
  • 豪取BAT!超详细暑期实习算法面经(非科班无论文)
  • 如何监控一个程序的运行情况,然后视情况将进程杀死并重启
  • redis使用总结
  • 对传递函数的零极点、频率响应、稳定性的理解
  • Vue3 如何全局使用按钮截流指令
  • 复古决战快速施法穿墙秒怪分析流程及安全防护
  • 网络基础设施 拥塞控制
  • 基于JavaWeb实现的寻码网文章资讯管理系统
  • 动态页面配置
  • 我有一个方法判断你有没有编程天赋
  • ElasticSearch学习随笔之分词算法
  • 第17章 信息系统安全管理
  • IAST工具是如何工作的?主动和被动IAST有什么区别?
  • 信号完整性分析基础知识之传输线和反射(三):仿真和测试反射波形
  • 开放式基金净值估算数据 API 数据接口
  • 编写服务器重启的脚本(rc.local调用版本)
  • 基于GWO灰狼优化算法的城市路径优化问题GWO-TSP(MATLAB程序)
  • 操作系统——线程调度
  • SpringBoot整合Mybatis-Plus、Jwt实现登录token设置
  • Java回收垃圾的基本过程与常用算法