• 解决Mybatis-plus高版本不向后兼容的问题


      mybatis-plus插件后面的版本没有兼容低版本。即:不存在低版本中EntityWrapper这个类了。而该类采用数据库表真实字段名作查询条件,这样硬编码形式确实不友好,比如如果后面数据库表中字段更名那么所有涉及到的业务都需要去修改,且硬编码形式没有遵循orm映射框架的设计理念。所以mybatis-plus后面的版本已经不支持该类操作了。

      但是这样造成一个问题。我们的一个项目开发设计时架构设计者采用了低版本的插件,但是项目进行一半时想要引入新版插件不兼容。要去一个个修改实在太麻烦,网上又没有这方面的文章。所以只能自己摸索出一个解决方案。

      解决的第一步大家可以参考这篇文章:https://www.cnblogs.com/java-jun-world2099/articles/11114501.html

      本以为就可以大功告成了,但是低高版本的插件内部设计重合度比较高(我并么有一步步去看原理),新的问题一个接一个。最后只能自己重写了BaseMapper和EntityWrapper这两个类。直接看代码好了:

    application.yml

    server:
      port: 8088
    
    spring:
      datasource:
        url: jdbc:mysql://xx.xx.xx.xxx:3306/ces?useUnicode=true&characterEncoding=utf-8
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
    
    
    
    
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      mapper-locations: classpath*:/mapper/*.xml

    pom文件

    <?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 http://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.1.6.RELEASE</version>
            <relativePath/>
        </parent>
        <groupId>com.bootjar</groupId>
        <artifactId>shadeboot</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>shadeboot</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>shadejar</groupId>
                <artifactId>plusjar</artifactId>
                <version>1.0</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-core</artifactId>
                <version>3.1.1</version>
            </dependency>
            <!--<dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.1.1</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>3.1.1</version>
            </dependency>-->
    
    
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatisplus-spring-boot-starter</artifactId>
                <version>1.0.5</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>2.2.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.1</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.6</version>
            </dependency>
            <!--lombok依赖-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.9.7</version>
            </dependency>
    
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    View Code

    实体类User

    @TableName("user")
    @Data
    public class User {
        @TableId
        private Long id;
        private String userName;
        private Integer age;
        private String email;
        private Date birth;
    
    }

    UserMapper接口

    package com.bootjar.shadeboot.mapper;
    
    import com.bootjar.shadeboot.entity.BaseMapper;
    import com.bootjar.shadeboot.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    
    /**
     * @author:shf date:2019/7/1 10:40
     */
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }

    EntityWrapper

    package com.bootjar.shadeboot.entity;
    
    import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
    import com.baomidou.mybatisplus.core.conditions.segments.NormalSegmentList;
    import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
    import com.baomidou.mybatisplus.core.metadata.TableInfo;
    import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
    import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
    
    import java.util.Objects;
    
    /**
     * @author:shf date:2019/7/1 14:13
     */
    public class EntityWrapper<T> extends com.baomidou.mybatisplus.mapper.EntityWrapper<T> {
        public T entity;
    
        public MergeSegments expression;
    
        public String lastSql = "";
    
        @Override
        public T getEntity() {
            return this.entity;
        }
    
        @Override
        public String getSqlSelect() {
            return null;
        }
    
        public String getSqlSet() {
            return null;
        }
    
        public MergeSegments getExpression() {
            return this.expression;
        }
    
        public String getCustomSqlSegment() {
            MergeSegments expression = this.getExpression();
            if (Objects.nonNull(expression)) {
                NormalSegmentList normal = expression.getNormal();
                String sqlSegment = this.getSqlSegment();
                if (StringUtils.isNotEmpty(sqlSegment)) {
                    if (normal.isEmpty()) {
                        return sqlSegment;
                    }
    
                    return this.concatWhere(sqlSegment);
                }
            }
    
            return "";
        }
    
        @Override
        public String getSqlSegment() {
            String sqlSegment = "";
            String sqlWhere = "";
            if (this.expression != null) {
                sqlSegment = this.expression.getSqlSegment();
            } else if (this.sql != null) {
                sqlWhere = this.sql.toString();
            }
    
            if (StringUtils.isNotEmpty(sqlSegment)) {
                return sqlSegment + this.lastSql;
            } else if (com.baomidou.mybatisplus.toolkit.StringUtils.isNotEmpty(sqlWhere)) {
               // return this.isWhere != null ? (this.isWhere ? sqlWhere : sqlWhere.replaceFirst("WHERE", this.AND_OR)) : sqlWhere.replaceFirst("WHERE", this.AND_OR);
                return sqlWhere;
            } else {
                return StringUtils.isNotEmpty(this.lastSql) ? this.lastSql : null;
            }
        }
    
        private String concatWhere(String sql) {
            return "WHERE " + sql;
        }
    
        @Override
        public boolean isEmptyOfWhere() {
            return this.isEmptyOfNormal() && this.isEmptyOfEntity();
        }
    
        public boolean nonEmptyOfWhere() {
            return !this.isEmptyOfWhere();
        }
    
        public boolean isEmptyOfNormal() {
            if(this.getExpression() != null){
                return CollectionUtils.isEmpty(this.getExpression().getNormal());
            }
           return true;
        }
    
        public boolean nonEmptyOfNormal() {
            return !this.isEmptyOfNormal();
        }
    
        public boolean nonEmptyOfEntity() {
            T entity = this.getEntity();
            if (entity == null) {
                return false;
            } else {
                TableInfo tableInfo = TableInfoHelper.getTableInfo(entity.getClass());
                if (tableInfo == null) {
                    return false;
                } else if (tableInfo.getFieldList().stream().anyMatch((e) -> {
                    return this.fieldStrategyMatch(entity, e);
                })) {
                    return true;
                } else {
                    return StringUtils.isNotEmpty(tableInfo.getKeyProperty()) ? Objects.nonNull(ReflectionKit.getMethodValue(entity, tableInfo.getKeyProperty())) : false;
                }
            }
        }
    
        private boolean fieldStrategyMatch(T entity, TableFieldInfo e) {
            switch (e.getFieldStrategy()) {
                case NOT_NULL:
                    return Objects.nonNull(ReflectionKit.getMethodValue(entity, e.getProperty()));
                case IGNORED:
                    return true;
                case NOT_EMPTY:
                    return StringUtils.checkValNotNull(ReflectionKit.getMethodValue(entity, e.getProperty()));
                default:
                    return Objects.nonNull(ReflectionKit.getMethodValue(entity, e.getProperty()));
            }
        }
    
        public boolean isEmptyOfEntity() {
            return !this.nonEmptyOfEntity();
        }
    
    }
    View Code

    BaseMapper

    package com.bootjar.shadeboot.entity;
    
    import com.baomidou.mybatisplus.mapper.Wrapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.session.RowBounds;
    
    import java.io.Serializable;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author:shf date:2019/7/1 13:17
     */
    public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {
        int insert(T var1);
    
        Integer insertAllColumn(T var1);
    
        int deleteById(Serializable var1);
    
        int deleteByMap(@Param("cm") Map<String, Object> var1);
    
        Integer delete(@Param("ew") Wrapper<T> var1);
    
        int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);
    
        int updateById(@Param("et") T var1);
    
        Integer updateAllColumnById(@Param("et") T var1);
    
        Integer update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);
    
        T selectById(Serializable var1);
    
        List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
    
        List<T> selectByMap(@Param("cm") Map<String, Object> var1);
    
        T selectOne(@Param("ew") T var1);
    
        Integer selectCount(@Param("ew") Wrapper<T> var1);
    
        List<T> selectList(@Param("ew") Wrapper<T> var1);
    
        List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);
    
        List<Object> selectObjs(@Param("ew") Wrapper<T> var1);
    
        List<T> selectPage(RowBounds var1, @Param("ew") Wrapper<T> var2);
    
        List<Map<String, Object>> selectMapsPage(RowBounds var1, @Param("ew") Wrapper<T> var2);
    
    
    }
    View Code

    测试类ShadebootApplicationTests

    package com.bootjar.shadeboot;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.bootjar.shadeboot.entity.EntityWrapper;
    import com.bootjar.shadeboot.entity.User;
    import com.bootjar.shadeboot.mapper.UserMapper;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ShadebootApplicationTests {
    
        @Autowired
        private UserMapper userMapper;
    
        //@Autowired
        //private UserCopyMapper userCopyMapper;
    
        @Test
        public void contextLoads() {
            User user = userMapper.selectById("1");
            System.out.println("--------------------user:" + user);
            EntityWrapper<User> itemWrapper = new EntityWrapper<>();
    
            itemWrapper.where("user_name = {0}", "Jack").eq("age", "20");
            List<User> itemsEntities = userMapper.selectList(itemWrapper);
            System.out.println("----------------itemsEntities :" + itemsEntities);
    
    
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                    .eq(User::getUserName, "Jack").last("ORDER BY id DESC");
            List<User> userList = userMapper.selectList(queryWrapper);
            System.out.println("----------------userList:" + userList);
        }
    
        @Test
        public void insertTest() {
            User user = new User();
            user.setUserName("dada");
            userMapper.insert(user);
        }
    
        @Test
        public void MapTest() {
            Map map = new HashMap();
            map.put("user_name", "1q");
            map.put("age", 18);
            List<User> MapList = userMapper.selectByMap(map);
            System.out.println("--------------------------MapList:" + MapList);
        }
    
    
    }
    View Code

    以上测试方法均通过,这是contextLoads方法的测试结果:

    JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7718a40f] will not be managed by Spring
    ==>  Preparing: SELECT id,user_name,age,email,birth FROM user WHERE id=? 
    ==> Parameters: 1(String)
    <==    Columns: id, user_name, age, email, birth
    <==        Row: 1, 1q, 18, test1@baomidou.com, 2019-01-01
    <==      Total: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@397ef2]
    --------------------user:User(id=1, userName=1q, age=18, email=test1@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019)
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1229a2b7] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7718a40f] will not be managed by Spring
    ==>  Preparing: SELECT id,user_name,age,email,birth FROM user WHERE (user_name = ? OR age = ?) 
    ==> Parameters: Jack(String), 20(String)
    <==    Columns: id, user_name, age, email, birth
    <==        Row: 2, Jack, 20, test2@baomidou.com, 2019-01-01
    <==        Row: 7, Jack, 24, test5@baomidou.com, 2019-01-01
    <==        Row: 8, Jack, 24, test5@baomidou.com, 2019-01-01
    <==        Row: 9, Jack, 24, test5@baomidou.com, 2019-01-01
    <==      Total: 4
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1229a2b7]
    ----------------itemsEntities :[User(id=2, userName=Jack, age=20, email=test2@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019), User(id=7, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019), User(id=8, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019), User(id=9, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019)]
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d95a72e] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7718a40f] will not be managed by Spring
    ==>  Preparing: SELECT id,user_name,age,email,birth FROM user WHERE user_name = ? AND ( age LIKE ? ) ORDER BY id DESC 
    ==> Parameters: Jack(String), %24%(String)
    <==    Columns: id, user_name, age, email, birth
    <==        Row: 9, Jack, 24, test5@baomidou.com, 2019-01-01
    <==        Row: 8, Jack, 24, test5@baomidou.com, 2019-01-01
    <==        Row: 7, Jack, 24, test5@baomidou.com, 2019-01-01
    <==      Total: 3
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d95a72e]
    ----------------userList:[User(id=9, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019), User(id=8, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019), User(id=7, userName=Jack, age=24, email=test5@baomidou.com, birth=Tue Jan 01 14:00:00 CST 2019)]
    2019-07-01 16:12:07.160  INFO 17744 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
    2019-07-01 16:12:07.164  INFO 17744 --- [       Thread-2] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed
    
    Process finished with exit code 0
    View Code
  • 相关阅读:
    常用SQL语句
    H5内嵌原生app
    github 从一个仓库换到另一个仓库
    vue使用install函数把组件做成插件方便全局调用
    git 支持tree命令
    vue---vue2.x自定义plugin,给vue添加全局方法,原型上增加全局方法
    vue 生命周期函数
    登录拦截设置白名单-坑
    vue
    vue实现滚动条滚到相应高度触发动画的操作
  • 原文地址:https://www.cnblogs.com/better-farther-world2099/p/11114729.html
Copyright © 2020-2023  润新知