SpringBoot——MyBatis-Plus source code analysis and detailed explanation of development practice

focus w x:CodingTechWork

introduction

  It has been used in the previous company Spring Data JPA. It is an enhanced support for the JPA-based data access layer. The bottom layer uses Hibernatethe framework and supports the use of native SQL or JPQLquery language. JPAIt is based on the separation ORMof the code and the code, that is, a new layer is added between the code and the indirect operation . You may think that the learning cost is relatively high, but it is actually okay, and no files are needed .   However, in the new company, using the oriented- based model , it may be more intuitive and friendly to operate complex operations by writing files , and take off in situ when combined . This article mainly summarizes some practical experience and source code analysis.DBDBDBxml
MybatisMybatisDBSQLSQLmapperxmlDBMybatisMybatis-PlusMybatis-Plus

Introduction to MyBatis-Plus

overview

  MyBatis-PlusIt is Mybatisan enhanced tool that can simplify development and improve our development efficiency.

features

  1. Non-intrusive: Yes Mybatisenhancement tool, no invasive changes.
  2. Rich lambda call support: Lambdawrite various queries through expressions.
  3. Powerful CRUD operation support: built-in Mapperand IServiceinterface and various operation methods.
  4. Built-in paging plug-in: Based on MyBatis physical paging, developers don't need to care about specific operations.
    ...

Common Notes

@TableName

Description: Annotation on the table name, identifying the entity class.

@TableId

Description: primary key annotation

IdType type

value illustrate
AUTO Database ID auto-increment
NONE By default, there is no state, and this type is an unset primary key type (in the annotation, it is equal to follow the global, and the global Rio is equal to INPUT)
INPUT Set the primary key value before insert
ASSIGN_ID Assign ID (primary key type is Number (Long and Integer) or String) (since 3.3.0), use the method nextId of interface IdentifierGenerator (default implementation class is DefaultIdentifierGenerator snowflake algorithm)
ASSIGN_UUID Assign UUID, the primary key type is String (since 3.3.0), use the method nextUUID of interface IdentifierGenerator (default default method)
ID_WORKER Distributed globally unique ID long integer type (please use ASSIGN_ID)
UUID 32-bit UUID string (please use ASSIGN_UUID)
ID_WORKER_STR Distributed globally unique ID string type (please use ASSIGN_ID)

@TableField

Description: Field annotation (non-primary key)
common attributes:

Attributes Type must specify a default value description
value String No "" Database field name
exist boolean No true Whether it is a database table field

MyBatis-Plus source code analysis

IService native CURD interface

save

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 根据插入批次数量,插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

saveorUpdate

// TableId 注解存在更新记录,是否插入一条记录或者更新记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 根据插入批次数量,批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

remove

// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

update

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据插入批次数量,根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

get

// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

list

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

page

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

Mapper's native CURD interface

insert

int insert(T entity);

delete

    int deleteById(Serializable id);

    int deleteById(T entity);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

    int delete(@Param("ew") Wrapper<T> queryWrapper);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

update

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

select

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

    default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
    
    
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
    
    
            if (ts.size() != 1) {
    
    
                throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
            } else {
    
    
                return ts.get(0);
            }
        } else {
    
    
            return null;
        }
    }

    Long selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

page

    <P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);

    <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);

pagination

principle

  1. The paging interceptor PaginationInnerInterceptorintercepts all query requests. beforeQueryWhen querying, it first determines whether the parameters contain IPagetype parameters.
  2. If it contains IPagetype parameters, paging query will be performed according to the passed parameter value, otherwise, no paging will be performed.

PaginationInnerInterceptor source code

Location:mybatis-plus-extension-3.4.3.4.jar#PaginationInnerInterceptor

public class PaginationInnerInterceptor implements InnerInterceptor {
    
    
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    
    
    	//判断并寻找IPage参数
        IPage<?> page = (IPage)ParameterUtils.findPage(parameter).orElse((Object)null);
        //参数中包含IPage类型参数,则执行分页
        if (null != page) {
    
    
            boolean addOrdered = false;
            String buildSql = boundSql.getSql();
            List<OrderItem> orders = page.orders();
            if (CollectionUtils.isNotEmpty(orders)) {
    
    
                addOrdered = true;
                buildSql = this.concatOrderBy(buildSql, orders);
            }
			//根据page参数,组装分页查询sql
            Long _limit = page.maxLimit() != null ? page.maxLimit() : this.maxLimit;
            //无需分页
            if (page.getSize() < 0L && null == _limit) {
    
    
                if (addOrdered) {
    
    
                    PluginUtils.mpBoundSql(boundSql).sql(buildSql);
                }

            } else {
    
    
                this.handlerLimit(page, _limit);
                IDialect dialect = this.findIDialect(executor);
                Configuration configuration = ms.getConfiguration();
                //构建分页sql
                DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());
                MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
                List<ParameterMapping> mappings = mpBoundSql.parameterMappings();
                Map<String, Object> additionalParameter = mpBoundSql.additionalParameters();
                model.consumers(mappings, configuration, additionalParameter);
                mpBoundSql.sql(model.getDialectSql());
                mpBoundSql.parameterMappings(mappings);
            }
        }
    }
}

ParameterUtils

Location:mybatis-plus-core-3.4.3.4.jar#ParameterUtils

public class ParameterUtils {
    
    
    private ParameterUtils() {
    
    
    }

    public static Optional<IPage> findPage(Object parameterObject) {
    
    
        if (parameterObject != null) {
    
    
        	//若多个参数,转为map对象,任意一个value包含IPage类型对象,则返回IPage对象
            if (parameterObject instanceof Map) {
    
    
                Map<?, ?> parameterMap = (Map)parameterObject;
                Iterator var2 = parameterMap.entrySet().iterator();

                while(var2.hasNext()) {
    
    
                    Entry entry = (Entry)var2.next();
                    if (entry.getValue() != null && entry.getValue() instanceof IPage) {
    
    
                        return Optional.of((IPage)entry.getValue());
                    }
                }
            } else if (parameterObject instanceof IPage) {
    
    
            	//单个参数,若类型为IPage,则返回IPage对象
                return Optional.of((IPage)parameterObject);
            }
        }
		//参数中无IPage类型参数,则返回空
        return Optional.empty();
    }
}

public class MySqlDialect implements IDialect {
    
    
    public MySqlDialect() {
    
    
    }

    public DialectModel buildPaginationSql(String originalSql, long offset, long limit) {
    
    
    	//拼接构建分页sql
        StringBuilder sql = (new StringBuilder(originalSql)).append(" LIMIT ").append("?");
        if (offset != 0L) {
    
    
            sql.append(",").append("?");
            return (new DialectModel(sql.toString(), offset, limit)).setConsumerChain();
        } else {
    
    
            return (new DialectModel(sql.toString(), limit)).setConsumer(true);
        }
    }
}

lambda function

Compare interface source code

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.core.conditions.interfaces;

import java.io.Serializable;
import java.util.Map;
import java.util.function.BiPredicate;

public interface Compare<Children, R> extends Serializable {
    
    
    default <V> Children allEq(Map<R, V> params) {
    
    
        return this.allEq(params, true);
    }

    default <V> Children allEq(Map<R, V> params, boolean null2IsNull) {
    
    
        return this.allEq(true, params, null2IsNull);
    }

    <V> Children allEq(boolean condition, Map<R, V> params, boolean null2IsNull);

    default <V> Children allEq(BiPredicate<R, V> filter, Map<R, V> params) {
    
    
        return this.allEq(filter, params, true);
    }

    default <V> Children allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) {
    
    
        return this.allEq(true, filter, params, null2IsNull);
    }

    <V> Children allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull);

    default Children eq(R column, Object val) {
    
    
        return this.eq(true, column, val);
    }

    Children eq(boolean condition, R column, Object val);

    default Children ne(R column, Object val) {
    
    
        return this.ne(true, column, val);
    }

    Children ne(boolean condition, R column, Object val);

    default Children gt(R column, Object val) {
    
    
        return this.gt(true, column, val);
    }

    Children gt(boolean condition, R column, Object val);

    default Children ge(R column, Object val) {
    
    
        return this.ge(true, column, val);
    }

    Children ge(boolean condition, R column, Object val);

    default Children lt(R column, Object val) {
    
    
        return this.lt(true, column, val);
    }

    Children lt(boolean condition, R column, Object val);

    default Children le(R column, Object val) {
    
    
        return this.le(true, column, val);
    }

    Children le(boolean condition, R column, Object val);

    default Children between(R column, Object val1, Object val2) {
    
    
        return this.between(true, column, val1, val2);
    }

    Children between(boolean condition, R column, Object val1, Object val2);

    default Children notBetween(R column, Object val1, Object val2) {
    
    
        return this.notBetween(true, column, val1, val2);
    }

    Children notBetween(boolean condition, R column, Object val1, Object val2);

    default Children like(R column, Object val) {
    
    
        return this.like(true, column, val);
    }

    Children like(boolean condition, R column, Object val);

    default Children notLike(R column, Object val) {
    
    
        return this.notLike(true, column, val);
    }

    Children notLike(boolean condition, R column, Object val);

    default Children likeLeft(R column, Object val) {
    
    
        return this.likeLeft(true, column, val);
    }

    Children likeLeft(boolean condition, R column, Object val);

    default Children likeRight(R column, Object val) {
    
    
        return this.likeRight(true, column, val);
    }

    Children likeRight(boolean condition, R column, Object val);
}

Func interface source code

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.core.conditions.interfaces;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

public interface Func<Children, R> extends Serializable {
    
    
    default Children isNull(R column) {
    
    
        return this.isNull(true, column);
    }

    Children isNull(boolean condition, R column);

    default Children isNotNull(R column) {
    
    
        return this.isNotNull(true, column);
    }

    Children isNotNull(boolean condition, R column);

    default Children in(R column, Collection<?> coll) {
    
    
        return this.in(true, column, coll);
    }

    Children in(boolean condition, R column, Collection<?> coll);

    default Children in(R column, Object... values) {
    
    
        return this.in(true, column, values);
    }

    Children in(boolean condition, R column, Object... values);

    default Children notIn(R column, Collection<?> coll) {
    
    
        return this.notIn(true, column, coll);
    }

    Children notIn(boolean condition, R column, Collection<?> coll);

    default Children notIn(R column, Object... value) {
    
    
        return this.notIn(true, column, value);
    }

    Children notIn(boolean condition, R column, Object... values);

    default Children inSql(R column, String inValue) {
    
    
        return this.inSql(true, column, inValue);
    }

    Children inSql(boolean condition, R column, String inValue);

    Children gtSql(boolean condition, R column, String inValue);

    default Children gtSql(R column, String inValue) {
    
    
        return this.gtSql(true, column, inValue);
    }

    Children geSql(boolean condition, R column, String inValue);

    default Children geSql(R column, String inValue) {
    
    
        return this.geSql(true, column, inValue);
    }

    Children ltSql(boolean condition, R column, String inValue);

    default Children ltSql(R column, String inValue) {
    
    
        return this.ltSql(true, column, inValue);
    }

    Children leSql(boolean condition, R column, String inValue);

    default Children leSql(R column, String inValue) {
    
    
        return this.leSql(true, column, inValue);
    }

    default Children notInSql(R column, String inValue) {
    
    
        return this.notInSql(true, column, inValue);
    }

    Children notInSql(boolean condition, R column, String inValue);

    Children groupBy(boolean condition, R column);

    default Children groupBy(R column) {
    
    
        return this.groupBy(true, column);
    }

    Children groupBy(boolean condition, List<R> columns);

    default Children groupBy(List<R> columns) {
    
    
        return this.groupBy(true, columns);
    }

    /** @deprecated */
    @Deprecated
    default Children groupBy(R column, R... columns) {
    
    
        return this.groupBy(true, column, columns);
    }

    /** @deprecated */
    @Deprecated
    Children groupBy(boolean condition, R column, R... columns);

    default Children orderByAsc(boolean condition, R column) {
    
    
        return this.orderBy(condition, true, column);
    }

    default Children orderByAsc(R column) {
    
    
        return this.orderByAsc(true, column);
    }

    default Children orderByAsc(boolean condition, List<R> columns) {
    
    
        return this.orderBy(condition, true, columns);
    }

    default Children orderByAsc(List<R> columns) {
    
    
        return this.orderByAsc(true, columns);
    }

    /** @deprecated */
    @Deprecated
    default Children orderByAsc(R column, R... columns) {
    
    
        return this.orderByAsc(true, column, columns);
    }

    /** @deprecated */
    @Deprecated
    default Children orderByAsc(boolean condition, R column, R... columns) {
    
    
        return this.orderBy(condition, true, column, columns);
    }

    default Children orderByDesc(boolean condition, R column) {
    
    
        return this.orderBy(condition, false, column);
    }

    default Children orderByDesc(R column) {
    
    
        return this.orderByDesc(true, column);
    }

    default Children orderByDesc(boolean condition, List<R> columns) {
    
    
        return this.orderBy(condition, false, columns);
    }

    default Children orderByDesc(List<R> columns) {
    
    
        return this.orderByDesc(true, columns);
    }

    /** @deprecated */
    @Deprecated
    default Children orderByDesc(R column, R... columns) {
    
    
        return this.orderByDesc(true, column, columns);
    }

    /** @deprecated */
    @Deprecated
    default Children orderByDesc(boolean condition, R column, R... columns) {
    
    
        return this.orderBy(condition, false, column, columns);
    }

    Children orderBy(boolean condition, boolean isAsc, R column);

    Children orderBy(boolean condition, boolean isAsc, List<R> columns);

    /** @deprecated */
    @Deprecated
    Children orderBy(boolean condition, boolean isAsc, R column, R... columns);

    default Children having(String sqlHaving, Object... params) {
    
    
        return this.having(true, sqlHaving, params);
    }

    Children having(boolean condition, String sqlHaving, Object... params);

    default Children func(Consumer<Children> consumer) {
    
    
        return this.func(true, consumer);
    }

    Children func(boolean condition, Consumer<Children> consumer);
}

Join interface source code

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.core.conditions.interfaces;

import java.io.Serializable;

public interface Join<Children> extends Serializable {
    
    
    default Children or() {
    
    
        return this.or(true);
    }

    Children or(boolean condition);

    default Children apply(String applySql, Object... values) {
    
    
        return this.apply(true, applySql, values);
    }

    Children apply(boolean condition, String applySql, Object... values);

    default Children last(String lastSql) {
    
    
        return this.last(true, lastSql);
    }

    Children last(boolean condition, String lastSql);

    default Children comment(String comment) {
    
    
        return this.comment(true, comment);
    }

    Children comment(boolean condition, String comment);

    default Children first(String firstSql) {
    
    
        return this.first(true, firstSql);
    }

    Children first(boolean condition, String firstSql);

    default Children exists(String existsSql, Object... values) {
    
    
        return this.exists(true, existsSql, values);
    }

    Children exists(boolean condition, String existsSql, Object... values);

    default Children notExists(String existsSql, Object... values) {
    
    
        return this.notExists(true, existsSql, values);
    }

    Children notExists(boolean condition, String existsSql, Object... values);
}

Nested interface source code

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.core.conditions.interfaces;

import java.io.Serializable;
import java.util.function.Consumer;

public interface Nested<Param, Children> extends Serializable {
    
    
    default Children and(Consumer<Param> consumer) {
    
    
        return this.and(true, consumer);
    }

    Children and(boolean condition, Consumer<Param> consumer);

    default Children or(Consumer<Param> consumer) {
    
    
        return this.or(true, consumer);
    }

    Children or(boolean condition, Consumer<Param> consumer);

    default Children nested(Consumer<Param> consumer) {
    
    
        return this.nested(true, consumer);
    }

    Children nested(boolean condition, Consumer<Param> consumer);

    default Children not(Consumer<Param> consumer) {
    
    
        return this.not(true, consumer);
    }

    Children not(boolean condition, Consumer<Param> consumer);
}

Summary of common functions

Function name illustrate Example and corresponding sql
eq equal to= eq(“id”, 1)
immediately
id = 1
ne not equal to <> ne(“id”, 1)

id <> 1
gt greater than> gt(“id”, 1)

id > 1
ge greater than or equal to >= ge(“id”,1) 即 id >= 1
lt less than< lt(“id”,1)

id < 1
le less than or equal to <= le("id,1)

id <= 1
between BETWEEN value 1 AND value 2 between(“id”, 1, 3)

id BETWEEN 1 AND 3
notBetween NOT BETWEEN value 1 AND value 2 notBetween(“id”, 1, 3)

id NOT BETWEEN 1 AND 3
like LIKE '%value%' like("name", "small")
means
name LIKE '%small%'
notLike NOT LIKE '%value%' notLike("name", "small")
means
name NOT LIKE '%small%'
likeLeft LIKE '%value' likeLeft("name", "small")
means
name LIKE '%small'
likeRight LIKE 'value%' likeRight(“name”, "小”)

name LIKE ‘小%’
isNull 字段 IS NULL isNull(“name”)

name IS NULL
isNotNull 字段 IS NOT NULL isNotNull(“name”)

name IS NOT NULL
in 字段 IN (值1, 值2, … …) in(“id”, {1,2,3,4,5})

id IN (1,2,3,4,5)
notIn 字段 NOT IN (值1, 值2, … …) notIn(“id”, {1,2,3,4,5})

id NOT IN (1,2,3,4,5)
inSql 字段 IN (sql语句) inSql(“id”, “select id from tab_01 where id > 10”)

id IN (select id from tab_01 where id > 10)
notInSql 字段 NOT IN (sql语句) notInSql(“id”, “select id from tab_01 where id > 10”)

id NOT IN (select id from tab_01 where id > 10)
groupBy GROUP BY 字段1, 字段2, … … groupBy(“id”, “name”)

GROUP BY id, name
orderBy ORDER BY 字段1, 字段2, … … orderBy(true, false, “id”, “name”)

ORDER BY id ASC, name DESC
orderByAsc ORDER BY 字段1, 字段2, … … ASC orderByAsc(“id”, “name”)

ORDER BY id ASC, name ASC
orderByDesc ORDER BY 字段1, 字段2, … … DESC orderByDesc(“id”, “name”)

ORDER BY id DESC, name DESC
having HAVING(sql语句) having(“count(number) > {0}”, 20)

HAVING COUNT(number) > 20
or OR eq(“id”, 2).or().eq(“name”, “小红”)

id = 2 OR name = “小红”
and AND and(query -> query.eq(“id”, 2).ne(“name”, "小红”))

AND (id = 2 AND name <> “小红”
apply 拼接sql语句 apply("date_format(df, ‘%Y-%m-%d’) = {0}, “2023-04-25”)

date_format(df, ‘%Y-%m-%d’) = ‘2023-04-25’)
last 拼接sql到最后 last(“limit”, 10)

xxx limit 10
exists EXISTS (sql语句) exists("select id from tab_01 where name = “小红”)

EXISTS ("select id from tab_01 where name = “小红”)
notExists NOT EXISTS (sql语句) notExists("select id from tab_01 where name = “小红”)

NOT EXISTS ("select id from tab_01 where name = “小红”)
nested 不带AND或OR的嵌套 nested(query -> query.eq(“id”, 2).ne(“name”, "小红”))

(id = 2 AND name <> “小红”

MyBatis-Plus 代码实践

依赖

<dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

分页插件配置

@Configuration
public class MybatisPlusConfig {
    
    
    /**
     * mybatis-plus 拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //新增内置分页拦截器,并设置数据库类型为mysql
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

IDEA插件MyBatisPlus

  1. 【preferences】—>【Plugins】—>【Marketplace】
  2. 搜索并安装MyBatisPlus插件,可以通过该插件进行Mapper层与xml之间的映射跳转。
    在这里插入图片描述

类模板

entity类

@Data
@TableName("demo_entity")
@ApiModel(value = "demo表")
public class DemoEntity {
    
    

    /**
     * id
     */
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 名称
     */
    private String name;

    /**
     * 编码
     */
    private String code;
	
	/**
     * 是否删除
     */
    private Integer deleted;
}

mapper类

@Mapper
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
    
    
... ...
}

service接口类

public interface DemoEntityService extends IService<DemoEntity> {
    
    
... ...
}

service实现类

@Slf4j
@Service
public class DemoEntityServiceImpl extends ServiceImpl<DemoEntityMapper, DemoEntity> implements DemoEntityService{
    
    
	/**
 	* mapper
 	*/
	@Autowired
	private DemoEntityMapper demoEntityMapper;
	
	... ...
}

lambda表达式

LambdaQueryWrapper查询

... ...
Long id = 1000L;
List<Long> userId = new ArrayList<>();
userId.add(100000L);
userId.add(100001L);
LambdaQueryWrapper<DemoEntity> lambdaQueryWrapper = new LambdaQueryWrapper();
lambdaQueryWrapper.eq(DemoEntity::getId, id)
                    .in(DemoEntity::getUserId, userId);
List<DemoEntity> entityList = demoEntityMapper.selectList(lambdaQueryWrapper);
... ...

QueryWrapper查询

... ...
Long id = 1000L;
List<Long> userId = new ArrayList<>();
userId.add(100000L);
userId.add(100001L);
QueryWrapper<DemoEntity> queryWrapper = Wrappers.query();
queryWrapper.lambda()
	//and筛选  
	.and(wrapper -> wrapper.in(DemoEntity::getUserId, userId)
	//or条件
	.or()
	.eq(DemoEntity::getId, id);
... ...

lambdaUpdate更新

... ...
Long id = 1000L;
this.lambdaUpdate()
    .eq(DemoEntity::getId, id)
    .set(DemoEntity::getUserId, 10000002L)
    //更新
    .update();
... ...

Mapper结合xml文件查询

根据基本数据类型查询

mapper方法

@Mapper
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
    
    
... ...
	/**
 	* 根据id进行查询
 	* @param id
 	* @return
 	*/
	public DemoVO getById(int id);
... ...
}

DemoEntityMapper.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.ljy.demo.mapper.DemoEntityMapper">
	<select id="getById" parameterType="int" resultType="com.ljy.demo.vo.DemoVO">
        SELECT * FROM demo_entity WHERE id=#{
    
    id}
    </select>
</mapper>

根据多个参数查询

mapper方法

@Mapper
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
    
    
... ...
	/**
 	* 根据name和code进行查询
 	* @param name
 	* @param code
 	* @return
 	*/
	public List<DemoVO> getByNameOrCode(String name, String code);
... ...
}

DemoEntityMapper.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.ljy.demo.mapper.DemoEntityMapper">
	<select id="getByNameOrCode" resultType="com.ljy.demo.vo.DemoVO">
        SELECT * FROM demo_entity WHERE name=#{
    
    0} OR code=#{
    
    1}
    </select>
</mapper>

根据对象参数查询

mapper方法

@Mapper
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
    
    
... ...
	/**
 	* 根据dto的不同入参进行查询
 	* @param demoDTO
 	* @return
 	*/
	public List<DemoVO> listDemo(@Param("dto") DemoDTO demoDTO);
... ...
}

DemoEntityMapper.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.ljy.demo.mapper.DemoEntityMapper">

    <sql id="List_demo">
        select de.id,
               de.name,
               de.code
        from demo_entity de
    </sql>

    <select id="listDemo" resultType="com.ljy.demo.vo.DemoVO">
        <include refid="List_demo"/>

        <where>
            <if test="dto.id != null" >
            	 <!--id不为空,则精准查询-->
                and de.id = #{
    
    dto.id}
            </if>
            <if test="dto.name != null and dto.name != ''">
                <!--名称不为空,则模糊查询-->
                and de.name like concat('%',#{
    
    dto.name},'%')
            </if>
            <!--未删除-->
            and de.deleted = 0
        </where>
        group by de.id
        order by de.name desc
    </select>
</mapper>

分页查询

mapper方法

@Mapper
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
    
    
... ...
	/**
 	* 分页查询
 	* @param page
 	* @param demoDTO
 	* @return
 	*/
	IPage<DemoVO> pageListDemo(@Param("page") IPage<DemoVO> page, @Param("dto") DemoDTO demoDTO);
... ...
}

DemoEntityMapper.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.ljy.demo.mapper.DemoEntityMapper">

    <sql id="List_demo">
        select de.id,
               de.name,
               de.code
        from demo_entity de
    </sql>
	<!--名称保持一致-->
    <select id="pageListDemo" resultType="com.ljy.demo.vo.DemoVO">
        <include refid="List_demo"/>
        <where>
            <if test="dto.name != null and dto.name != ''">
                <!--名称不为空,则模糊查询-->
                and de.name like concat('%',#{
    
    dto.name},'%')
            </if>
            <!--未删除-->
            and de.deleted = 0
        </where>
        group by de.id
        order by de.name desc
    </select>
</mapper>

调用代码

...
//构造分页
Page<DemoVO> page = new Page<>(2, 10);
//page 查询
IPage<DemoVO> iPage = demoEntityMapper.pageListDemo(page, demoDTO);
...

Guess you like

Origin blog.csdn.net/Andya_net/article/details/130257724