包含 分页、逻辑删除、自定义全局操作 等绝大部分常用功能的使用示例,相当于大整合的完整示例

  • pom.xml

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.2.0</version>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.49</version>
    <scope>test</scope>
    </dependency>
    <!-- for testing -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
  • application.yml

    # DataSource Config
    spring:
    datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:tcp://192.168.180.115:19200/~/mem/test
    username: root
    password: test

    # Logger Config
    logging:
    level:
    com.mp.deluxe: debug

    mybatis-plus:
    # 扫描 mapper.xml
    mapper-locations: classpath:/mapper/*Mapper.xml
    configuration:
    jdbc-type-for-null: 'null'
  • 配置类

    public interface MyBaseMapper<T> extends BaseMapper<T> {

    /**
    * 自定义通用方法
    */
    Integer deleteAll();

    int myInsertAll(T entity);

    /**
    * 如果要自动填充,@{@code Param}(xx) xx参数名必须是 list/collection/array 3个的其中之一
    *
    * @param batchList
    * @return
    */
    int mysqlInsertAllBatch(@Param("list") List<T> batchList);
    }

    @Configuration
    @MapperScan("com.mp.deluxe.mapper")
    public class MybatisPlusConfig {

    /**
    * 1.分页插件
    * 2.多租户
    */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
    }

    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
    return new OptimisticLockerInterceptor();
    }

    /**
    * 自定义 SqlInjector
    * 里面包含自定义的全局方法
    */
    @Bean
    public MyLogicSqlInjector myLogicSqlInjector() {
    return new MyLogicSqlInjector();
    }
    }

    public class TestTypeHandler extends BaseTypeHandler<String> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, "TestTypeHandler set {" + parameter + "}");
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    String string = rs.getString(columnName);
    return "TestTypeHandler(rs columnName) get {" + string + "}";
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    String string = rs.getString(columnIndex);
    return "TestTypeHandler(rs columnIndex) get {" + string + "}";
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    String string = cs.getString(columnIndex);
    return "TestTypeHandler(cs columnIndex) get {" + string + "}";
    }
    }

    @Data
    @Accessors(chain = true)
    public class User {
    private Long id;
    private String name;
    private Integer age;
    @TableField(typeHandler = TestTypeHandler.class)
    private String email;

    @Version
    private Integer version;

    @TableLogic(value = "0", delval = "1")
    @TableField(select = false)
    private Integer deleted;

    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Timestamp createTime;
    }
  • Mapper层

    public interface UserMapper extends MyBaseMapper<User> {

    /**
    * 自定义分页查询
    *
    * @param userPage 单独 user 模块使用的分页
    * @return 分页数据
    */
    UserPage selectUserPage(UserPage userPage);

    List<User> findList(@Param("user") User user);

    }
     
  • 方法层

    public class DeleteAll extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    /* 执行 SQL ,动态 SQL 参考类 SqlMethod */
    String sql = "delete from " + tableInfo.getTableName();
    /* mapper 接口方法名一致 */
    String method = "deleteAll";
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
    return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
    }

    public class MyInsertAll extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    String sql = "insert into %s %s values %s";
    StringBuilder fieldSql = new StringBuilder();
    fieldSql.append(tableInfo.getKeyColumn()).append(",");
    StringBuilder valueSql = new StringBuilder();
    valueSql.append("#{").append(tableInfo.getKeyProperty()).append("},");
    tableInfo.getFieldList().forEach(x->{
    fieldSql.append(x.getColumn()).append(",");
    valueSql.append("#{").append(x.getProperty()).append("},");
    });
    fieldSql.delete(fieldSql.length()-1, fieldSql.length());
    fieldSql.insert(0, "(");
    fieldSql.append(")");
    valueSql.insert(0, "(");
    valueSql.delete(valueSql.length()-1, valueSql.length());
    valueSql.append(")");
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(sql, tableInfo.getTableName(), fieldSql.toString(), valueSql.toString()), modelClass);
    return this.addInsertMappedStatement(mapperClass, modelClass, "myInsertAll", sqlSource, new NoKeyGenerator(), null, null);
    }
    }

    public class MysqlInsertAllBatch extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    final String sql = "<script>insert into %s %s values %s</script>";
    final String fieldSql = prepareFieldSql(tableInfo);
    final String valueSql = prepareValuesSqlForMysqlBatch(tableInfo);
    final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, valueSql);
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
    return this.addInsertMappedStatement(mapperClass, modelClass, "mysqlInsertAllBatch", sqlSource, new NoKeyGenerator(), null, null);
    }

    private String prepareFieldSql(TableInfo tableInfo) {
    StringBuilder fieldSql = new StringBuilder();
    fieldSql.append(tableInfo.getKeyColumn()).append(",");
    tableInfo.getFieldList().forEach(x -> {
    fieldSql.append(x.getColumn()).append(",");
    });
    fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
    fieldSql.insert(0, "(");
    fieldSql.append(")");
    return fieldSql.toString();
    }

    private String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
    final StringBuilder valueSql = new StringBuilder();
    valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
    valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
    tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
    valueSql.delete(valueSql.length() - 1, valueSql.length());
    valueSql.append("</foreach>");
    return valueSql.toString();
    }
    }
  • model层

    @Data
    @Accessors(chain = true)
    @EqualsAndHashCode(callSuper = true)
    public class UserPage extends Page<User> {
    private static final long serialVersionUID = 7246194974980132237L;

    private Integer selectInt;
    private String selectStr;

    public UserPage(long current, long size) {
    super(current, size);
    }
    }
  • 其他类

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

    @Override
    public void insertFill(MetaObject metaObject) {
    LOGGER.info("start insert fill ....");
    //避免使用metaObject.setValue()
    this.setInsertFieldValByName("createTime", new Timestamp(System.currentTimeMillis()), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    LOGGER.info("nothing to fill ....");
    }
    }

    public class MyLogicSqlInjector extends DefaultSqlInjector {

    /**
    * 如果只需增加方法,保留MP自带方法
    * 可以super.getMethodList() 再add
    * @return
    */
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
    List<AbstractMethod> methodList = super.getMethodList(mapperClass);
    methodList.add(new DeleteAll());
    methodList.add(new MyInsertAll());
    methodList.add(new MysqlInsertAllBatch());
    methodList.add(new SelectById());
    return methodList;
    }
    }
  • 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.mp.deluxe.mapper.UserMapper">

    <select id="selectUserPage" resultType="com.mp.deluxe.model.UserPage">
    select *
    from user
    <trim prefix="where" prefixOverrides="AND">
    <if test="selectInt != null">
    age = #{selectInt}
    </if>
    <if test="selectStr != null">
    AND name = #{selectStr}
    </if>
    AND deleted = 0
    </trim>
    </select>
    <!-- verify github #1532-->
    <select id="findList" parameterType="com.mp.deluxe.entity.User" resultType="com.mp.deluxe.entity.User">
    select * from user where name like concat(concat('%', #{user.name}), '%')
    </select>

    </mapper>
  • 测试类

    @SpringBootTest
    class DeluxeApplicationTests {

    @Resource
    private UserMapper mapper;

    @Test
    public void testPage() {
    // System.out.println("------ 自定义 xml 分页 ------");
    // UserPage selectPage = new UserPage(1, 5).setSelectInt(20);
    // UserPage userPage = mapper.selectUserPage(selectPage);
    // Assert.assertSame(userPage, selectPage);
    // System.out.println("总条数 ------> " + userPage.getTotal());
    // System.out.println("当前页数 ------> " + userPage.getCurrent());
    // System.out.println("当前每页显示数 ------> " + userPage.getSize());
    // print(userPage.getRecords());


    System.out.println("------ baseMapper 自带分页 ------");
    Page<User> page = new Page<>(1, 5);
    IPage<User> userIPage = mapper.selectPage(page, new QueryWrapper<User>().eq("age", 20));
    Assert.assertSame(userIPage, page);
    System.out.println("总条数 ------> " + userIPage.getTotal());
    System.out.println("当前页数 ------> " + userIPage.getCurrent());
    System.out.println("当前每页显示数 ------> " + userIPage.getSize());
    print(userIPage.getRecords());
    }

    @Test
    public void testDelAll() {
    mapper.deleteAll();
    }

    @Test
    public void testInsert() {
    User u = new User().setEmail("122@qq.com").setVersion(1).setDeleted(0);
    mapper.insert(u);

    u.setAge(18);
    mapper.updateById(u);
    u = mapper.selectById(u.getId());
    Assert.assertEquals("version should be updated",2, u.getVersion().intValue());
    }

    @Test
    public void testSelect() {
    System.out.println(mapper.selectById(1L));
    }

    private <T> void print(List<T> list) {
    if (!CollectionUtils.isEmpty(list)) {
    list.forEach(System.out::println);
    }
    }


    @Test
    public void myInsertAll(){
    long id =1008888L;
    User u = new User().setEmail("122@qq.com").setVersion(1).setDeleted(0).setId(id);
    mapper.myInsertAll(u);

    User user = mapper.selectById(id);
    Assert.assertNotNull(user);
    Assert.assertNotNull(user.getCreateTime());
    }

    @Test
    public void myInsertBatch(){
    long id = 1009991;
    List<User> batchList = new ArrayList<>(2);
    batchList.add(new User().setId(id++).setEmail("111@qq.com").setVersion(1).setDeleted(0));
    batchList.add(new User().setId(id).setEmail("112@qq.com").setVersion(1).setDeleted(0));
    mapper.mysqlInsertAllBatch(batchList);

    User user = mapper.selectById(1009991);
    Assert.assertNotNull(user);
    Assert.assertNotNull(user.getCreateTime());
    }

    @Test
    public void verifyGithub1532(){
    mapper.findList(new User().setName("a")).forEach(System.out::println);
    }

    }
  • 部分方法的测试结果

    2019-11-02 16:16:46.170  WARN 6088 --- [           main] c.b.m.core.injector.AbstractMethod       : [com.mp.deluxe.mapper.UserMapper.selectById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.SelectById]
    _ _ |_ _ _|_. ___ _ | _
    | | |\/|_)(_| | |_\ |_)||_|_\
    / |
    3.2.0
    2019-11-02 16:16:46.366 INFO 6088 --- [ main] com.mp.deluxe.DeluxeApplicationTests : Started DeluxeApplicationTests in 3.38 seconds (JVM running for 5.204)
    ------ baseMapper 自带分页 ------
    2019-11-02 16:16:46.680 INFO 6088 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
    2019-11-02 16:16:46.799 INFO 6088 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
    2019-11-02 16:16:46.873 DEBUG 6088 --- [ main] c.m.deluxe.mapper.UserMapper.selectPage : ==> Preparing: SELECT COUNT(1) FROM user WHERE deleted = 0 AND (age = ?)
    2019-11-02 16:16:46.893 DEBUG 6088 --- [ main] c.m.deluxe.mapper.UserMapper.selectPage : ==> Parameters: 20(Integer)
    2019-11-02 16:16:46.916 DEBUG 6088 --- [ main] c.m.deluxe.mapper.UserMapper.selectPage : ==> Preparing: SELECT id,create_time,name,version,email,age FROM user WHERE deleted=0 AND (age = ?) limit ?
    2019-11-02 16:16:46.928 DEBUG 6088 --- [ main] c.m.deluxe.mapper.UserMapper.selectPage : ==> Parameters: 20(Integer), 5(Long)
    2019-11-02 16:16:46.946 DEBUG 6088 --- [ main] c.m.deluxe.mapper.UserMapper.selectPage : <== Total: 5
    总条数 ------> 13
    当前页数 ------> 1
    当前每页显示数 ------> 5
    User(id=2, name=Jack, age=20, email=test2@baomidou.com, version=1, deleted=null, createTime=null)
    User(id=3, name=Jack, age=20, email=test2@baomidou.com, version=1, deleted=null, createTime=null)
    User(id=4, name=Jack, age=20, email=test2@baomidou.com, version=1, deleted=null, createTime=null)
    User(id=5, name=Jack, age=20, email=test2@baomidou.com, version=1, deleted=null, createTime=null)
    User(id=6, name=Jack, age=20, email=test2@baomidou.com, version=1, deleted=null, createTime=null)

SpringBoot与MybatisPlus3.X整合示例(十六)的更多相关文章

  1. SpringBoot与PageHelper的整合示例详解

    SpringBoot与PageHelper的整合示例详解 1.PageHelper简介 PageHelper官网地址: https://pagehelper.github.io/ 摘要: com.gi ...

  2. SpringBoot与MybatisPlus3.X整合之通用枚举(十二)

    一 通用枚举 解决了繁琐的配置,让 mybatis 优雅的使用枚举属性! 自3.1.0开始,可配置默认枚举处理类来省略扫描通用枚举配置 默认枚举配置 升级说明: 3.1.0 以下版本改变了原生默认行为 ...

  3. SpringBoot与MybatisPlus3.X整合之字段类型处理器(八)

    pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...

  4. SpringBoot与MybatisPlus3.X整合之动态表名 SQL 解析器(七)

    pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...

  5. SpringBoot | 第二十六章:邮件发送

    前言 讲解了日志相关的知识点后.今天来点相对简单的,一般上,我们在开发一些注册功能.发送验证码或者订单服务时,都会通过短信或者邮件的方式通知消费者,注册或者订单的相关信息.而且基本上邮件的内容都是模版 ...

  6. 二十六:Struts2 和 spring整合

    二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...

  7. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

  8. 跟我学SpringCloud | 第十六篇:微服务利剑之APM平台(二)Pinpoint

    目录 SpringCloud系列教程 | 第十六篇:微服务利剑之APM平台(二)Pinpoint 1. Pinpoint概述 2. Pinpoint主要特性 3. Pinpoint优势 4. Pinp ...

  9. Spring Boot 2.X(十六):应用监控之 Spring Boot Actuator 使用及配置

    Actuator 简介 Actuator 是 Spring Boot 提供的对应用系统的自省和监控功能.通过 Actuator,可以使用数据化的指标去度量应用的运行情况,比如查看服务器的磁盘.内存.C ...

随机推荐

  1. 从SpringMVC获取用户信息谈起

    Github地址:https://github.com/andyslin/spring-ext 编译.运行环境:JDK 8 + Maven 3 + IDEA + Lombok spring-boot: ...

  2. visual c++.net 技术内幕 第6版 附带的程序如何在vs2013中编译成功

    看vc++技术内幕时 如果你使用的是比此书的附带项目更新版的vs时千万不要使用这种方法,这些对编译都有影响. 请使用当前新版的vs并输入书中改动的代码就Ok,因为vs会生成合理的mfc代码,养成好的习 ...

  3. 在创建activiti5..22所需的25张表时 ,所用的方法和遇到的问题。

    最近在学习关于activiti流程设计的相关内容,首先第一步就需要了解25张activiti相关的表,具体的每张表的含义 请自行百度. 这里讲一下 用java代码生成所需要的25张表,很简单: pub ...

  4. xpath语法分享

    # xpath语法: ## 使用方式: 使用//获取整个页面当中的元素,然后写标签名,然后再写谓词进行提取.比如: ``` //div[@class='abc'] ``` ## 需要注意的知识点: 1 ...

  5. 集合线性表--List之LinkedList(队列与栈)

    队列和栈1. Queue 队列(Queue)是常用的数据结构,可以将队列看成特殊的线性表,队列限制了对线性表的访问方式:只能从线性表的一端添加(offer)元素,从另一端取出(poll)元素.队列遵循 ...

  6. beego之操作model

    beego之操作model 1.环境配置 1>.下载安装orm go get github.com/astaxie/beego/orm 默认安装路径在gopath路径下,可使用go env查看路 ...

  7. 小程序webview调用微信扫一扫的“曲折”思路

    自上一篇遇到webview中没有返回按钮之后,虽然跳出坑了.解决方案:<小程序webview跳转页面后没有返回按钮完美解决方案> 但是,小程序踩坑之路并没有结束.在公众号网页中通过配置AP ...

  8. @ConfigurationProperties、@Value、@PropertySource

    @ConfigurationProperties(spring-boot依赖下).@Value(spring-beans依赖下).@PropertySource(spring-context依赖下) ...

  9. 从干将莫邪的故事说起--java比较操作注意要点

    故事背景 <搜神记>: 楚干将.莫邪为楚王作剑,三年乃成.王怒,欲杀之.剑有雌雄.其妻重身当产.夫语妻曰:“吾为王作剑,三年乃成.王怒,往必杀我.汝若生子是男,大,告之曰:‘出户望南山,松 ...

  10. 浅析十大常见排序(含C++代码)

    首先声明一下,本文只对十种排序算法做简单总结,并参照一些资料给出自己的代码实现,并没有对某种算法理论讲解,更详细的 了解可以参考以下资料: 1.<data structure and algor ...