SpringBoot——Análisis del código fuente de MyBatis-Plus y explicación detallada de la práctica de desarrollo

enfoque wx:CodingTechWork

introducción

  Se ha utilizado en la empresa anterior Spring Data JPA. Es un soporte mejorado para la capa de acceso a datos basada en JPA. La capa inferior utiliza Hibernateel marco y admite el uso de SQL nativo o JPQLlenguaje de consulta. JPASe basa en la separación ORMdel código y el código, es decir, se agrega una nueva capa entre el código y la operación indirecta . Puede pensar que el costo de aprendizaje es relativamente alto, pero en realidad está bien y no hay archivos. necesario Sin embargo   , en la nueva empresa, utilizando el modelo orientado , puede ser más intuitivo y amigable operar operaciones complejas escribiendo archivos , y despegar in situ cuando se combinan . Este artículo resume principalmente algunas experiencias prácticas y análisis de código fuente.DBDBDBxml
MybatisMybatisDBSQLSQLmapperxmlDBMybatisMybatis-PlusMybatis-Plus

Introducción a MyBatis-Plus

descripción general

  MyBatis-PlusEs Mybatisuna herramienta mejorada que puede simplificar el desarrollo y mejorar nuestra eficiencia de desarrollo.

características

  1. No intrusivo: Sí Mybatisherramienta de mejora, sin cambios invasivos.
  2. Rich lambda call support: Lambdaescriba varias consultas a través de expresiones.
  3. MapperPotente soporte de operación CRUD: interfaz integrada IServicey varios métodos de operación.
  4. Complemento de paginación incorporado: basado en la paginación física de MyBatis, los desarrolladores no necesitan preocuparse por operaciones específicas.
    ...

Notas comunes

@Nombre de la tabla

Descripción: Anotación en el nombre de la tabla, identificando la clase de entidad.

@TableId

Descripción: anotación de clave principal

tipo de IdType

valor ilustrar
AUTO Incremento automático de ID de base de datos
NINGUNO De forma predeterminada, no hay estado, y este tipo es un tipo de clave principal no establecida (en la anotación, es igual a seguir el global, y el Rio global es igual a INPUT)
APORTE Establecer el valor de la clave principal antes de insertar
ASSIGN_ID Asignar ID (el tipo de clave principal es Número (largo y entero) o Cadena) (desde 3.3.0), use el método nextId de la interfaz IdentifierGenerator (la clase de implementación predeterminada es el algoritmo de copo de nieve DefaultIdentifierGenerator)
ASSIGN_UUID Asigne UUID, el tipo de clave principal es String (desde 3.3.0), use el método nextUUID de la interfaz IdentifierGenerator (método predeterminado predeterminado)
ID_TRABAJADOR Tipo de número entero largo de ID único distribuido globalmente (utilice ASSIGN_ID)
UUID Cadena UUID de 32 bits (utilice ASSIGN_UUID)
ID_TRABAJADOR_STR Tipo de cadena de ID única distribuida globalmente (utilice ASSIGN_ID)

@TableField


Descripción: atributos comunes de anotación de campo (clave no principal) :

Atributos El tipo debe especificar una descripción de valor predeterminado
valor Cadena No "" Nombre del campo de la base de datos
existir booleano No verdadero Si es un campo de tabla de base de datos

Análisis de código fuente MyBatis-Plus

Interfaz nativa de CURD de IService

ahorrar

// 插入一条记录(选择字段,策略插入)
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);

eliminar

// 根据 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);

actualizar

// 根据 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);

conseguir

// 根据 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);

lista

// 查询所有
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);

página

// 无条件分页查询
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);

Interfaz CURD nativa de Mapper

insertar

int insert(T entity);

borrar

    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);

actualizar

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

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

seleccionar

    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);

página

    <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);

paginación

principio

  1. El interceptor de paginación PaginationInnerInterceptorintercepta todas las solicitudes de consulta. beforeQueryAl consultar, primero determina si los parámetros contienen IPageparámetros de tipo.
  2. Si contiene IPageparámetros de tipo, la consulta de paginación se realizará de acuerdo con el valor del parámetro pasado; de lo contrario, no se realizará la paginación.

Código fuente de PaginationInnerInterceptor

Ubicación: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);
            }
        }
    }
}

Utilidades de parámetros

Ubicación: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);
        }
    }
}

función lambda

Comparar el código fuente de la interfaz

//
// 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);
}

Código fuente de la interfaz de funciones

//
// 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);
}

Unirse al código fuente de la interfaz

//
// 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);
}

Código fuente de la interfaz anidada

//
// 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);
}

Resumen de funciones comunes

Nombre de la función ilustrar Ejemplo y sql correspondiente
eq igual a = eq(“id”, 1)
inmediatamente
id = 1
ne no es igual a <> ne(“id”, 1)

id <> 1
gt mayor que> gt(“id”, 1)

id > 1
ge mayor o igual que >= ge(“id”,1) 即 id >= 1
lt menos que< lt(“id”,1)

id < 1
le menor o igual que <= le("id,1)

id <= 1
between ENTRE valor 1 Y valor 2 between(“id”, 1, 3)

id ENTRE 1 Y 3
notBetween NO ENTRE valor 1 Y valor 2 notBetween(“id”, 1, 3)

id NO ENTRE 1 Y 3
like COMO '%valor%' like("nombre", "pequeño")
significa
nombre LIKE '%pequeño%'
notLike NO COMO '%valor%' notLike("nombre", "pequeño")
significa
nombre NO COMO '%pequeño%'
likeLeft COMO '%valor' likeLeft("nombre", "pequeño")
significa
nombre COMO '%pequeño'
likeRight COMO 'valor%' 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);
...

Supongo que te gusta

Origin blog.csdn.net/Andya_net/article/details/130257724
Recomendado
Clasificación