MyBatis-Plus【通用Mapper篇】

2年前 (2022) 程序员胖胖胖虎阿
333 0 0

MP-通用Mapper

  • 一、通用Mapper
  • 二、使用方式
    • 1、源码分析
      • :one:Insert 插入方法
      • :two:Delete 删除方法
      • :three:Update 修改方法
      • :four: Select 查询方法

一、通用Mapper

在MyBatis-Plus里面,可以实现对数据库的CRUD操作,官方对通用Mapper的解释如下说明:

通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器,
1、泛型 T任意实体对象
2、参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
3、对象 Wrapper条件构造器

MyBatis-Plus【通用Mapper篇】
这张图的大致含义就是 MyBatis-PLUS利用注解,核心模块和生成器等组件,来完成对实体的扫描,自动映射解析实体对象,完成表名与列名的对应关系。通过封装的SQL语句,最终完成 CRUD操作。

二、使用方式

在Mapper的接口上需要继承一个BaseMapper的接口,其泛型为操作的数据库表对应的pojo类。

@Repository("userMapper")
public interface UserMapper extends BaseMapper<User>{
}

1、源码分析

BaseMapper的源码如下所示,

public interface BaseMapper<T> extends Mapper<T> {

    /**
     * 插入一条记录
     *
     * @param entity 实体对象
     */
    int insert(T entity);

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    int deleteById(Serializable id);

    /**
     * 根据实体(ID)删除
     *
     * @param entity 实体对象
     * @since 3.4.4
     */
    int deleteById(T entity);

    /**
     * 根据 columnMap 条件,删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,删除记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 删除(根据ID或实体 批量删除)
     *
     * @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * 根据 whereEntity 条件,更新记录
     *
     * @param entity        实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T selectById(Serializable id);

    /**
     * 查询(根据ID 批量查询)
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,查询一条记录
     * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
            if (ts.size() != 1) {
                throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records");
            }
            return ts.get(0);
        }
        return null;
    }

    /**
     * 根据 Wrapper 条件,判断是否存在记录
     *
     * @param queryWrapper 实体对象封装操作类
     * @return
     */
    default boolean exists(Wrapper<T> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0;
    }

    /**
     * 根据 Wrapper 条件,查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>注意: 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

1️⃣Insert 插入方法

参数说明:

类型 参数名 描述
T Entity 实体对象

案例演示:

@Test
	public void test2() {
		// 新增用户信息 INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
		User user = new User("joker",23,"joker@qq.com");
		int insert = userMapper.insert(user);
		System.out.println("成功插入"+insert+"条数据");
		// 在MyBatis里默认是使用雪花算法创建id 不会默认使用数据库里面的自增主键
		System.out.println("id:"+user.getId());
	}

注意:如果未设置主键,MyBatis-plus则会使用雪花算法自动生成一个随机的Long型的的主键

2️⃣Delete 删除方法

方法介绍:

// 根据 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 wrapper 实体对象封装操作类(可以为 null)
Collection<? extends Serializable> idList 主键 ID 列表(不能为 null 以及 empty)
Serializable id 主键 ID
Map<String, Object> columnMap 表字段 map 对象

案例演示:
1、delete

@Test
	public void test() {
		// 根据 entity 条件,删除记录
		//int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
		User user = new User();
		user.setId(13L);
		Wrapper<User> wrapper = new UpdateWrapper<>(user);

		int delete = userMapper.delete(wrapper);
		System.out.println("删除了"+delete+"条数据");
	}

2、deleteBatchIds:

@Test
	public void test5() {
		// 批量删除 DELETE FROM user WHERE id IN ( ? , ? )
		Collection<Long> ids = new ArrayList<>();
		ids.add(5L);
		ids.add(2L);
		int deleteBatchIds = userMapper.deleteBatchIds(ids);
		System.out.println("删除了"+deleteBatchIds+"条数据");
	}

3、deleteById

@Test
	public void test3() {
		// 根据id删除 DELETE FROM user WHERE id=?
		int deleteById = userMapper.deleteById(1529380500983910401L); 
		System.out.println("成功删除"+deleteById);
	}

4、deleteByMap

@Test
	public void test4() {
		// 根据条件删除数据 可以删除多个 DELETE FROM user WHERE name = ? AND age = ?
		Map<String, Object> map = new HashMap<>();
		map.put("name", "张三");
		map.put("age", 23);
		int deleteByMap = userMapper.deleteByMap(map);
		System.out.println("删除了"+deleteByMap);
	}

3️⃣Update 修改方法

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

参数说明:

类型 参数名 描述
T entity 实体对象 (set 条件值,可为 null)
Wrapper updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

案例演示:
1、Update

@Test
	public void testupdate() {
		// 根据id修改数据 UPDATE user SET name=?, age=?, email=? WHERE id=?
		User user  = new User(1L,"koppy",25,"koppy@163.com");
		User wrapperUser = new User();
		wrapperUser.setId(1L);
		Wrapper<User> wrapper = new UpdateWrapper<>(wrapperUser);
		int updateById = userMapper.update(user, wrapper);
		System.out.println("修改了"+updateById+"条数据");
	}

2、updateById

@Test
	public void test6() {
		// 根据id修改数据 UPDATE user SET name=?, age=?, email=? WHERE id=?
		User user  = new User(1L,"koppy",45,"koppy@163.com");
		int updateById = userMapper.updateById(user);
		System.out.println("修改了"+updateById+"条数据");
	}

4️⃣ Select 查询方法

// 根据 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 queryWrapper 实体对象封装操作类(可以为 null)
Collection<? extends Serializable> idList 主键 ID 列表(不能为 null 以及 empty)
Map<String, Object> columnMap 表字段 map 对象
IPage page 分页查询条件(可以为 RowBounds.DEFAULT)

案例演示:
1、selectById

@Test
	public void testSelect() {
		User user = userMapper.selectById(1L);
		System.out.println(user);
	}

MyBatis-Plus【通用Mapper篇】
2、selectOne

@Test
	public void TestSelectOne() {
		User user  =new User();
		user.setAge(18);
		Wrapper<User> queWrapper  =new QueryWrapper<>(user);
		
		User selectOne = userMapper.selectOne(queWrapper);
		System.out.println(selectOne);
	}

注意:在使用SelectOne的方法的时候,需要注意的是!!!selectOne中方法如果查出多条数据,则会抛出一个警告,但是不会报错,原因就是SelectOne的底层中,对查询结果进行了一个判断,如果将结果>1则会抛出warn,否则会返回第一个查询结果

selectOne的底层源码:

 /**
     * 根据 entity 条件,查询一条记录
     * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
            if (ts.size() != 1) {
                throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records");
            }
            return ts.get(0);
        }
        return null;
    }

**还要额外说明一点:我用的是MP的最新版本,不会像网上说的抛出警告,可能旧版本会吧,这个还需要看源码
3、selectByPage 不带条件的查询

@Test
	public void selectByPage() {
		Page<User> page = new Page<>();
		page.setCurrent(1);
		page.setSize(5);
		User user = new User();
		user.setAge(15);
		Wrapper<User> wrapper  =new QueryWrapper<>();
		
		Page<User> page2 = userMapper.selectPage(page, null);
		List<User> list = page2.getRecords();
		for (User user2 : list) {
			System.out.println(user2);
		}
	}

MyBatis-Plus【通用Mapper篇】
selectMapsPage带条件的查询

@Test
	public void testSelectMapsPage() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		// 返回指定列,这里是数据库的字段,而不是实体类的属性
		queryWrapper.select("id", "name", "age", "email");
		Map<String, Object> paramMaps = new HashMap<>();
		paramMaps.put("age",21);
		queryWrapper.allEq(paramMaps);
		Page<Map<String, Object>> page = new Page<>(1, 5);
		// 第1个参数:分页参数 第2个参数:条件查询包装参数——指定了返回哪些列
		Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, queryWrapper);
		List<Map<String, Object>> records = pageParam.getRecords();
		records.forEach(System.out::println);
		System.out.println("总页数:"+pageParam.getPages()); // 总页数
		System.out.println("总记录数:"+pageParam.getTotal()); // 总记录数
		System.out.println("当前页码:"+pageParam.getCurrent()); // 当前页码
		System.out.println("每页记录数:"+pageParam.getSize()); // 每页记录数
		System.out.println("是否有下一页:"+pageParam.hasNext()); // 是否有下一页
		System.out.println("是否有上一页"+pageParam.hasPrevious()); // 是否有上一页
	}

MyBatis-Plus【通用Mapper篇】

版权声明:程序员胖胖胖虎阿 发表于 2022年10月4日 上午1:16。
转载请注明:MyBatis-Plus【通用Mapper篇】 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...