SpringBoot 整合 Sharding-JDBC 分庫分表
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
作者 | 陳彥斌
來源 | urlify.cn/F73IBj
導(dǎo)讀
分庫分表的技術(shù)有:數(shù)據(jù)庫中間件Mycat(點(diǎn)我直達(dá)),當(dāng)當(dāng)網(wǎng)開源的Sharding-JDBC;我們公司用的也是sharding-jdbc,自己也搭建一個(gè)完整的項(xiàng)目,直接可以拿來用。下面附源碼(CRUD,分頁,事務(wù)等都已測試過)
技術(shù)棧
SpringBoot 2.3.9
sharding-jdbc-core 2.0.3 (官網(wǎng)地址:點(diǎn)我直達(dá))
druid
mybatis-plus
lombok
mybatis | mybatisplus 分頁功能
統(tǒng)一異常處理器
項(xiàng)目結(jié)構(gòu)

pom.xml
<?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 https://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.3.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ybchen</groupId>
<artifactId>springboot-sharding</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-sharding</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--sharding-->
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>2.0.3</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--mybatis pagehelper分頁插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志級(jí)別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設(shè)置為WARN,則低于WARN的信息都不會(huì)輸出 -->
<!-- scan:當(dāng)此屬性設(shè)置為true時(shí),配置文件如果發(fā)生改變,將會(huì)被重新加載,默認(rèn)值為true -->
<!-- scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。 -->
<!-- debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是變量的名稱,value的值時(shí)變量定義的值。通過定義的值會(huì)被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。 -->
<property name="log.path" value="applog/" />
<property name="log.name" value="springboot-sharding"/>
<!--控制臺(tái)打印格式-->
<property name="CONSOLE_LOG_PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %C:%M:%L [%thread] %-5level %msg%n"/>
<!--debug文件打印格式-->
<property name="DEBUG_LOG_PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n"/>
<!-- 彩色日志 -->
<!-- 彩色日志依賴的渲染類 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--輸出到控制臺(tái)-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是為開發(fā)使用,只配置最底級(jí)別,控制臺(tái)輸出的日志級(jí)別是大于或等于此級(jí)別的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 設(shè)置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--輸出到文件-->
<!-- 時(shí)間滾動(dòng)輸出 level為 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/${log.name}/${log.name}_info.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN_FILE}</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志歸檔路徑以及格式 -->
<fileNamePattern>${log.path}/${log.name}/info/${log.name}-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數(shù)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄info級(jí)別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 時(shí)間滾動(dòng)輸出 level為 debug 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/${log.name}/${log.name}_debug.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>${DEBUG_LOG_PATTERN_FILE}</pattern>
<charset>UTF-8</charset> <!-- 此處設(shè)置字符集 -->
</encoder>
<!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/debug/${log.name}-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數(shù)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄DEBUG級(jí)別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 時(shí)間滾動(dòng)輸出 level為 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/${log.name}/${log.name}_error.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN_FILE}</pattern>
<charset>UTF-8</charset> <!-- 此處設(shè)置字符集 -->
</encoder>
<!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/error/${log.name}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數(shù)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄ERROR級(jí)別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<logger name="com.ybchen.mapper" level="DEBUG"/>
<logger name="com.ybchen" level="DEBUG"/>
</configuration>
application.properties
server.port=9999
# ds0
ds0.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
ds0.datasource.url=jdbc:mysql://localhost:3306/online_education?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
ds0.datasource.username=root
ds0.datasource.password=root
# ds1
ds1.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
ds1.datasource.url=jdbc:mysql://localhost:3306/online_education1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
ds1.datasource.username=root
ds1.datasource.password=root
UserMapper.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.ybchen.mapper.UserMapper">
<select id="all" resultType="com.ybchen.domain.UserDO">
SELECT * FROM t_user
</select>
<insert id="add" parameterType="com.ybchen.domain.UserDO">
INSERT INTO `t_user` (`id`, `user_name`, `age`, `create_time`, `tags`) VALUES (#{id}, #{userName}, #{age}, #{createTime}, #{tags})
</insert>
<update id="update" parameterType="com.ybchen.domain.UserDO">
update t_user set user_name=#{userName} where id=#{id}
</update>
<delete id="delete">
delete from t_user where id=#{id}
</delete>
</mapper>
SpringBootShardingApplication.java
package com.ybchen;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//忽略自動(dòng)裝配DataSource
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
//掃描Mapper
@MapperScan("com.ybchen.mapper")
//開啟事務(wù)
@EnableTransactionManagement
public class SpringbootShardingApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootShardingApplication.class, args);
}
}
DataSourceConfig.java
package com.ybchen;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.github.pagehelper.PageInterceptor;
import com.google.common.collect.Lists;
import groovy.util.logging.Slf4j;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.InlineShardingStrategyConfiguration;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
/**
* @Description:配置參考鏈接:https://shardingsphere.apache.org/document/legacy/3.x/document/cn/manual/sharding-jdbc/configuration/config-java/
* @Author:chenyanbin
* @Date:2021/4/15 上午11:44
* @Versiion:1.0
*/
@Configuration
@EnableTransactionManagement
@Slf4j
public class DataSourceConfig {
@Autowired
private Environment env;
@Bean
public Filter statFilter() {
StatFilter filter = new StatFilter();
filter.setSlowSqlMillis(5000);
filter.setLogSlowSql(true);
filter.setMergeSql(true);
return filter;
}
@Bean("sqlSessionFactory")
SqlSessionFactory sqlSessionFactory(
) throws Exception {
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
//設(shè)置數(shù)據(jù)源
sessionFactory.setDataSource(dataSource());
//設(shè)置分頁
sessionFactory.setPlugins(new Interceptor[]{mybatisPlusInterceptor(), pageInterceptor()});
//mapper掃描路徑
Resource[] r1 = new PathMatchingResourcePatternResolver()
.getResources("classpath*:com/ybchen/mapper/xml/*.xml");
Resource[] r2 = new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/*.xml");
List<Resource> list = new ArrayList<>();
list.addAll(Arrays.asList(r1));
list.addAll(Arrays.asList(r2));
sessionFactory.setMapperLocations(list.toArray(new Resource[list.size()]));
return sessionFactory.getObject();
}
//事務(wù)管理
@Bean
public DataSourceTransactionManager transactitonManager(@Autowired DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
//mybatis 分頁
public PageInterceptor pageInterceptor() {
PageInterceptor pi = new PageInterceptor();
Properties p = new Properties();
//當(dāng)該參數(shù)設(shè)置為 true 時(shí),pageNum<=0 時(shí)會(huì)查詢第一頁, pageNum>pages(超過總數(shù)時(shí)),會(huì)查詢最后一頁
p.setProperty("reasonable", "true");
pi.setProperties(p);
return pi;
}
//mybatis plus分頁
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}
@Bean
public DataSource dataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
//添加表
shardingRuleConfig.getTableRuleConfigs().add(tUserTableRuleConfiguration());
Properties properties = new Properties();
//是否開啟SQL顯示,默認(rèn)值: false
// properties.setProperty("sql.show", "true");
return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new HashMap<>(), properties);
}
/**
* 表分片規(guī)則配置對(duì)象,表:t_user
* 參考鏈接:https://shardingsphere.apache.org/document/legacy/3.x/document/cn/manual/sharding-jdbc/configuration/config-java/
*
* @return
*/
TableRuleConfiguration tUserTableRuleConfiguration() {
TableRuleConfiguration result = new TableRuleConfiguration();
//邏輯表名稱
result.setLogicTable("t_user");
//由數(shù)據(jù)源名 + 表名組成,以小數(shù)點(diǎn)分隔。多個(gè)表以逗號(hào)分隔,支持inline表達(dá)式。缺省表示使用已知數(shù)據(jù)源與邏輯表名稱生成數(shù)據(jù)節(jié)點(diǎn)。用于廣播表(即每個(gè)庫中都需要一個(gè)同樣的表用于關(guān)聯(lián)查詢,多為字典表)或只分庫不分表且所有庫的表結(jié)構(gòu)完全一致的情況
result.setActualDataNodes("ds${0..1}.t_user");
//分片列名稱
final String shardingColumn = "tags";
//分片算法行表達(dá)式,需符合groovy語法,表達(dá)式參考:https://shardingsphere.apache.org/document/legacy/3.x/document/cn/features/sharding/other-features/inline-expression/
final String algorithmExpression = "ds${tags%2}";
//ShardingStrategyConfiguration的實(shí)現(xiàn)類,用于配置行表達(dá)式分片策略。
result.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration(shardingColumn, algorithmExpression));
//自增列名稱,缺省表示不適用自增主鍵生成器
// result.setKeyGeneratorColumnName("id");
return result;
}
Map<String, DataSource> createDataSourceMap() {
Map<String, DataSource> result = new HashMap<>();
result.put("ds0", dataSource_0());
result.put("ds1", dataSource_1());
return result;
}
/**
* 數(shù)據(jù)源-0
*
* @return
*/
public DataSource dataSource_0() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(env.getProperty("ds0.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("ds0.datasource.url"));
dataSource.setUsername(env.getProperty("ds0.datasource.username"));
dataSource.setPassword(env.getProperty("ds0.datasource.password"));
dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
//每個(gè)分區(qū)最大的連接數(shù)
dataSource.setMaxActive(20);
//每個(gè)分區(qū)最小的連接數(shù)
dataSource.setMinIdle(5);
return dataSource;
}
/**
* 數(shù)據(jù)源-1
*
* @return
*/
public DataSource dataSource_1() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(env.getProperty("ds1.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("ds1.datasource.url"));
dataSource.setUsername(env.getProperty("ds1.datasource.username"));
dataSource.setPassword(env.getProperty("ds1.datasource.password"));
dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
//每個(gè)分區(qū)最大的連接數(shù)
dataSource.setMaxActive(20);
//每個(gè)分區(qū)最小的連接數(shù)
dataSource.setMinIdle(5);
return dataSource;
}
}
GlobalExceptions.java
package com.ybchen.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @ClassName:GlobalExceptiions
* @Description:全局異常
* @Author:chenyb
* @Date:2021/4/15 上午11:44
* @Versiion:1.0
*/
@ControllerAdvice
public class GlobalExceptions {
private final Logger logger = LoggerFactory.getLogger(getClass());
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Object handle(Exception ex) {
logger.error("「 全局異常 」 ===============》{}", ex);
return "「 全局異常 」錯(cuò)誤信息:"+ex.getMessage();
}
}
UserDO.java
package com.ybchen.domain;
import java.util.Date;
/**
* @Description:mybatis方式實(shí)體類
* @Author:chenyanbin
* @Date:2021/4/16 上午9:47
* @Versiion:1.0
*/
public class UserDO {
private String id;
private String userName;
private Integer age;
private Date createTime;
private Integer tags;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getTags() {
return tags;
}
public void setTags(Integer tags) {
this.tags = tags;
}
@Override
public String toString() {
return "UserDO{" +
"id='" + id + '\'' +
", userName='" + userName + '\'' +
", age=" + age +
", createTime=" + createTime +
", tags=" + tags +
'}';
}
}UserMybatisDO.java
package com.ybchen.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
/**
* @Description:mybatis plus方式實(shí)體類
* @Author:chenyanbin
* @Date:2021/4/16 上午9:47
* @Versiion:1.0
*/
@TableName("t_user")
public class UserMybatisDO {
@TableId(value = "id")
private String id;
@TableField("user_name")
private String userName;
@TableField("age")
private Integer age;
@TableField("create_time")
private Date createTime;
@TableField("tags")
private Integer tags;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getTags() {
return tags;
}
public void setTags(Integer tags) {
this.tags = tags;
}
@Override
public String toString() {
return "UserMybatisDO{" +
"id='" + id + '\'' +
", userName='" + userName + '\'' +
", age=" + age +
", createTime=" + createTime +
", tags=" + tags +
'}';
}
}UserMapper.java
package com.ybchen.mapper;
import com.ybchen.domain.UserDO;
import java.util.List;
public interface UserMapper {
//查詢
List<UserDO> all();
//添加
Integer add(UserDO userDO);
//更新
Integer update(UserDO userDO);
//刪除
Integer delete(String id);
}UserMybatisPlusMapper.java
package com.ybchen.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ybchen.domain.UserMybatisDO;
public interface UserMybatisPlusMapper extends BaseMapper<UserMybatisDO> {
}UserService.java
package com.ybchen.service;
import com.ybchen.domain.UserDO;
import com.ybchen.domain.UserMybatisDO;
import java.util.List;
/**
* @Description:
* @Author:chenyanbin
* @Date:2021/4/15 下午4:52
* @Versiion:1.0
*/
public interface UserService {
//mybatis 查詢
List<UserDO> all();
//mybatisplus 查詢
List<UserMybatisDO> allMybatisPlus();
//添加
Integer add(UserDO userDO);
//更新
Integer update(UserDO userDO);
//刪除
Integer delete(String id);
}UserServiceImpl.java
package com.ybchen.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.ybchen.domain.UserDO;
import com.ybchen.domain.UserMybatisDO;
import com.ybchen.mapper.UserMapper;
import com.ybchen.mapper.UserMybatisPlusMapper;
import com.ybchen.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
/**
* @Description:
* @Author:chenyanbin
* @Date:2021/4/15 下午4:53
* @Versiion:1.0
*/
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Autowired
UserMybatisPlusMapper userMybatisPlusMapper;
@Override
public List<UserDO> all() {
log.info("---info----");
log.debug("----debug----");
log.error("----error----");
//mybatis 分頁
PageHelper.startPage(4, 3);
return userMapper.all();
}
@Override
public List<UserMybatisDO> allMybatisPlus() {
//mybatis plus 分頁
int start = 4;
int end = 3;
IPage<UserMybatisDO> page = new Page<>(start, end);
return userMybatisPlusMapper.selectPage(page, null).getRecords();
}
@Override
//開啟事務(wù)
@Transactional
public Integer add(UserDO userDO) {
userDO.setId(UUID.randomUUID().toString().replace("-", ""));
userDO.setTags(LocalDateTime.now().getSecond());
userMapper.add(userDO);
//模擬事務(wù)失敗
int num = 1 / 0;
userDO.setAge(99);
userDO.setId(UUID.randomUUID().toString().replace("-", ""));
return userMapper.add(userDO);
}
@Override
public Integer update(UserDO userDO) {
return userMapper.update(userDO);
}
@Override
public Integer delete(String id) {
return userMapper.delete(id);
}
}UserController.java
package com.ybchen.controller;
import com.ybchen.domain.UserDO;
import com.ybchen.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Description:
* @Author:chenyanbin
* @Date:2021/4/15 下午4:52
* @Versiion:1.0
*/
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("all")
public Object all() {
return userService.all();
}
@PostMapping("allMybatisPlus")
public Object allMybatisPlus() {
return userService.allMybatisPlus();
}
@PostMapping("add")
public Object add(@RequestBody UserDO userDO) {
return userService.add(userDO);
}
@PostMapping("update")
public Object update(@RequestBody UserDO userDO) {
return userService.update(userDO);
}
@GetMapping("delete")
public Object delete(@RequestParam("id") String id) {
return userService.delete(id);
}
}數(shù)據(jù)庫

粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點(diǎn)贊支持下哈 
評(píng)論
圖片
表情
