1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SpringBoot 整合 Sharding-JDBC 分庫分表

        共 51477字,需瀏覽 103分鐘

         ·

        2021-04-22 13:32

        點擊上方藍色字體,選擇“標(biāo)星公眾號”

        優(yōu)質(zhì)文章,第一時間送達

          作者 |  陳彥斌

        來源 |  urlify.cn/F73IBj

        導(dǎo)讀

          分庫分表的技術(shù)有:數(shù)據(jù)庫中間件Mycat(點我直達),當(dāng)當(dāng)網(wǎng)開源的Sharding-JDBC;我們公司用的也是sharding-jdbc,自己也搭建一個完整的項目,直接可以拿來用。下面附源碼(CRUD,分頁,事務(wù)等都已測試過)

        技術(shù)棧

        • SpringBoot 2.3.9

        • sharding-jdbc-core 2.0.3 (官網(wǎng)地址:點我直達)

        • druid

        • mybatis-plus

        • lombok

        • mybatis | mybatisplus 分頁功能

        • 統(tǒ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"?>
        <!-- 日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設(shè)置為WARN,則低于WARN的信息都不會輸出 -->
        <!-- scan:當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變,將會被重新加載,默認(rèn)值為true -->
        <!-- scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時,此屬性生效。默認(rèn)的時間間隔為1分鐘。 -->
        <!-- debug:當(dāng)此屬性設(shè)置為true時,將打印出logback內(nèi)部日志信息,實時查看logback運行狀態(tài)。默認(rèn)值為false。 -->
        <configuration  scan="true" scanPeriod="10 seconds">

            <contextName>logback</contextName>
            <!-- name的值是變量的名稱,value的值時變量定義的值。通過定義的值會被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。 -->
            <property name="log.path" value="applog/" />
            <property name="log.name" value="springboot-sharding"/>
            <!--控制臺打印格式-->
            <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}}"/>


            <!--輸出到控制臺-->
            <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
                <!--此日志appender是為開發(fā)使用,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息-->
                <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>


            <!--輸出到文件-->
            <!-- 時間滾動輸出 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>
                <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
                <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級別的 -->
                <filter class="ch.qos.logback.classic.filter.LevelFilter">
                    <level>info</level>
                    <onMatch>ACCEPT</onMatch>
                    <onMismatch>DENY</onMismatch>
                </filter>
            </appender>

            <!-- 時間滾動輸出 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>
                <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
                <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級別的 -->
                <filter class="ch.qos.logback.classic.filter.LevelFilter">
                    <level>DEBUG</level>
                    <onMatch>ACCEPT</onMatch>
                    <onMismatch>DENY</onMismatch>
                </filter>
            </appender>

            <!-- 時間滾動輸出 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>
                <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
                <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級別的 -->
                <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;

        //忽略自動裝配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 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數(shù)時),會查詢最后一頁
                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ī)則配置對象,表: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ù)點分隔。多個表以逗號分隔,支持inline表達式。缺省表示使用已知數(shù)據(jù)源與邏輯表名稱生成數(shù)據(jù)節(jié)點。用于廣播表(即每個庫中都需要一個同樣的表用于關(guān)聯(lián)查詢,多為字典表)或只分庫不分表且所有庫的表結(jié)構(gòu)完全一致的情況
                result.setActualDataNodes("ds${0..1}.t_user");
                //分片列名稱
                final String shardingColumn = "tags";
                //分片算法行表達式,需符合groovy語法,表達式參考:https://shardingsphere.apache.org/document/legacy/3.x/document/cn/features/sharding/other-features/inline-expression/
                final String algorithmExpression = "ds${tags%2}";
                //ShardingStrategyConfiguration的實現(xiàn)類,用于配置行表達式分片策略。
                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()));
                //每個分區(qū)最大的連接數(shù)
                dataSource.setMaxActive(20);
                //每個分區(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()));
                //每個分區(qū)最大的連接數(shù)
                dataSource.setMaxActive(20);
                //每個分區(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 "「 全局異常 」錯誤信息:"+ex.getMessage();
            }
        }

        UserDO.java

        package com.ybchen.domain;

        import java.util.Date;

        /**
         * @Description:mybatis方式實體類
         * @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方式實體類
         * @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 秒


        感謝點贊支持下哈 

        瀏覽 63
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            少妇一级婬片免费放2 | 爱爱网站久久 | 国产又粗又猛又大又爽的视频 | 狠狠狠狠的青草 | 熟女人妻在线 | 俺来俺来也www色官网 | 91女虐女调教 | 女主播一级A片免费播放 | 国产精品无码a v在线观看 | 黄色91视频 |