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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 本篇文章具体对数据库框架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>
相关文章
|
4天前
|
SQL druid Java
Javaweb之数据库连接池以及lombok类库的详细解析
Javaweb之数据库连接池以及lombok类库的详细解析
19 0
|
4天前
|
SQL 存储 关系型数据库
数据库开发之图形化工具以及表操作的详细解析
数据库开发之图形化工具以及表操作的详细解析
21 0
|
24天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。
|
4天前
|
SQL 存储 关系型数据库
数据库开发之mysql前言以及详细解析
数据库开发之mysql前言以及详细解析
14 0
|
15天前
|
存储 中间件 关系型数据库
数据库切片大对决:ShardingSphere与Mycat技术解析
数据库切片大对决:ShardingSphere与Mycat技术解析
24 0
|
9天前
|
机器学习/深度学习 API TensorFlow
TensorFlow的高级API:tf.keras深度解析
【4月更文挑战第17天】本文深入解析了TensorFlow的高级API `tf.keras`,包括顺序模型和函数式API的模型构建,以及模型编译、训练、评估和预测的步骤。`tf.keras`结合了Keras的易用性和TensorFlow的性能,支持回调函数、模型保存与加载等高级特性,助力提升深度学习开发效率。
|
13天前
|
SQL API 数据库
Python中的SQLAlchemy框架:深度解析与实战应用
【4月更文挑战第13天】在Python的众多ORM(对象关系映射)框架中,SQLAlchemy以其功能强大、灵活性和易扩展性脱颖而出,成为许多开发者首选的数据库操作工具。本文将深入探讨SQLAlchemy的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
13天前
|
SQL Java 数据库连接
什么是MyBatis持久层框架?
MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs (Plain Old Java Objects, 普通的 Java 对象) 映射成数据库中的记录。
25 5
|
14天前
|
机器学习/深度学习 分布式计算 BI
Flink实时流处理框架原理与应用:面试经验与必备知识点解析
【4月更文挑战第9天】本文详尽探讨了Flink实时流处理框架的原理,包括运行时架构、数据流模型、状态管理和容错机制、资源调度与优化以及与外部系统的集成。此外,还介绍了Flink在实时数据管道、分析、数仓与BI、机器学习等领域的应用实践。同时,文章提供了面试经验与常见问题解析,如Flink与其他系统的对比、实际项目挑战及解决方案,并展望了Flink的未来发展趋势。附带Java DataStream API代码样例,为学习和面试准备提供了实用素材。
37 0
|
17天前
|
JavaScript API UED
Vue3.0新特性解析与实战:Composition API、Teleport与Suspense
【4月更文挑战第6天】Vue3.0引入了颠覆性的Composition API,通过函数式方法提升代码可读性和复用性,例如`setup()`、`ref`等,便于逻辑模块化。实战中,自定义的`useUser`函数可在多个组件中共享用户信息逻辑。另外,Teleport允许组件渲染到DOM特定位置,解决模态框等场景的上下文问题。再者,Suspense提供异步组件加载的延迟渲染,使用fallback内容改善用户体验。这些新特性显著优化了开发和性能,适应现代Web需求。
19 0

推荐镜像

更多