SpringBoot集成Redis,以及MybatisPlus分页、Mapper的使用(一)

来源:互联网 发布:mac 下安装ipython 编辑:程序博客网 时间:2024/06/03 15:52

概述

这段时间接触很多知识,也逐渐深入到项目整个流程开发,对Linux也有逐步地认识。虽然有去探索,但感觉能力还不足以写出来跟大家分享。撰写本文是了解到有些读者反馈,对于MP(MybatisPlus缩写)不太了解以及如何去使用,但更多还是笔者用完觉得非常强大,有必要share。文章还会主讲Redis配置使用,篇幅有点长,因此分为两节讲解。

构建

  • 开发环境:Spring Tool Suite(Version: 3.8.2.RELEASE当然,譬如Eclipse、MyEclipse等其他IDE工具也行)
  • 数据库:MySQL

项目结构

这里写图片描述
新建Maven项目,导入相关依赖包,pom.xml(根据个人需求可以去掉不必要的包)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.jekin.example</groupId>  <artifactId>redis-example</artifactId>  <version>0.0.1-SNAPSHOT</version>  <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <spring.boot.version>1.5.3.RELEASE</spring.boot.version>        <java.version>1.8</java.version>        <redis.version>1.4.7.RELEASE</redis.version>        <druid.version>1.0.0</druid.version>        <mybatisplus-spring-boot-starter.version>1.0.1</mybatisplus-spring-boot-starter.version>        <fastjson.version>1.2.31</fastjson.version>        <mysql.version>5.1.42</mysql.version>        <commons.lang3.version>3.5</commons.lang3.version>  </properties>  <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-dependencies</artifactId>                <version>${spring.boot.version}</version>                <type>pom</type>                <scope>import</scope>            </dependency>        </dependencies>    </dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-redis</artifactId>            <version>${redis.version}</version>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>${fastjson.version}</version>        </dependency>        <!-- 数据库连接池 -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>${druid.version}</version>        </dependency>        <dependency>            <groupId>com.baomidou</groupId>            <artifactId>mybatisplus-spring-boot-starter</artifactId>            <version>${mybatisplus-spring-boot-starter.version}</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-lang3</artifactId>            <version>${commons.lang3.version}</version>        </dependency>    </dependencies>    <build>        <plugins>            <!-- Maven编译版本 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <version>3.1</version>                <configuration>                    <executable>true</executable>                    <source>1.8</source>                    <target>1.8</target>                </configuration>            </plugin>            <!-- 为Spring Boot提供Maven操作支持 -->            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>                <configuration>                    <finalName>redis</finalName>                </configuration>                <executions>                    <execution>                    <!-- 重新打包成可执行包文件,达到一键启动运行 -->                        <goals>                            <goal>repackage</goal>                        </goals>                    </execution>                </executions>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-war-plugin</artifactId>                <version>2.6</version>                <configuration>                    <warSourceExcludes>src/main/resources/**</warSourceExcludes>                    <failOnMissingWebXml>false</failOnMissingWebXml>                </configuration>            </plugin>        </plugins>        <resources>            <resource>                <directory>src/main/resources</directory>            </resource>            <resource>                <directory>src/main/java</directory>                <includes>                    <include>**/*.xml</include>                </includes>            </resource>        </resources>    </build></project>

SpringBoot配置文件,application.yaml

server:  port: 8080spring:  main:    banner-mode: "off"  application:    name: redis  profiles:    active: local  thymeleaf:    cache: false  #前后端分离,关闭前端模板引擎,官方建议  http:    converters:      preferred-json-mapper: fastjson  redis:  #redis配置,不使用可删除    host: 192.168.1.70    password: rs0720$    port: 6379    pool:      max-idle: 10      min-idle: 1      max-active: 1000      max-wait: -1  datasource:      url: jdbc:mysql://192.168.1.70:3306/sharing?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false      username: *** #本地数据库用户名      password: *** #本地数据库密码      filters: mergeStatlogging:  config: classpath:logback-${spring.profiles.active}.xml###################  mybatis-plus配置  ###################mybatis-plus:   mapper-locations: classpath*:com/jekin/example/**/mapping/*.xml  typeAliasesPackage: com.jekin.example.entity  global-config:    id-type: 3  #1:数据库ID自增   2:用户输入id   3:全局唯一id(IdWorker)   4:全局唯一ID(uuid)    db-column-underline: false    refresh-mapper: true    is-capital-mode: false  configuration:    map-underscore-to-camel-case: true    cache-enabled: true #配置的缓存的全局开关    lazyLoadingEnabled: true #延时加载的开关    jdbcTypeForNull: NULL    multipleResultSetsEnabled: true #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句,调试用

数据源配置文件,DruidProperties.java

package com.jekin.example.properties;import java.sql.SQLException;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import com.alibaba.druid.pool.DruidDataSource;/** * <p>数据库数据源配置</p> * <p>说明:这个类中包含了许多默认配置,若这些配置符合您的情况,您可以不用管,若不符合,建议不要修改本类,建议直接在"application.yml"中配置即可</p> *  * @date 2017-05-21 11:18 */@Component@ConfigurationProperties(prefix = "spring.datasource")public class DruidProperties {    private String url = "jdbc:mysql://127.0.0.1:3306/operation?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";    private String username = "root";    private String password = "admin";    private String driverClassName = "com.mysql.jdbc.Driver";    private Integer initialSize = 2;    private Integer minIdle = 1;    private Integer maxActive = 20;    private Integer maxWait = 60000;    private Integer timeBetweenEvictionRunsMillis = 60000;    private Integer minEvictableIdleTimeMillis = 300000;    private String validationQuery = "SELECT 'x' from dual";    private Boolean testWhileIdle = true;    private Boolean testOnBorrow = false;    private Boolean testOnReturn = false;    private Boolean poolPreparedStatements = true;    private Integer maxPoolPreparedStatementPerConnectionSize = 20;    private String filters = "stat";    public void coinfig(DruidDataSource dataSource) {        dataSource.setUrl(url);        dataSource.setUsername(username);        dataSource.setPassword(password);        dataSource.setDriverClassName(driverClassName);        dataSource.setInitialSize(initialSize);     //定义初始连接数        dataSource.setMinIdle(minIdle);             //最小空闲        dataSource.setMaxActive(maxActive);         //定义最大连接数        dataSource.setMaxWait(maxWait);             //最长等待时间        // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);        // 配置一个连接在池中最小生存的时间,单位是毫秒        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);        dataSource.setValidationQuery(validationQuery);        dataSource.setTestWhileIdle(testWhileIdle);        dataSource.setTestOnBorrow(testOnBorrow);        dataSource.setTestOnReturn(testOnReturn);        // 打开PSCache,并且指定每个连接上PSCache的大小        dataSource.setPoolPreparedStatements(poolPreparedStatements);        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);        try {            dataSource.setFilters(filters);        } catch (SQLException e) {            e.printStackTrace();        }    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String getDriverClassName() {        return driverClassName;    }    public void setDriverClassName(String driverClassName) {        this.driverClassName = driverClassName;    }    public Integer getInitialSize() {        return initialSize;    }    public void setInitialSize(Integer initialSize) {        this.initialSize = initialSize;    }    public Integer getMinIdle() {        return minIdle;    }    public void setMinIdle(Integer minIdle) {        this.minIdle = minIdle;    }    public Integer getMaxActive() {        return maxActive;    }    public void setMaxActive(Integer maxActive) {        this.maxActive = maxActive;    }    public Integer getMaxWait() {        return maxWait;    }    public void setMaxWait(Integer maxWait) {        this.maxWait = maxWait;    }    public Integer getTimeBetweenEvictionRunsMillis() {        return timeBetweenEvictionRunsMillis;    }    public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) {        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;    }    public Integer getMinEvictableIdleTimeMillis() {        return minEvictableIdleTimeMillis;    }    public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;    }    public String getValidationQuery() {        return validationQuery;    }    public void setValidationQuery(String validationQuery) {        this.validationQuery = validationQuery;    }    public Boolean getTestWhileIdle() {        return testWhileIdle;    }    public void setTestWhileIdle(Boolean testWhileIdle) {        this.testWhileIdle = testWhileIdle;    }    public Boolean getTestOnBorrow() {        return testOnBorrow;    }    public void setTestOnBorrow(Boolean testOnBorrow) {        this.testOnBorrow = testOnBorrow;    }    public Boolean getTestOnReturn() {        return testOnReturn;    }    public void setTestOnReturn(Boolean testOnReturn) {        this.testOnReturn = testOnReturn;    }    public Boolean getPoolPreparedStatements() {        return poolPreparedStatements;    }    public void setPoolPreparedStatements(Boolean poolPreparedStatements) {        this.poolPreparedStatements = poolPreparedStatements;    }    public Integer getMaxPoolPreparedStatementPerConnectionSize() {        return maxPoolPreparedStatementPerConnectionSize;    }    public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;    }    public String getFilters() {        return filters;    }    public void setFilters(String filters) {        this.filters = filters;    }}

MP注解配置,MybatisPlusConfig.java

package com.jekin.example.config;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import com.alibaba.druid.pool.DruidDataSource;import com.baomidou.mybatisplus.enums.DBType;import com.baomidou.mybatisplus.plugins.PaginationInterceptor;import com.jekin.example.properties.DruidProperties;/** * MybatisPlus配置 *   * @author Jekin * @date 2017年10月31日上午11:36:30 */@Configuration@MapperScan(basePackages = {"com.jekin.example.mapper"})public class MybatisPlusConfig {    @Autowired    DruidProperties druidProperties;    /**     * mybatis-plus分页插件     */    @Bean    public PaginationInterceptor paginationInterceptor() {        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();        paginationInterceptor.setDialectType(DBType.MYSQL.getDb());        return paginationInterceptor;    }    /**     * druid数据库连接池     */    @Bean(initMethod = "init")    public DruidDataSource dataSource() {        DruidDataSource dataSource = new DruidDataSource();        druidProperties.coinfig(dataSource);        return dataSource;    }}

启动类,RedisExampleApplication.java

package com.jekin.example;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/** * 启动类 *   * @author fengjk   * @date 2017年6月27日 * @since 1.0 */@SpringBootApplicationpublic class RedisExampleApplication extends WebMvcConfigurerAdapter{    protected final static Logger logger = LoggerFactory.getLogger(RedisExampleApplication.class);    public static void main(String[] args) {        SpringApplication.run(RedisExampleApplication.class, args);        logger.info("RedisExampleApplication is sussess!");    }}

至此,SpringBoot集成MP框架就算搭建完成。下面,看下MP封装的常见mapper方法的使用。
创建实体类(略),映射文件(略),UserMapper.java

package com.jekin.example.mapper;import java.util.List;import org.apache.ibatis.annotations.Param;import com.baomidou.mybatisplus.mapper.BaseMapper;import com.baomidou.mybatisplus.plugins.Page;import com.jekin.example.entity.User;/** * 用户表 数据层 * */public interface UserMapper extends BaseMapper<User> {    List<User> getUserPage(@Param("page") Page<User> page,        @Param("orderByField") String orderByField, @Param("isAsc") boolean isAsc);}

getUserPage是分页方法,下节会提到。这里主要看下BaseMapper(MP对外mapper封装类)

/** * Copyright (c) 2011-2020, hubin (jobob@qq.com). * <p> * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */package com.baomidou.mybatisplus.mapper;import java.io.Serializable;import java.util.List;import java.util.Map;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.session.RowBounds;/** * <p> * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能 * </p> * <p> * 这个 Mapper 支持 id 泛型 * </p> * * @author hubin * @Date 2016-01-23 */public interface BaseMapper<T> {    /**     * <p>     * 插入一条记录     * </p>     *     * @param entity     *            实体对象     * @return int     */    Integer insert(T entity);    /**     * <p>     * 插入一条记录     * </p>     *     * @param entity     *            实体对象     * @return int     */    Integer insertAllColumn(T entity);    /**     * <p>     * 根据 ID 删除     * </p>     *     * @param id     *            主键ID     * @return int     */    Integer deleteById(Serializable id);    /**     * <p>     * 根据 columnMap 条件,删除记录     * </p>     *     * @param columnMap     *            表字段 map 对象     * @return int     */    Integer deleteByMap(@Param("cm") Map<String, Object> columnMap);    /**     * <p>     * 根据 entity 条件,删除记录     * </p>     *     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return int     */    Integer delete(@Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 删除(根据ID 批量删除)     * </p>     *     * @param idList     *            主键ID列表     * @return int     */    Integer deleteBatchIds(List<? extends Serializable> idList);    /**     * <p>     * 根据 ID 修改     * </p>     *     * @param entity     *            实体对象     * @return int     */    Integer updateById(T entity);    /**     * <p>     * 根据 ID 修改     * </p>     *     * @param entity     *            实体对象     * @return int     */    Integer updateAllColumnById(T entity);    /**     * <p>     * 根据 whereEntity 条件,更新记录     * </p>     *     * @param entity     *            实体对象     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return     */    Integer update(@Param("et") T entity, @Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 ID 查询     * </p>     *     * @param id     *            主键ID     * @return T     */    T selectById(Serializable id);    /**     * <p>     * 查询(根据ID 批量查询)     * </p>     *     * @param idList     *            主键ID列表     * @return List<T>     */    List<T> selectBatchIds(List<? extends Serializable> idList);    /**     * <p>     * 查询(根据 columnMap 条件)     * </p>     *     * @param columnMap     *            表字段 map 对象     * @return List<T>     */    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);    /**     * <p>     * 根据 entity 条件,查询一条记录     * </p>     *     * @param entity     *            实体对象     * @return T     */    T selectOne(@Param("ew") T entity);    /**     * <p>     * 根据 Wrapper 条件,查询总记录数     * </p>     *     * @param wrapper     *            实体对象     * @return int     */    Integer selectCount(@Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 entity 条件,查询全部记录     * </p>     *     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return List<T>     */    List<T> selectList(@Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 Wrapper 条件,查询全部记录     * </p>     *     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return List<T>     */    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 Wrapper 条件,查询全部记录     * </p>     *     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return List<Object>     */    List<Object> selectObjs(@Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 entity 条件,查询全部记录(并翻页)     * </p>     *     * @param rowBounds     *            分页查询条件(可以为 RowBounds.DEFAULT)     * @param wrapper     *            实体对象封装操作类(可以为 null)     * @return List<T>     */    List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);    /**     * <p>     * 根据 Wrapper 条件,查询全部记录(并翻页)     * </p>     *     * @param rowBounds     *            分页查询条件(可以为 RowBounds.DEFAULT)     * @param wrapper     *            实体对象封装操作类     * @return List<Map<String, Object>>     */    List<Map<String, Object>> selectMapsPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);}

就如作者说的,只要继承该接口,就可以使用里面的CURD,用起来十分方便快捷。
单元测试(使用例子),RedisTest.java

package com.jekin.example.test;import java.util.List;import org.junit.Test;import org.junit.runner.RunWith;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;import org.springframework.test.context.ActiveProfiles;import org.springframework.test.context.junit4.SpringRunner;import com.alibaba.fastjson.JSON;import com.baomidou.mybatisplus.mapper.EntityWrapper;import com.jekin.example.RedisExampleApplication;import com.jekin.example.entity.User;import com.jekin.example.mapper.UserMapper;import com.jekin.example.service.RedisService;@RunWith(SpringRunner.class)@SpringBootTest(classes = RedisExampleApplication.class,webEnvironment=WebEnvironment.RANDOM_PORT)@ActiveProfiles("local")public class RedisTest {    private static final Logger LOGGER = LoggerFactory.getLogger(RedisTest.class);    @Autowired    RedisService redisService;    @Autowired    UserMapper userMapper;    /*@Test    public void testRedis(){        redisService.set("haha", "1");        String str = redisService.get("haha");        LOGGER.info(str);    }*/    @Test    public void testMapper(){        // 新增        User use = new User();        userMapper.insert(use);        // 根据主键删除        userMapper.deleteById(898474800007831552L);        // 条件删除        userMapper.delete(new EntityWrapper<User>().eq("name", "Jekin"));        // 根据ID修改        userMapper.updateById(use);        // 条件修改        userMapper.update(use, new EntityWrapper<User>().eq("name", "Jekin"));        // 主键查询        User user = userMapper.selectById(898474800007831552L);        LOGGER.info("get user object:{}", JSON.toJSONString(user));        // 条件查询        List<User> users = userMapper.selectList(new EntityWrapper<User>().eq("name", "Jekin"));        LOGGER.info("get users list:{}", JSON.toJSONString(users));        // 多条件查询        List<User> users1 = userMapper.selectList(new EntityWrapper<User>().notIn("type", 1).eq("name", "Jekin"));        LOGGER.info("get users1 list:{}", JSON.toJSONString(users1));    }}

当存在多个环境时,才需要使用@ActiveProfiles来指定加载文件,此处可省略。以上基本覆盖了常用的方法,还有个别笔者没有一一列举,但都是大同小异,相信大家都可以举一反三。
日志文件,logback-local.xml

<?xml version="1.0" encoding="UTF-8"?><configuration debug="true">    <contextName>logback</contextName>    <property name="log.path" value="logs/redis.log" />    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">            <level>debug</level>        </filter>        <encoder>            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n            </pattern>        </encoder>    </appender>    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>${log.path}</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>        </rollingPolicy>        <encoder>            <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n            </pattern>        </encoder>    </appender>    <root level="debug">        <appender-ref ref="console" />    </root>    <logger name="org.springframework"  level="error" />    <logger name="org.apache.http"  level="error" />    <logger name="org.mybatis" level="debug" />    <logger name="java.sql" level="error" /></configuration>

总结

本章主要讲的是MP的集成,框架搭建,至此,如果只想学习SpringBoot项目搭建的话,可以到此止步,不必看下节内容,去掉Redis依赖包就完事了。下节讲解MP的分页以及Redis的配置使用。
如有问题或笔误,可以评论留言,亦可加Q群讨论学习:583138104。笔者每篇文章源码都会上传上去。
源码下载

阅读全文
3 0
原创粉丝点击