数据库框架MyBatisPlus的使用解析!详细解析MyBatisPlus中API的使用方式

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
全局流量管理 GTM,标准版 1个月
简介: 本篇文章具体对数据库框架MyBatisPlus中的API的使用方式进行详细的说明解析,包括注解的使用,CRUD接口的使用和条件构造器的使用。通过实例对MyBatisPlus中API方法进行具体的使用说明,可以帮助你学会在项目中集成使用MyBatisPlus框架。

注解

@TableName
  • 表名注解:
属性 类型 是否必须 缺省值 描述
value String 表名
schema String schema
keepGlobalPrefix boolean false 是否保持使用全局的tablePrefix的值(要求设置tablePrefix并且自定义设置了value的值)
resultMap String xmlresultMapid
autoResultMap boolean false 是否自动构建resultMap并使用,如果设置了resultMap就不会进行resultMap的自动构建注入
  • autoResultMap:

    • autoResultMap会自动构建一个ResultMap并注入到MyBatis中,一般情况下不会用到
    • autoResultMap只是注入了常用的CRUDMyBatis中,注入之前是动态的:根据entity的字段以及注解的变化而变化. 但是注入之后是静态的,就相当于写在xml中了
    • 对于直接指定typeHandler,MyBatis只支持写在两个地方:

      • 定义在resultMap里,只作用于select查询的返回结果封装
      • 定义在insertupdatesql中的 #{property} 里的property后面

        • 比如: #{property.typehandler=xxx.xxx.xxx}
        • 只作用于设置值
    • 除了这两种直接指定typeHandler,MyBatis有一个全局扫描自定义的typeHandler包的配置,根据property的类型去找typeHandler
@TableId
  • 主键注解:
属性 类型 是否必须 缺省值 描述
value String 主键字段名
type Enum IdType.NONE 主键类型

IdType:

描述
AUTO 数据库ID自增
NONE 无状态,该类型为未设置主键类型:注解里等于跟随全局,全局里约等于INPUT
INPUT insert前自行set主键值
ASSIGN_ID 分配ID: 主键类型为Number(LongInteger)String
使用接口IdentifierGenerator的方法nextId: 默认实现类为DefaultIdentifierGenerator雪花算法SnowFlakeIdWorker
ASSIGN_UUID 分配UUID: 主键类型为String
使用接口IdentifierGenerator的方法nextUUID: 默认dafault方法
@TableField
  • 非主键字段注解:
属性 类型 是否必须 缺省值 描述
value String 字段名
el String 映射为原生 #{ } 逻辑,相当于xml里的 #{ } 部分
exist boolean true 是否为数据库表字段
condition String 字段where实体查询比较条件
如果有值设置则按设置的值为准,如果没有值则为默认全局的 %s = #{%s}
update String 字段update set部分注入
比如 : update = "%s + 1", 表示更新时会set version = version + 1. 该属性的优先级高于el
insertStrategy Enum DEFAULT NOT_NULL:
insert into table_a(< if test="columnProperty != null" >column< /if >) values (< if test="columnProperty != null">#{columnProperty}< /if >)
updateStrategy Enum DEFAULT IGNORED:
update table_a set column = #{columnProperty}
whereStrategy Enum DEFAULT NOT_EMPTY:
where < if test="columnProperty != null and columnProperty != ' ' ">column = #{columnProperty}< /if >
fill Enum FiledFill.DEFAULT 字段自动填充策略
select boolean true 是否进行select查询
keepGlobalFormat boolean false 是否保持全局的format进行处理
jdbcType JdbcType JdbcType.UNDEFINED JDBC类型,该默认值不代表会按照该值生效
typeHandler Class<? extends TypeHandler> UnknownTypeHandler.class 类型处理器,该默认值不代表会按照该值生效
numericScale String 指定小数点后保留的位数
  • numbericScale只生效于updatesql
  • jdbcTypetypeHandler如果不配合 @TableName#autoResultMap = true一起使用,也只生效于updatesql
  • typeHandler中,如果字段类型和set进去的类型为equals关系,则只需要让自定义的typeHandlerMyBatis加载到即可,不需要使用注解
  • FieldStrategy:
描述
IGNORED 忽略判断
NOT_NULL NULL判断
NOT_EMPTY 非空判断:只针对于字符串类型
其它类型字段依然为非NULL判断
DEFAULT 追随全局配置
  • FieldFill:
描述
DEFAULT 默认不处理
INSERT 插入时填充字段
UPDATE 更新时填充字段
INSERT_UPDATE 插入和更新时填充字段
@Version
  • 乐观锁注解,标记@Version在字段上
@EnumValue
  • 通枚举类注解,注解在枚举字段上
@TableLogic
  • 表字段逻辑处理(逻辑删除)注解
属性 类型 是否必须 默认值 描述
value String 逻辑未删除值
delval String 逻辑删除值
@SqpParser
  • 租户注解,支持method和mapper接口
属性 类型 是否必须 默认值 描述
filter boolean false true: 表示过滤SQL解析,即不会进入SqlParser解析链
false: 进解析链并追加例如tenant_id等条件
@KeySequence
  • 序列主键策略
属性 类型 是否必须 默认值 描述
value String 序列名
clazz Class Long.class ID的类型
可以指定String.class, 这样返回的Sequence值是字符串1

CRUD接口

Service CRUD

  • 通用Service CRUD封装IService接口,进一步封装CRUD
  • 采用前缀命名方式区分Mapper层来避免混淆:

    • get: 查询单行
    • remove: 删除
    • list: 查询集合
    • page: 分页
  • 泛型T为任意实体对象
  • 如果存在自定义通用Service方法,需要创建自定义的IBaseService继承Mybatis-Plus提供的基类
  • 对象Wrapper为条件构造器
save
/**
 * 插入一条记录(选择字段,策略插入)
 * 
 * @param entity 实体对象 T 
 * @return 是否插入成功
 */
boolean save(T entity);
saveBatch
/**
 * 批量插入记录
 * 
 * @param entityList 实体对象集合 Collection<T> 
 * @return 是否插入成功
 */
boolean saveBatch(Collection<T> entityList);

/**
 * 批量插入记录
 * 
 * @param entityList 实体对象集合 Collection<T>
 * @param batchSize 插入批次数量 int
 * @return 是否插入成功
 */
boolean saveBatch(Collection<T> entityList, int batchSize);
saveOrUpdate
/**
 * 如果TableId存在就更新记录,否则就插入一条记录
 * 
 * @param entity 实体对象 T 
 * @return 是否插入成功
 */
boolean saveOrUpdate(T entity);

/**
 * 根据updateWrapper尝试更新,否则执行saveOrUpdate(T)方法
 * 
 * @param entity 实体对象 T
 * @param updateWrapper 实体对象封装操作类 UpdateWrapper
 * @return 是否插入成功
 */
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
saveOrUpdateBatch
/**
 * 批量修改插入
 * 
 * @param entryList 实体对象集合 Collection<T>
 * @return 是否插入成功
 */
boolean saveOrUpdate(Collection<T> entryList);

/**
 * 批量修改插入
 * 
 * @param entryList 实体对象集合 Collection<T>
 * @param batchSize 插入批次数量 int
 * @return 是否插入成功
 */
boolean saveOrUpdate(Collection<T> entryList, int batchSize);
remove
/**
 * 根据entity条件,删除记录
 * 
 * @param queryWrapper 实体包装类 QueryWrapper
 * @return 是否删除成功
 */
boolean remove(Wrapper<T> queryWrapper);
removeById
/**
 * 根据ID删除记录
 * 
 * @param id 主键ID Serializable
 * @return 是否删除成功
 */
boolean removeById(Serializable id);
removeByMap
/**
 * 根据columnMap条件删除记录
 * 
 * @param columnMap 表字段map对象 Map<String, Object>
 * @return 是否删除成功
 */
boolean removeById(Serializable id);
removeByIds
/**
 * 根据ID批量删除记录
 * 
 * @param idList 主键ID列表 Collection<? extends Serializeable>
 * @return 是否删除成功
 */
boolean removeByIds(Collection<? extends Serializeable> idList);
update
/**
 * 根据updateWrapper条件更新记录,需要设置sqlset
 * 
 * @param updateWrapper 实体对象封装操作类 UpdateWrapper
 * @return 是否更新成功
 */
boolean update(Wrapper<T> updateWrapper);

/**
 * 根据whereEntity条件更新记录
 * 
 * @param entity 实体对象 T
 * @param updateWrapper 实体对象封装操作类 UpdateWrapper
 * @return 是否更新成功
 */
boolean update(T entity, Wrapper<T> updateWrapper);
updateById
/**
 * 根据ID选择修改
 * 
 * @param entity 实体对象 T
 * @return 是否更新成功
 */
boolean updateById(T entity);
updateBatchById
/**
 * 根据ID批量更新
 * 
 * @param entityList 实体对象集合 Collection<T>
 * @return 是否更新成功
 */
boolean updateBatchById(Collection<T> entityList);

/**
 * 根据ID批量更新
 * 
 * @param entityList 实体对象集合 Collection<T>
 * @param batchSize 更新批次数量
 * @return 是否更新成功
 */
boolean updateBatchById(Collection<T> entityList, int batchSize);
getById
/**
 * 根据ID查询
 * 
 * @param id 主键ID Serializable
 * @return 实体对象 T
 */
T getById(Serializable id);
getOne
/**
 * 根据Wrapper查询一条记录
 * 结果集如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @return 实体对象 T
 */
T getOne(Wrapper<T> queryWrapper);

/**
 * 根据Wrapper查询一条记录
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @param throwEx 有多个result是否抛出异常
 * @return 实体对象 T
 */
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
getMap
/**
 * 根据Wrapper查询一条记录
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @return 实体对象Map Map<String, Object>
 */
Map<String, Object> getMap(Wrapper<T> queryWrapper);
getObj
/**
 * 根据Wrapper查询一条记录
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @param mapper 转换函数
 * @return 实体对象Map Map<String, Object>
 */
<V> V getMap(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
list
/**
 * 查询所有
 * 
 * @return 实体对象集合 List<T>
 */
List<T> list();

/**
 * 查询所有列表
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @return 实体对象集合 List<T>
 */
List<T> list(Wrapper<T> queryWrapper);
listByIds
/**
 * 根据Ids批量查询
 * 
 * @param idList 主键ID列表
 * @return 实体对象集合 List<T>
 */
Collection<T> listByIds(Collection<? extends Serializable> idList);
listByMap
/**
 * 根据columnMap条件查询
 * 
 * @param columnMap 表字段map对象
 * @return 实体对象集合 List<T>
 */
Collection<T> listByMap(Map<String, Object> columnMap);
listMaps
/**
 * 查询所有列表
 * 
 * @return 实体对象Map集合 List<Map<String, Object>>
 */
List<Map<String, Object>> listMaps();

/**
 * 查询列表
 * 
 * @param queryWrapper 实体对象封装操作类 QueryWrapper
 * @return 实体对象Map集合 List<Map<String, Object>>
 */
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
listObjs
/**
 * 查询全部记录
 * 
 * @return 实体对象集合 List<Object>
 */
List<Object> listObjs();

/**
 * 查询全部记录
 * 
 * @param mapper 转换函数
 * @return 实体对象集合 <V> List<V>
 */
<V> List<V> listObjs(Function<? super Object, V> mapper);

/**
 * 根据Wrapper条件,查询全部记录
 * 
 * @param queryWrapper 实体对象封装操作类
 * @return 实体对象集合 List<Object>
 */
List<Object> listObjs(Wrapper<T> queryWrapper);

/**
 * 根据Wrapper条件,查询全部记录
 * 
 * @param queryWrapper 实体对象封装操作类
 * @param mapper 转换函数
 * @return 实体对象集合 <V> List<V>
 */
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
page
/**
 * 分页查询所有记录
 * 
 * @param page 分页查询条件 IPage<T>
 * @return 分页对象集合 IPage<T>
 */
IPage<T> page(IPage<T> page);

/**
 * 根据Wrapper条件,分页查询
 * 
 * @param page 分页查询条件 IPage<T> 
 * @param queryWrapper 实体对象封装操作类
 * @return 分页对象集合 IPage<T>
 */
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
pageMaps
/**
 * 分页查询所有记录
 * 
 * @param page 分页查询条件 IPage<T>
 * @return 分页对象Map集合 IPage<Map<String, Object>>
 */
IPage<Map<String, Object>> pageMaps(IPage<T> page);

/**
 * 根据Wrapper条件,分页查询
 * 
 * @param page 分页查询条件 IPage<T>
 * @param queryWrapper 实体对象封装操作类
 * @return 分页对象Map集合 IPage<Map<String, Object>>
 */
IPage<Map<String, Object>> page(IPage<T> page, Wrapper<T> queryWrapper);
count
/**
 * 查询总记录数
 * 
 * @return 总记录的数目 int
 */
int count();

/**
 * 根据Wrapper条件,查询总记录数目
 * 
 * @param queryWrapper 实体对象封装操作类
 * @return 记录数目 int
 */
int count(Wrapper<T> queryWrapper);

Chain 链式

query
/**
 * 普通链式查询 
 * 
 * @return 链式查询条件构造器 QueryChainWrapper<T>
 */
QueryChainWrapper<T> query();

/**
 * Lambda式链式查询,不支持Kotlin
 * 
 * @return Lambda式链式查询条件构造器
 */
LambdaQueryChainWrapper<T> lambdaQuery();


/*
 * 示例
 */
 query().eq("column", value).one();
 lambdaQuery().eq(Entity :: getId, value).list();
update
/**
 * 普通链式更改
 * 
 * @return 链式更改条件构造器  UpdateChainWrapper<T>
 */
 UpdateChainWrapper<T> update();

/**
 * Lambda式链式更改,不支持Kotlin
 * 
 * @return Lambda式链式更改条件构造器 LambdaUpdateChainWrapper<T>
 */
 LambdaUpdateChainWrapper<T> lambdaUpdate();

/*
 * 示例
 */
 update().eq("column", value).remove();
 lambdaUpdate().eq(Entity :: getId, value).update(entity)

Mapper CRUD

  • 通用CRUD封装BaseMapper接口,在MyBatis-Plus启动时自动解析实体表关系映射转换为MyBatis内部对象注入容器
  • 泛型T为任意实体对象
  • 参数Serializable为任意类型主键 ,MyBatis-Plus不推荐使用复合主键约定. 每一张表都有自己的唯一ID主键
  • 对象Wrapper为条件构造器
insert
/**
 * 插入一条记录
 * 
 * @param entity 实体对象 T
 * @return 是否插入成功 int
 */ 
int insert(T entity);
delete
/**
 * 根据entity条件,删除记录
 * 
 * @param wrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 是否删除成功 int
 */ 
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
deleteBatchIds
/**
 * 根据IDs批量删除记录
 * 
 * @param idList 主键ID列表,不能为null以及不能为空 Collection<? extends Serializable>
 * @return 是否批量删除成功 int
 */ 
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
deleteById
/**
 * 根据ID删除记录
 * 
 * @param id 主键ID Serializable 
 * @return 是否删除成功 int
 */ 
int deleteById(Serializable id);
deleteByMap
/**
 * 根据columMap条件删除记录
 * 
 * @param cloumnMap 表字段Map对象 Map<String, Object> 
 * @return 是否删除成功 int
 */ 
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> cloumnMap);
update
/**
 * 根据whereEntity条件更新记录
 * 
 * @param entity 实体对象,set条件值,可以为null T
 * @param updateWrapper 实体对象封装操作类,可以为null,里面的entity用于生成where语句 Wrapper<T>
 * @return 是否更新成功 int
 */ 
int update(@Param(Constant.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
updateById
/**
 * 根据ID更新记录
 * 
 * @param entity 实体对象,set条件值,可以为null T
 * @return 是否更新成功 int
 */
int updateById(@Param(Constants.ENTITY) T entity);
selectById
/**
 * 根据ID查询
 *
 * @param id 主键ID Serializable 
 * @return 实体对象 T
 */
T selectById(Serializable id);
selectOne
/**
 * 根据entity条件,查询一条记录
 *
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T> 
 * @return 实体对象 T
 */
T selectOne(@Param(Constants.Wrapper) Wrapper<T> queryWrapper);
selectBatchIds
/**
 * 根据IDs批量查询记录
 *
 * @param idList 主键ID列表,不能为null以及不能为空 Collection<? extends Serializable> 
 * @return 实体对象集合 List<T>
 */
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
selectList
/**
 * 根据entity条件,查询全部记录
 *
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 实体对象集合 List<T>
 */
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
selectByMap
/**
 * 根据cloumnMap条件,查询全部记录
 *
 * @param columnMap 表字段map对象 Map<String, Object>
 * @return 实体对象集合 List<T> 
 */
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
selectMaps
/**
 * 根据Wrapper条件,查询全部记录
 *
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 实体对象Map集合 List<Map<String, Object>> 
 */
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
selectObjs
/**
 * 根据Wrapper条件,查询全部记录,只返回第一个字段的值
 *
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 实体对象集合 List<Object> 
 */
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
selectPage
/**
 * 根据Wrapper条件,查询全部记录并分页
 *
 * @param page 分页查询条件 IPage<T>
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 分页对象集合 Ipage<T>
 */
Ipage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
selectMapsPage
/**
 * 根据Wrapper条件,查询全部记录并分页
 *
 * @param page 分页查询条件 IPage<T>
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 分页对象Map集合 Ipage<Map<String, Object>>
 */
Ipage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
selectCount
/**
 * 根据Wrapper条件,查询记录数目
 * 
 * @param queryWrapper 实体对象封装操作类,可以为null Wrapper<T>
 * @return 记录数目 Integer
 */
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Mapper 选装件

  • 选装件位于com.baomidou.mybatisplus.extension.injector.methods.addtional包下,需要配合SQL注入器使用
alwaysUpdateSomeColumnById
/**
 * 根据ID更新列表字段
 *  
 * @param entity 实体对象,set条件值,可以为null T
 * @return 是否更新成功 int
 */
 int alwaysUpdateSomeColumnById(T entity);
insertBatchSomeColumn
/**
 * 批量数据插入列表
 *  
 * @param entryList 实体对象集合 List<T>
 * @return 是否批量插入成功 int
 */
 int insertBatchSomeColumn(List<T> entryList);
deleteByIdWithFill
/**
 * 根据Id删除数据
 *  
 * @param entity 实体对象,set条件值,可以为null T
 * @return 是否删除成功 int
 */
 int deleteByIdWithFill(T entity);

条件构造器

  • 出现的第一个入参boolean condition表示该条件是否加入最后生成的SQL
  • 代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 泛型Param均为Wrapper子类的实例,均具有AbstractWrapper的所有方法
  • 方法入参中出现的R为泛型,在普通Wrapper中是String,LambdaWrapper中是函数. 比如 - Entity::getId, 其中Entity为实体类 ,getId为字段idgetMethod
  • 方法入参中出现的R column表示数据库字段,当R具体类型为String时则为数据库字段名而不是实体类字段名, 如果字段名是数据库关键字的需要用转义符包裹
  • 普通Wrapper中入参为MapList的均以json形式表现
  • 使用中如果入参的Map或者List为空,则不会加入最后生成的SQL
  • 注意:

    • 不要在RPC调用中使用Wrapper进行传输:

      • Wrapper很重
      • 传输Wrapper可以类比为controller中使用map接收值
      • 正确的RPC调用时是写一个DTO进行传输,被调用方再根据DTO执行相应的操作

AbstractWrapper

  • QueryWrapper(LambdaQueryWrapper)UpdateWrapper(LambdaUpdateWrapper) 的父类

    • 用于生成SQLwhere条件
    • entity属性也用于生成SQLwhere条件
allEq
allEq(Map<R, V> params);

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

allEq(boolean condition, Map<R, V> params, boolean null2IsNull);
  • 全部eq或者个别isNull :

    • params:

      • key为数据库字段名
      • value为字段值
    • null2IsNull:

      • 如果为true则在mapvaluenull时调用isNull方法
      • 如果为false则忽略valuenull
  1. allEq({id:1,name:"wang",age:null}) --> id = 1 and name = 'wang' and age is null
  2. allEq({id:1,name:'"wang",age:null}, false) --> id = 1 and name = 'wang'
allEq(BiPredicate<R, V> filter, Map<R, V> params);
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull);
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNUll);
  • filter:

    • 过滤函数,是否允许字段传入比对条件
  • params:

    • key为数据库字段名
    • value为字段值
  • null2IsNull:

    • 如果为true则在mapvaluenull时调用isNull方法
    • 如果为false则忽略valuenull
  1. allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"wang",age:null}) --> name = 'wang' and age is null
  2. allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"wang",age:null}, false) --> name = 'wang'
eq
eq(R column, Object val);
eq(boolean condition, R column, Object val);
  • 等于 = :
eq("name", "wang") --> name = 'wang'
ne
ne(R column, Object val);
ne(boolean condition, R column, Object val);
  • 不等于 <> :
ne("name", "wang") --> name <> 'wang'
gt
gt(R column, Object val);
gt(boolean condition, R column, Object val);
  • 大于 > :
gt("age", 18) --> age > 18
ge
ge(R column, Object val)
ge(boolean condition, R column, Object val)
  • 大于等于 >= :
ge("age", 18) --> age >= 18
lt
lt(R column, Object val);
lt(boolean condition, R column, Object val);
  • 小于 < :
lt("age", 18) --> age < 18
le
le(R column, Object val);
le(boolean condition, R column, Object val);
  • 小于等于 <= :
le("age", 18) --> age <= 18
between
between(R column, Object val1, Object val2);
between(boolean condition, R column, Object val1, Object val2);
  • between 值1 and 值2 :
between("age", 18, 30) --> age between 18 and 30
notBetween
notBetween(R column, Object val1, Object val2);
notBetween(boolean condition, R column, Object val1, Object val2);
  • not between 值1 and 值2
notBetween("age", 18, 30) --> age not between 18 and 30
like
like(R column, Object val);
like(boolean condition, R column, Object val);
  • like '%值%' :
like("name", "wang") --> name like '%wang%'
notLike
notLike(R column, Object val);
notLike(boolean condition, R column, Object val);
  • not like '%值%' :
notLike("name", "wang") --> name not like '%wang%'
likeLeft
likeLeft(R column, Obeject val);
likeLeft(boolean condition, R column, Object val);
  • like '%值' :
likeLeft("name", "wang") --> name like '%wang'
likeRight
likeRight(R column, Object val);
likeRight(boolean condition, R column, Object val);
  • like '值%' :
likeRight("name", "wang") --> name like 'wang%'
isNull
isNull(R column);
isNull(boolean condition, R column);
  • 字段 is null :
isNull("name") --> name is null
isNotNull
isNotNull(R column);
isNotNull(boolean condition, R column);
  • 字段 is not null :
isNotNull("name") --> name is not null
in
in(R column, Collection<?> value);
in(booelan condition, R column, Collection<?> value);
  • 字段 in (value.get(0), value.get(1) ...) :
in("age", {1, 2, 3}) --> age in (1, 2, 3)
in(R column, Object... values);
in(booelan condition, R column, Object... values);
  • 字段 in (v0, v1 ...) :
in("age", 1, 2, 3) --> age in (1, 2, 3)
notIn
notIn(R column, Collection<?> value);
notIn(booelan condition, R column, Collection<?> value);
  • 字段 not in (value.get(0), value.get(1) ...) :
notIn("age", {1, 2, 3}) --> age not in (1, 2, 3)
notIn(R column, Object... values);
notIn(boolean condition, R column, Object... values);
  • 字段 not in (v0, v1 ...) :
notIn("age", 1, 2, 3) --> age not in (1, 2, 3)
inSql
inSql(R column, String inValue);
inSql(boolean condition, R column, String inValue);
  • 字段 in (sql) :
inSql("age", "1, 2, 3, 4, 5, 6") --> age in (1, 2, 3, 4, 5, 6)
inSql("id", "select id from table where id < 3") --> id in (select id from table where id < 3)
notInSql
notInSql(R column, String inValue);
notInSql(boolean condition, R column, String inValue);
  • 字段 not in (sql) :
  1. notInSql("age", "1, 2, 3, 4, 5, 6") --> age not in (1, 2, 3, 4, 5, 6)
  2. notInSql("id", "select id from table where id < 3") --> age not in (select id from table where id < 3)
groupBy
groupBy(R... columns);
groupBy(boolean condition, R... columns);
  • group by 字段 ... :
groupBy("id", "name") --> group by id,name
orderByAsc
orderByAsc(R... columns);
orderByAsc(boolean condition, R... columns);
  • order by 字段 ... asc :
orderByAsc("id", "name") --> order by id,name asc
oederByDesc
orderByDesc(R... columns);
orderByDesc(boolean condition, R... columns);
  • order by 字段 ... desc :
orderByDesc("id", "name") --> order by id,name desc
orderBy
orderBy(boolean condition, boolean isAsc, R... columns);
  • order by 字段 ... :
orderBy(true, true, "id", "name") --> order by id,name asc
having
having(String sqlHaving, Object... params);
having(boolean condition, String sqlHaving, Object... params);
  • having (sql) :
  1. having("sum(age) > 10") --> having sum(age) > 10
  2. having("sum(age) > {0}", 10) --> having sum(age) > 10
or
or();
or(boolean condition);
  • 拼接 or :
  • 注意事项:

    • 主动调用or表示紧接着下一个方法不是用and连接
    • 不调用or则默认使用and连接
eq("id", 1).or().eq("name", "wang") --> id = 1 or name = 'wang'
or(Consumer<Param> consumer);
or(boolean condition, Consumer<Param> consumer);
  • 嵌套 or :
or(i -> i.eq("name", "li").ne("status", "live")) --> or(name = 'li' and status <> 'live')
and
and(Consumer<Param> consumer);
and(boolean condition, Consumer<Param> consumer);
  • 嵌套 and
and(i -> i.eq('name', 'li').ne('status', 'live')) --> and(name = 'li' and status <> 'live')
nested
nested(Consumer<Param> consumer);
nested(boolean condition, Consumer<Param> consumer);
  • 正常嵌套 不带 and 或者 or :
nested(i -> i.eq("name", "li").ne("status", "live")) --> (name = 'li' and status <> 'live')
apply
apply(String applySql, Object... params);
apply(boolean condition, String applySql, Object... params);
  • 拼接 sql :

    • 该方法可用于数据库函数
    • 动态入参的params对应前面applySql内部的 {index} 部分
    • 这样是不会有sql注入风险的,反之会有
  1. apply("id = 1") --> id = 1
  2. apply("date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'") --> date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'
  3. apply("date_format(dateColumn, '%Y-%m-%d') = {0}", "2008-08-08") --> date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'
last
last(String lastSql);
last(boolean condition, String lastSql);
  • 无视优化规则直接拼接到sql的最后
  • 只能调用一次,多次调用以最后一次为准
  • 有sql注入的风险,不推荐使用
last("limit 1") --> limit 1
exists
exists(String existsSql);
exists(boolean condition, String existsSql);
  • 拼接 exists(sql) :
exists("select id from table where age = 1") --> exists(select id from table where age = 1)
notExists
notExists(String notExistsSql);
notExists(boolean condition, String notExistsSql);
  • 拼接 not exists(sql) :
notExists("select id from table where age = 1") --> not exists (select id from table where age = 1)

QueryWrapper

  • 继承自AbstractWrapper, 自身的内部属性entity也是用于生成where条件
  • 其中的LambdaQueryWrapper, 可以通过new QueryWrapper().lambda() 方法获取
select
select(String... sqlSelect);
select(Predicate<TableFieldInfo> predicate);
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate);
  • select方法分为两类:

    • 第二类方法:

      • 过滤查询字段,主键除外
      • 入参不包括class的调用前需要wrapper内的entity属性有值
    • 这两类方法重复调用以最后一次为准
  1. select("id", "name", "age")
  2. select(i -> i.getProperty().startsWith("test"))

UpdateWrapper

  • 继承自AbstractWrapper, 自身的内部属性entity也是用于生成where条件
  • 其中的LambdaUpdateWrapper, 可以通过new updateWrapper().lambda() 方法调用
set
set(String column, Object val);
set(boolean condition, String column, Object val);
  • SQL set 字段 :
set("name", ''li")
set("name", "") --> 数据库字段值变为空字符串
set("name", null) --> 数据库字段值变为 null
setSql
setSql(String sql);
set("name = 'li'")

lambda

  • 获取LambdaWrapper:

    • QueryWrapper中是获取LambdaQueryWrapper
    • UpdateWrapper中是获取LambdaUpdateWrapper

使用Wrapper自定义SQL

Service.java
mysqlMapper.getAll(Wrappers.<MysqlData>.lambdaQuery().eq(MysqlData :: getGroup, 1));
注解方式-Mapper.java
@Select("select * from mysql_data ${ew.customSqlSegment}")
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
XML形式-Mapper.xml
<select id="getAll" resultType="MysqlData">
    SELECT * FROM mysql_data ${ew.customSqlSegment}
</select>
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
15 2
|
19天前
|
数据库 索引
深入探索数据库索引技术:回表与索引下推解析
【10月更文挑战第15天】在数据库查询优化的领域中,回表和索引下推是两个核心概念,它们对于提高查询性能至关重要。本文将详细解释这两个术语,并探讨它们在数据库操作中的作用和影响。
42 3
|
18天前
|
存储 负载均衡 监控
数据库多实例的深入解析
【10月更文挑战第24天】数据库多实例是一种重要的数据库架构方式,它为数据库的高效运行和灵活管理提供了多种优势。在实际应用中,需要根据具体的业务需求和技术环境,合理选择和配置多实例,以充分发挥其优势,提高数据库系统的性能和可靠性。随着技术的不断发展和进步,数据库多实例技术也将不断完善和创新,为数据库管理带来更多的可能性和便利。
88 57
|
11天前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
29 1
持久层框架MyBatisPlus
|
6天前
|
存储 SQL API
探索后端开发:构建高效API与数据库交互
【10月更文挑战第36天】在数字化时代,后端开发是连接用户界面和数据存储的桥梁。本文深入探讨如何设计高效的API以及如何实现API与数据库之间的无缝交互,确保数据的一致性和高性能。我们将从基础概念出发,逐步深入到实战技巧,为读者提供一个清晰的后端开发路线图。
|
4天前
|
API 数据安全/隐私保护
抖音视频,图集无水印直链解析免费API接口教程
该接口用于解析抖音视频和图集的无水印直链地址。请求地址为 `https://cn.apihz.cn/api/fun/douyin.php`,支持POST或GET请求。请求参数包括用户ID、用户KEY和视频或图集地址。返回参数包括状态码、信息提示、作者昵称、标题、视频地址、封面、图集和类型。示例请求和返回数据详见文档。
|
7天前
|
API PHP 数据库
PHP中哪个框架最适合做API?
在数字化时代,API作为软件应用间通信的桥梁至关重要。本文探讨了PHP中适合API开发的主流框架,包括Laravel、Symfony、Lumen、Slim、Yii和Phalcon,分析了它们的特点和优势,帮助开发者选择合适的框架,提高开发效率、保证接口稳定性和安全性。
24 3
|
14天前
|
JavaScript 中间件 API
Node.js进阶:Koa框架下的RESTful API设计与实现
【10月更文挑战第28天】本文介绍了如何在Koa框架下设计与实现RESTful API。首先概述了Koa框架的特点,接着讲解了RESTful API的设计原则,包括无状态和统一接口。最后,通过一个简单的博客系统示例,详细展示了如何使用Koa和koa-router实现常见的CRUD操作,包括获取、创建、更新和删除文章。
35 4
|
7天前
|
安全 API 网络架构
Python中哪个框架最适合做API?
本文介绍了Python生态系统中几个流行的API框架,包括Flask、FastAPI、Django Rest Framework(DRF)、Falcon和Tornado。每个框架都有其独特的优势和适用场景。Flask轻量灵活,适合小型项目;FastAPI高性能且自动生成文档,适合需要高吞吐量的API;DRF功能强大,适合复杂应用;Falcon高性能低延迟,适合快速API开发;Tornado异步非阻塞,适合高并发场景。文章通过示例代码和优缺点分析,帮助开发者根据项目需求选择合适的框架。
23 0
|
17天前
|
JSON 前端开发 JavaScript
API接口商品详情接口数据解析
商品详情接口通常用于提供特定商品的详细信息,这些信息比商品列表接口中的信息更加详细和全面。以下是一个示例的JSON数据格式,用于表示一个商品详情API接口的响应。这个示例假定API返回一个包含商品详细信息的对象。

推荐镜像

更多