?🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的博客专栏《SpringBoot开发之Mybatis-Plus系列》。🎯🎯
🎁如果感觉还不错的话请给我关注加三连吧!🎁🎁
? ? ? ? 在上一期的Mybatis-Plus的博客分享中我们在官网上一起了解了关于Mybatis-Plus的一核心功能和插件,例如:自定义的Id生成器、逻辑删除、乐观锁以及分页插件,当然还有一些插件及核心功能在官网,感兴趣的宝子可自行研究。本期带来的是Mybatis-Plus的内置接口
????????MyBatis-Plus是一个基于MyBatis的增强工具,它简化了MyBatis的开发并提供了一些强大的功能,其中包括一些内置的通用Mapper接口。这些通用Mapper接口使得开发者可以使用简单的方法进行数据库的增、删、改、查操作,而无需手动编写对应的SQL语句。
MyBatis-Plus的内置接口具有以下主要特点:
通用 CRUD 方法:MyBatis-Plus的内置接口提供了通用的增、删、改、查的方法,如、、、等。这些方法封装了对数据库表的基本操作,减少了开发者需要手动编写SQL语句的工作。
insert
deleteById
updateById
selectById
无需XML映射文件:MyBatis-Plus采用了约定大于配置的思想,通过接口的命名规范和方法的签名,无需编写繁琐的XML映射文件,即可完成数据库操作。这简化了MyBatis的配置和使用。
支持主键策略:MyBatis-Plus提供了对多种主键策略的支持,包括自增主键、UUID、雪花算法生成的主键等。开发者可以通过配置指定主键的生成方式。
条件构造方法:MyBatis-Plus的接口提供了一些条件构造的方法,使得开发者可以通过传入条件对象来动态生成SQL条件,实现动态查询的功能。
ConditionMapper
SQL 注入器支持: MyBatis-Plus的接口允许开发者自定义SQL注入的逻辑,以满足一些特殊的需求。这为开发者提供了更大的灵活性。
SqlInjector
支持分页查询: MyBatis-Plus内置了分页查询的功能,通过对象可以轻松地实现分页查询,无需手动编写分页SQL。
Page
逻辑删除: MyBatis-Plus支持逻辑删除,通过注解或配置可以简单地实现逻辑删除的功能,而无需修改表结构。
自动填充字段: MyBatis-Plus支持通过注解或配置自动填充字段,例如创建时间、更新时间等,减少了对这些字段的手动处理。
支持乐观锁: MyBatis-Plus提供了对乐观锁的支持,通过注解或配置可以启用乐观锁机制,确保数据的一致性。
Service CRUD 接口说明:
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
@Test
public void test01() {
Faker faker = new Faker(Locale.CHINA);
Book book = new Book()
.setBookname(faker.book().title())
.setPrice((float) faker.number().randomDouble(2, 100, 999));
bookService.save(book);
log.error("{}", book);
}
@Test
public void test02() {
Faker faker = new Faker(Locale.CHINA);
List<Book> list = Stream.generate(
() -> new Book()
.setBookname(faker.name().fullName())
.setPrice((float) faker.number().randomDouble(2, 100, 999))
).limit(10).collect(Collectors.toList());
bookService.saveBatch(list);
}
@Test
public void test03() {
Faker faker = new Faker(Locale.CHINA);
List<Book> list = Stream.generate(
() -> new Book()
.setBookname(faker.name().fullName())
.setPrice((float) faker.number().randomDouble(2, 100, 999))
).limit(10).collect(Collectors.toList());
bookService.saveBatch(list, 500);
}
? ? ? ? 执行前先进行查找,有则修改无则新增
用法格式
// 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);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
@Test
public void test04() {
Faker faker = new Faker(Locale.CHINA);
Book book = new Book()
.setBookname(faker.book().title())
.setPrice((float) faker.number().randomDouble(2, 100, 999));
bookService.saveOrUpdate(book);
log.error("{}", book);
}
@Test
public void test05() {
Faker faker = new Faker(Locale.CHINA);
Book book = new Book()
.setBookname(faker.book().title())
.setPrice((float) faker.number().randomDouble(2, 100, 999));
UpdateWrapper<Book> wrapper=new UpdateWrapper<>();
wrapper.set("id",494692663555129l);
bookService.saveOrUpdate(book,wrapper);
log.error("{}", book);
}
@Test
public void test06() {
Faker faker = new Faker(Locale.CHINA);
List<Book> list = Stream.generate(
() -> new Book()
.setBookname(faker.name().fullName())
.setPrice((float) faker.number().randomDouble(2, 100, 999))
).limit(10).collect(Collectors.toList());
bookService.saveOrUpdateBatch(list);
}
@Test
public void test07() {
Faker faker = new Faker(Locale.CHINA);
List<Book> list = Stream.generate(
() -> new Book()
.setBookname(faker.name().fullName())
.setPrice((float) faker.number().randomDouble(2, 100, 999))
).limit(10).collect(Collectors.toList());
bookService.saveOrUpdateBatch(list,5);
}
?
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 实体包装类 QueryWrapper |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
@Test
public void test08() {
QueryWrapper<Book> wrapper = new QueryWrapper<>();
wrapper.lt("price", 500);
wrapper.like("bookname", "陈");
bookService.remove(wrapper);
}
@Test
public void test09() {
Map<String, Object> ms = new HashMap<>();
ms.put("price", 100);
ms.put("bookname", "陈");
bookService.removeByMap(ms);
}
@Test
public void test10() {
List<Long> ids = bookService
.list()
.stream()
.limit(5)
.map(Book::getId)
.collect(Collectors.toList());
bookService.removeBatchByIds(ids);
}
removeById根据id删除就不演示了。
?因为我使用的是逻辑删除所有改变的是逻辑删除的字段状态
// 根据 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);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 更新批次数量 |
?测试代码
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);这两个格式测试代码如下
@Test
public void test011() {
UpdateWrapper<Book> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 493587255361727L);
wrapper.set("bookname", "jack");
wrapper.setSql("price=price+1");
bookService.update(wrapper);
}
@Test
public void test12() {
Faker faker = new Faker(Locale.CHINA);
Book goods = new Book()
.setBookname(faker.name().fullName())
.setPrice((float) faker.number().randomDouble(2, 100, 999));
UpdateWrapper<Book> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 493587255361723L);
bookService.update(goods, wrapper);
}
后续的测试代码就不演示了。?
// 根据 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);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Serializable | id | 主键 ID |
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
boolean | throwEx | 有多个 result 是否抛出异常 |
T | entity | 实体对象 |
Function<? super Object, V> | mapper | 转换函数 |
// 查询所有
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);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
Map<String, Object> | columnMap | 表字段 map 对象 |
Function<? super Object, V> | mapper | 转换函数 |
Mapper CRUD接口说明:
通用 CRUD 封装BaseMapper (opens new window)接口,为
Mybatis-Plus
启动时自动解析实体表关系映射转换为Mybatis
内部对象注入容器泛型
T
为任意实体对象参数
Serializable
为任意类型主键Mybatis-Plus
不推荐使用复合主键约定每一张表都有自己的唯一id
主键对象
Wrapper
为 条件构造器
?Mapper接口的一些使用方法的格式都和Service接口的参数一样的,可以借鉴官网进行查看。我下面是简单介绍
// 插入一条记录
int insert(T entity);
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | wrapper | 实体对象封装操作类(可以为 null) |
Collection<? extends Serializable> | idList | 主键 ID 列表(不能为 null 以及 empty) |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
使用提示:在调用
updateById
方法前,需要在T entity
(对应的实体类)中的主键属性上加上@TableId
注解。
参数说明
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 (set 条件值,可为 null) |
Wrapper<T> | updateWrapper | 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) |
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
?
// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
?
// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Serializable | id | 主键 ID |
Wrapper<T> | queryWrapper | 实体对象封装操作类(可以为 null) |
Collection<? extends Serializable> | idList | 主键 ID 列表(不能为 null 以及 empty) |
Map<String, Object> | columnMap | 表字段 map 对象 |
IPage<T> | page | 分页查询条件(可以为 RowBounds.DEFAULT) |
🎉🎉本期的博客分享到此结束🎉🎉
📚📚各位老铁慢慢消化📚📚
🎯🎯下期博客博主会带来新货🎯🎯
🎁三连加关注,阅读不迷路?!🎁