5. 通用
CRUD接口
5.1. Mapper CRUD 接口
集成MyBatis Plus之后,userMapper就会提供17个方法,我们把结构视图打开可以看到:
这些方法就是BaseMapper为我们提供的通用的CRUD方法,只要是继承BaseMapper就会有这些方法。接下来分类讲一下这些通用CRUD方法的使用。
5.1.1. 插入操作
1 int insert(T entity);
@Test
public void testInsert(){
User user = new User();
user.setId(8l);
user.setName("王五");
user.setEmail("ww@qq.com");
user.setAge(34);
int result = userMapper.insert(user);
System.out.println("result:"+result);
}
5.1.2. 更新操作
- Integer updateById(@Param(“et”) T entity);
要更新id为6的数据信息
测试代码
@Test
public void testUpdate(){
User user = new User();
user.setId(6l);
user.setLastName("刘六");
user.setEmail("ll@qq.com");
user.setAge(23);
int result = userMapper.updateById(user);
System.out.println("result:"+result);
}
日志输出如下:
14:39:19.821 [main] DEBUG com.zzlh.mp.mapper.UserMapper.updateById - ==> Preparing: UPDATE tbl_user SET last_Name=?, age=?, email=? WHERE id=?
14:39:19.842 [main] DEBUG com.zzlh.mp.mapper.UserMapper.updateById - ==> Parameters: 刘六(String), 23(Integer), ll@qq.com(String), 6(Long)
14:39:19.887 [main] DEBUG com.zzlh.mp.mapper.UserMapper.updateById - <== Updates: 1
14:39:19.888 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@742d4e15]
14:39:19.888 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
result:1
再次查看数据库记录
5.1.3. 查询操作
- T selectById(Serializable id);
User user = userMapper.selectById(6l);
- T selectOne(@Param(“ew”) Wrapper queryWrapper);
User user = mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, 6));
- List selectBatchIds(@Param(“coll”) Collection<? extends Serializable> idList);
List<Integer> idlist = Arrays.asList(3, 5, 6);
List<User> userList = userMapper.selectBatchIds(idlist);
userList.forEach(System.out::println);
15:04:48.769 [main] DEBUG com.zzlh.mp.mapper.UserMapper.selectBatchIds - ==> Preparing: SELECT id,last_Name,age,email FROM tbl_user WHERE id IN ( ? , ? , ? )
15:04:48.788 [main] DEBUG com.zzlh.mp.mapper.UserMapper.selectBatchIds - ==> Parameters: 3(Integer), 5(Integer), 6(Integer)
15:04:48.799 [main] DEBUG com.zzlh.mp.mapper.UserMapper.selectBatchIds - <== Total: 3
15:04:48.800 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@88a8218]
15:04:48.800 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
User(id=3, lastName=Tom, age=28, email=test3@baomidou.com, level=0)
User(id=5, lastName=Billie, age=24, email=test5@baomidou.com, level=0)
User(id=6, lastName=刘七, age=23, email=ll@qq.com, level=0)
- List selectByMap(@Param(“cm”) Map<String, Object> columnMap);
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("last_name","刘七");
columnMap.put("age",34);
List<User> userList = userMapper.selectByMap(columnMap);
userList.forEach(System.out::println);
注意:使用Map查询的时候,使用的是数据库的地段名称last_name,而不是实体的属性lastName
。
5) IPage selectPage(IPage page, @Param(“ew”) Wrapper queryWrapper);
IPage<User> userIPage = userMapper.selectPage(new Page<User>(2, 2), null);
List<User> userList = userIPage.getRecords();
userList.forEach(System.out::println);
注:2.X
版本的时候,该方法返回的分页对象是内存分页,也就是将所有数据都查询出来,然后通过java方法进行分页,当数据量大的时候或者操作比较频繁的时候该方法会有查询不准确的情况。3.X
版本的时候,我发现直接使用的时候并不会分页,可能在新版本的时候将该方法修改为必须配合分页插件进行物理分页。由于没有找到相关的说明,到码云上给官方团队确认了一下,确实必须使用分页插件。分页插件在以后插件里面专门讲解。
5.1.4. 删除操作
- int deleteById(Serializable id);
int reult = userMapper.deleteById(6l);
- int deleteByMap(@Param(“cm”) Map<String, Object> columnMap);
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("last_name","王留");
columnMap.put("age",34);
int result = userMapper.deleteByMap(columnMap);
- int deleteBatchIds(@Param(“coll”) Collection<? extends Serializable> idList);
List<Integer> idList = Arrays.asList(8, 9, 10);
userMapper.deleteBatchIds(idList);
5.1.5. MP 启动注入 SQL 原理分析
mapper类继承了BaseMapper就会有通用的CRUD操作,相关的17个方法是来自于BaseMapper,但是我们并没有写SQL语句或者SQL代码块,那么是怎么操作呢?因为 MyBatis最终还是需要通过SQL语句操作数据。
首先来看一下使用的userMapper是什么?里面有哪些内容?运行一个测试方法,打上断点,可以看到。是一个MybatisMapperProxy代理对象。
userMapper是一个com.baomidou.mybatisplus.core.override.MybatisMapperProxy
MybatisMapperProxy下面有sqlSession–>sqlSessionFactory。
然后sqlSessionFactory里面 configuration(全局配置)–>mappedStatements(包含了sql语句的配置)。每一个mappedStatement都表示Mapper接口中的一个方法与Mapper映射文件中的一个SQL,也就是说,mappedStatement对象里面都包含了接口的方法和SQL语句。
MP在启动就会挨个分析xxxMapper中的方法,并且将对应SQL语句处理好,保存到configuration对象中的mappedStatements中。
在控制台日志中可以看到:
而实现这些代码是在AbstractSqlInjector这个类的inspectInject方法中。可以追踪源码看看怎么装载的,这里说几个重要的对象;
- Configuration: MyBatis 或者 MP全局配置对象。
- MappedStatement:一 个 MappedStatement对应Mapper配置文件中的一个select/update/insert/delete节点,主要描述的是一条SQL语句。
SqlMethod
: 枚举对象,MP支持的 支持的 SQL方法,SQL语句也在这里存放。- TableInfo:数据库表反射信息,可以获取到数据库表相关的信息。
- SqlSource: SQL语句处理对象。
- MapperBuilderAssistant: 用于缓存、 SQL参数、查询方剂结果集处理等.通过 MapperBuilderAssistant将每一个mappedStatement添加到 configuration中。
5.2. Service CRUD 接口
5.2.1. 插入操作
//新增单条数据
boolean save(T entity);
//批量插入,默认1000
boolean saveBatch(Collection<T> entityList);
//批量分批次插入,数据量大的时候建议使用
boolean saveBatch(Collection<T> entityList, int batchSize);
//新增或更新单条数据
boolean saveOrUpdate(T entity);
boolean saveOrUpdateBatch(Collection<T> entityList);
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
5.2.2. 更新操作
//按ID更新
boolean updateById(T entity);
//按条件更新
boolean update(T entity, Wrapper<T> updateWrapper);
boolean update(Wrapper<T> updateWrapper);
//批量更新
boolean updateBatchById(Collection<T> entityList);
boolean updateBatchById(Collection<T> entityList, int batchSize);
5.2.3. 查询操作
//根据ID查询
T getById(Serializable id);
//根据查询条件查询,返回第一条
T getOne(Wrapper<T> queryWrapper);
//根据查询条件查询,如果查询到多条抛出异常
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
//返回map对象
Map<String, Object> getMap(Wrapper<T> queryWrapper);
//查询列表
List<T> list(Wrapper<T> queryWrapper);
//根据ID集合查询列表
Collection<T> listByIds(Collection<? extends Serializable> idList);
//带分页的查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
5.2.4. 删除操作
//按条件删除
boolean remove(Wrapper<T> queryWrapper);
//按ID删除
boolean removeById(Serializable id);
//批量删除
boolean removeByIds(Collection<? extends Serializable> idList);
//按表字段 map 条件删除
boolean removeByMap(Map<String, Object> columnMap);
5.2.5. 其他方法
//根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);
//获取对应 entity 的 BaseMapper
BaseMapper<T> getBaseMapper();
//该方法返回的是链式查询条件构造器,并不是具体的更新方法。
QueryChainWrapper<T> query();
//链式查询 lambda 式
LambdaQueryChainWrapper<T> lambdaQuery();
//该方法返回的是链式更新条件构造器,并不是具体的更新方法。
UpdateChainWrapper<T> update();
//链式更新 lambda 式
LambdaUpdateChainWrapper<T> lambdaUpdate();
5.3. 通用CRUD总结
我们仅仅只是通过集成了BaseMapper就可以使用将近17种增删改查的通用方法,解决了MyBatis每个mapper都要写大量重复的基础SQL片段的问题,极大的减少开发负担。
共同学习,写下你的评论
评论加载中...
作者其他优质文章