✨mybatis-plus 是现在我们经常使用的插件,极大的提高了我们开发的效率。这篇文章就总结一下,mybatis-plus 的基础操作。
# 常用注解
# @TableName
这个注解用在类上,声明当前类关联的表名称,可以配置下列属性:
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|
value | String | 否 | "" | 表名 |
schema | String | 否 | "" | schema |
keepGlobalPrefix | boolean | 否 | false | 是否保持使用全局的 tablePrefix 的值 (如果设置了全局 tablePrefix 且自行设置了 value 的值) |
resultMap | String | 否 | "" | xml 中 resultMap 的 id |
autoResultMap | boolean | 否 | false | 是否自动构建 resultMap 并使用 (如果设置 resultMap 则不会进行 resultMap 的自动构建并注入) |
# @TableId
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 主键类型,通过 IdType 枚举指定 |
值 | 描述 |
---|
AUTO | 数据库 ID 自增 |
NONE | 无状态,该类型为未设置主键类型 (注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID (主键类型为 Number (Long 和 Integer) 或 String)(since 3.3.0), 使用接口 IdentifierGenerator 的方法 nextId (默认实现类为 DefaultIdentifierGenerator 雪花算法) |
ASSIGN_UUID | 分配 UUID, 主键类型为 String (since 3.3.0), 使用接口 IdentifierGenerator 的方法 nextUUID (默认 default 方法) |
# @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 | N | DEFAULT | 举例:NOT_NULL: insert into table_a(column) values (#{columnProperty}) |
updateStrategy | Enum | N | DEFAULT | 举例:IGNORED: update table_a set column=#{columnProperty} |
whereStrategy | Enum | N | DEFAULT | 举例:NOT_EMPTY: where column=#{columnProperty} |
fill | Enum | 否 | FieldFill.DEFAULT | 字段自动填充策略 |
select | boolean | 否 | true | 是否进行 select 查询 |
keepGlobalFormat | boolean | 否 | false | 是否保持使用全局的 format 进行处理 |
jdbcType | JdbcType | 否 | JdbcType.UNDEFINED | JDBC 类型 (该默认值不代表会按照该值生效) |
typeHandler | Class<? extends TypeHandler> | 否 | UnknownTypeHandler.class | 类型处理器 (该默认值不代表会按照该值生效) |
numericScale | String | 否 | "" | 指定小数点后保留的位数 |
# BaseMapper 的 CRUD
在 MybatisPlus 中,BaseMapper 中定义了一些常用的 CRUD 方法,当我们自定义的 Mapper 接口继承 BaseMapper 后即可拥有了这些方法。
# 新增
# 参数说明
# 删除
# 方法:
| |
| int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); |
| |
| int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); |
| |
| int deleteById(Serializable id); |
| |
| int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); |
# #参数说明
类型 | 参数名 | 描述 |
---|
Wrapper | wrapper | 实体对象封装操作类(可以为 null) |
Collection<? extends Serializable> | idList | 主键 ID 列表 (不能为 null 以及 empty) |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
# 修改
# 方法:
| |
| int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); |
| |
| int updateById(@Param(Constants.ENTITY) T entity); |
# 参数:
类型 | 参数名 | 描述 |
---|
T | entity | 实体对象 (set 条件值,可为 null) |
Wrapper | updateWrapper | 实体对象封装操作类(可以为 null, 里面的 entity 用于生成 where 语句) |
# 查询单个
# 方法列表:
| |
| T selectById(Serializable id); |
| |
| T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Serializable | id | 主键 ID |
Wrapper | queryWrapper | 实体对象封装操作类(可以为 null) |
# 查询集合
# 方法列表:
| |
| List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); |
| |
| List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
| |
| List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); |
| |
| List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
| |
| List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
# 示例:
1)根据 id 集合查询:
| @Test |
| public void testQueryByIdList(){ |
| |
| List<User> list = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L)); |
| list.forEach(System.out::println); |
| } |
2)根据 wrapper 查询:
| @Test |
| public void testQueryByWrapper(){ |
| |
| QueryWrapper<User> wrapper = new QueryWrapper<>(); |
| |
| wrapper.like("name", "o") |
| |
| .le("age", 30) |
| |
| .orderByAsc("age"); |
| |
| |
| List<User> list = userMapper.selectList(wrapper); |
| |
| list.forEach(System.out::println); |
| } |
生成的 sql:
| SELECT id,name,email,age FROM user WHERE (name LIKE ? AND age <= ?) ORDER BY age ASC |
# 分页查询
| |
| IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
| |
| IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
| |
| Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); |
# 引入分页插件
| import com.baomidou.mybatisplus.annotation.DbType; |
| import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| import org.springframework.context.annotation.Bean; |
| import org.springframework.context.annotation.Configuration; |
| |
| @Configuration |
| public class MybatisConfig { |
| |
| |
| * 注册 mybatis plus 的分页插件 |
| */ |
| @Bean |
| public MybatisPlusInterceptor paginationInterceptor() { |
| MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
| |
| paginationInnerInterceptor.setDbType(DbType.MYSQL); |
| |
| paginationInnerInterceptor.setOverflow(true); |
| |
| paginationInnerInterceptor.setMaxLimit(500L); |
| interceptor.addInnerInterceptor(paginationInnerInterceptor); |
| return interceptor; |
| } |
| } |
# 测试分页
代码:
| @Test |
| public void testPageQuery(){ |
| |
| Page<User> page = new Page<>(); |
| |
| page.setCurrent(1); |
| |
| page.setSize(3); |
| |
| userMapper.selectPage(page, null); |
| |
| |
| long total = page.getTotal(); |
| System.out.println("total = " + total); |
| |
| long pages = page.getPages(); |
| System.out.println("pages = " + pages); |
| |
| List<User> list = page.getRecords(); |
| list.forEach(System.out::println); |
| } |
# IService 的 CRUD
MybatisPlus 除了提供 BaseMapper,还提供了通用的 Service 接口: IService
# 新增
| |
| boolean save(T entity); |
| |
| boolean saveBatch(Collection<T> entityList); |
| |
| boolean saveBatch(Collection<T> entityList, int batchSize); |
# 参数说明
类型 | 参数名 | 描述 |
---|
T | entity | 实体对象 |
Collection | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
# SaveOrUpdate
| |
| boolean saveOrUpdate(T entity); |
| |
| boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); |
| |
| boolean saveOrUpdateBatch(Collection<T> entityList); |
| |
| boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize); |
# 参数说明
类型 | 参数名 | 描述 |
---|
T | entity | 实体对象 |
Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
# 删除
| |
| boolean remove(Wrapper<T> queryWrapper); |
| |
| boolean removeById(Serializable id); |
| |
| boolean removeByMap(Map<String, Object> columnMap); |
| |
| boolean removeByIds(Collection<? extends Serializable> idList); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Wrapper | queryWrapper | 实体包装类 QueryWrapper |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
# 修改
| |
| boolean update(Wrapper<T> updateWrapper); |
| |
| boolean update(T entity, Wrapper<T> updateWrapper); |
| |
| boolean updateById(T entity); |
| |
| boolean updateBatchById(Collection<T> entityList); |
| |
| boolean updateBatchById(Collection<T> entityList, int batchSize); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
T | entity | 实体对象 |
Collection | entityList | 实体对象集合 |
int | batchSize | 更新批次数量 |
# 查询单个
| |
| T getById(Serializable id); |
| |
| T getOne(Wrapper<T> queryWrapper); |
| |
| T getOne(Wrapper<T> queryWrapper, boolean throwEx); |
| |
| Map<String, Object> getMap(Wrapper<T> queryWrapper); |
| |
| <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Serializable | id | 主键 ID |
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
boolean | throwEx | 有多个 result 是否抛出异常 |
T | entity | 实体对象 |
Function<? super Object, V> | mapper | 转换函数 |
# 查询多个
| |
| List<T> list(); |
| |
| List<T> list(Wrapper<T> queryWrapper); |
| |
| Collection<T> listByIds(Collection<? extends Serializable> idList); |
| |
| 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); |
| |
| List<Object> listObjs(Wrapper<T> queryWrapper); |
| |
| <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
Map<?String, Object> | columnMap | 表字段 map 对象 |
Function<? super Object, V> | mapper | 转换函数 |
# 分页查询
| |
| 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); |
# 参数说明
类型 | 参数名 | 描述 |
---|
IPage | page | 翻页对象 |
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
# 查询数量
| |
| int count(); |
| |
| int count(Wrapper<T> queryWrapper); |
# 参数说明
类型 | 参数名 | 描述 |
---|
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
# 链式查询
# query
| |
| QueryChainWrapper<T> query(); |
| |
| LambdaQueryChainWrapper<T> lambdaQuery(); |
| |
| |
| query().eq("column", value).one(); |
| lambdaQuery().eq(Entity::getId, value).list(); |
# 引入 mybatis-plus
# 依赖
| |
| <dependency> |
| <groupId>com.baomidou</groupId> |
| <artifactId>mybatis-plus-boot-starter</artifactId> |
| </dependency> |
# 增加扫描路径
| @MapperScan("com.lemon.goods") |
| @SpringBootApplication |
| public class GoodsApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(GoodsApplication.class); |
| } |
| } |
# 全局配置
然后在 ly-item-service
的 application.yml
文件中添加配置:
| mybatis-plus: |
| type-aliases-package: com.leyou.item.entity |
| mapper-locations: classpath*: mappers/*.xml |
| global-config: |
| db-config: |
| id-type: auto |
| update-strategy: NOT_EMPTY |
| insert-strategy: NOT_EMPTY |
# 引入分页插件
| import com.baomidou.mybatisplus.annotation.DbType; |
| import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| import org.springframework.context.annotation.Bean; |
| import org.springframework.context.annotation.Configuration; |
| |
| @Configuration |
| public class MybatisConfig { |
| |
| |
| * 注册 mybatis plus 的分页插件 |
| */ |
| @Bean |
| public MybatisPlusInterceptor paginationInterceptor() { |
| MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
| |
| paginationInnerInterceptor.setDbType(DbType.MYSQL); |
| |
| paginationInnerInterceptor.setOverflow(true); |
| |
| paginationInnerInterceptor.setMaxLimit(500L); |
| interceptor.addInnerInterceptor(paginationInnerInterceptor); |
| return interceptor; |
| } |
| } |
# 使用
# Service
| public interface CategoryService extends IService<Category> { |
| } |
# ServiceImpl
| @Service |
| public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService { |
| } |
# Mapper
| public interface CategoryMapper extends BaseMapper<Category> { |
| } |
🚀🚀🚀