千家信息网

如何操作Mybatis-Plus通用CRUD

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章给大家介绍如何操作Mybatis-Plus通用CRUD,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、插入操作1.1 方法定义/*** 插入一条记录 *@param e
千家信息网最后更新 2026年11月03日如何操作Mybatis-Plus通用CRUD

这篇文章给大家介绍如何操作Mybatis-Plus通用CRUD,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

1、插入操作

1.1 方法定义

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

1.2 测试用例

@RunWith(SpringRunner.class)@SpringBootTestpublic class TestUserMapper {    @Autowired    private UserMapper userMapper;    @Test    public void testInsert(){        User user=new User();        user.setAge(12);        user.setName("曹操");        user.setPassword("123");        user.setMail("caocao@qq.com");        user.setUserName("曹操");        user.setAddress("北京");        //result数据库受影响的行数        int result = userMapper.insert(user);        System.out.println("result=>"+result);        //获取自增长后的id值        System.out.println(user.getId());//自增后的id会回填到对象中    }}

1.3 测试


可以看到,数据已经写入到了数据库,但是,id的值不正确,我们期望的是数据库自增长,实际是MP生成了id的值
写入到了数据库。

如何设置id的生成策略呢?

MP支持的id策略

package com.baomidou.mybatisplus.annotation;import lombok.Getter;/** * 生成ID类型枚举类 * * @author hubin * @since 2015-11-10 */@Getterpublic enum IdType {    /**     * 数据库ID自增     */    AUTO(0),    /**     * 该类型为未设置主键类型     */    NONE(1),    /**     * 用户输入ID     * 

该类型可以通过自己注册自动填充插件进行填充

*/ INPUT(2), /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */ /** * 全局唯一ID (idWorker) */ ID_WORKER(3), /** * 全局唯一ID (UUID) */ UUID(4), /** * 字符串全局唯一ID (idWorker 的字符串表示) */ ID_WORKER_STR(5); private final int key; IdType(int key) { this.key = key; }}

修改User对象:

@Data@NoArgsConstructor@AllArgsConstructor@TableName("tb_user")public class User {    @TableId(value="id",type= IdType.AUTO)//设置id字段为自增长    private Long id;    private String userName;    private String password;    private String name;    private Integer age;    private String email;}

数据插入成功:

1.4 @TableField

在MP中通过@TableField注解可以指定字段的一些属性,常常解决的问题有2个:

1、对象中的属性名和字段名不一致的问题(非驼峰)

2、对象中的属性字段在表中不存在的问题

使用:


其他用法,如密碼字段不加入查询字段:


效果:

.

2、更新操作

在MP中,更新操作有2种,一种是根据id更新,另一种是根据条件更新。

2.1 根据id更新

方法定义:

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

测试:

@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testUpdateById() {         User user = new User(); user.setId(6L); //主键         user.setAge(21); //更新的字段         //根据id更新,更新不为null的字段         this.userMapper.updateById(user); } }

结果:

2.2 根据条件更新

方法定义:

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

测试用例:

@Test public void testUpdate() {        User user = new User(); user.setAge(22); //更新的字段         //更新的条件         QueryWrapper wrapper = new QueryWrapper<>();         wrapper.eq("id", 6);         //执行更新操作         int result = this.userMapper.update(user, wrapper);         System.out.println("result = " + result); }

或者,通过UpdateWrapper进行更新:

@Test public void testUpdate() {         //更新的条件以及字段         UpdateWrapper wrapper = new UpdateWrapper<>();         wrapper.eq("id", 6).set("age", 23);         //执行更新操作         int result = this.userMapper.update(null, wrapper);         System.out.println("result = " + result); }

测试结果:


均可达到更新的效果。

关于wrapper更多的用法后面会详细讲解。

3、删除操作

3.1 deleteById

方法定义:

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

测试用例:

@Test public void testDeleteById() {         //执行删除操作         int result = this.userMapper.deleteById(6L);         System.out.println("result = " + result); }

数据被删除。

3.2 deleteByMap

方法定义:

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

测试用例:

@Test public void testDeleteByMap() {         Map columnMap = new HashMap<>();         columnMap.put("age",20); columnMap.put("name","张三");                 //将columnMap中的元素设置为删除的条件,多个之间为and关系         int result = this.userMapper.deleteByMap(columnMap);         System.out.println("result = " + result); }

3.3 delete

方法定义:

/*** 根据 entity 条件,删除记录 ** @param wrapper 实体对象封装操作类(可以为 null) */  int delete(@Param(Constants.WRAPPER) Wrapper wrapper);

测试用例:

@Test public void testDeleteByMap() {         User user = new User();         user.setAge(20);         user.setName("张三");                 //将实体对象进行包装,包装为操作条件         QueryWrapper wrapper = new QueryWrapper<>(user);         int result = this.userMapper.delete(wrapper);         System.out.println("result = " + result); }

结果:

3.4 deleteBatchIds

方法定义:

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

测试用例:

@Test public void testDeleteByMap() {         //根据id集合批量删除         int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L));         System.out.println("result = " + result); }

结果:

4、查询操作

MP提供了多种查询操作,包括根据id查询、批量查询、查询单条数据、查询列表、分页查询等操作。

4.1 selectById

方法定义:

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

测试用例:

@Test public void testSelectById() {         //根据id查询数据         User user = this.userMapper.selectById(2L);         System.out.println("result = " + user); }

结果:

4.2 selectBatchIds

方法定义:

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

测试用例:

@Test public void testSelectBatchIds() {         //根据id集合批量查询         List users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L));         for (User user : users) {         System.out.println(user);         } }

4.3 selectOne

方法定义:

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

测试用例:

@Test public void testSelectOne() {         QueryWrapper wrapper = new QueryWrapper();         wrapper.eq("name", "李四");         //根据条件查询一条数据,如果结果超过一条会报错         User user = this.userMapper.selectOne(wrapper);        System.out.println(user); }

结果:

4.4 selectCount

方法定义:

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

测试用例:

@Test public void testSelectCount() {         QueryWrapper wrapper = new QueryWrapper();         wrapper.gt("age", 23); //年龄大于23岁                 //根据条件查询数据条数        Integer count = this.userMapper.selectCount(wrapper);         System.out.println("count = " + count); }

4.5 selectList

方法定义:

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

测试用例:

@Test public void testSelectList() {         QueryWrapper wrapper = new QueryWrapper();         wrapper.gt("age", 23); //年龄大于23岁                //根据条件查询数据         List users = this.userMapper.selectList(wrapper);         for (User user : users) {                 System.out.println("user = " + user);         } }

4.6 selectPage

方法定义:

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

配置分页插件:

package cn.itcast.mp; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("cn.itcast.mp.mapper") //设置mapper接口的扫描包 public class MybatisPlusConfig {         /*** 分页插件 */         @Bean         public PaginationInterceptor paginationInterceptor() {                return new PaginationInterceptor();         } }

测试用例:

@Test public void testSelectPage() {         QueryWrapper wrapper = new QueryWrapper();         wrapper.gt("age", 20); //年龄大于20岁         Page page = new Page<>(1,1);                 //根据条件查询数据         IPage iPage = this.userMapper.selectPage(page, wrapper);         System.out.println("数据总条数:" + iPage.getTotal());         System.out.println("总页数:" + iPage.getPages());                 List users = iPage.getRecords();         for (User user : users) {                 System.out.println("user = " + user);         } }

结果:

5 SQL注入的原理

前面我们已经知道,MP在启动后会将BaseMapper中的一系列的方法注册到mappedStatements中,那么究竟是如
何注入的呢?流程又是怎么样的?下面我们将一起来分析下。

在MP中,ISqlInjector负责SQL的注入工作,它是一个接口,AbstractSqlInjector是它的实现类,实现关系如下:


在AbstractSqlInjector中,主要是由inspectInject()方法进行注入的,如下:

 @Override    public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) {        Class modelClass = extractModelClass(mapperClass);        if (modelClass != null) {            String className = mapperClass.toString();            Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());            if (!mapperRegistryCache.contains(className)) {                List methodList = this.getMethodList();                if (CollectionUtils.isNotEmpty(methodList)) {                    TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);                    // 循环注入自定义方法                    methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));                } else {                    logger.debug(mapperClass.toString() + ", No effective injection method was found.");                }                mapperRegistryCache.add(className);            }        }    }

在实现方法中, methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); 是关键,循环遍历方法,进行注入。

最终调用抽象方法injectMappedStatement进行真正的注入:

 /**     * 注入自定义 MappedStatement     *     * @param mapperClass mapper 接口     * @param modelClass  mapper 泛型     * @param tableInfo   数据库表反射信息     * @return MappedStatement     */    public abstract MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo);

查看该方法的实现:

以SelectById为例查看:

可以看到,生成了SqlSource对象,再将SQL通过addSelectMappedStatement方法添加到mappedStatements中。

关于如何操作Mybatis-Plus通用CRUD就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

查询 方法 条件 对象 更新 数据 测试 字段 实体 结果 数据库 封装 类型 生成 全局 属性 年龄 接口 插件 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海睿民互联网科技有限公司 亿策互联网科技 云电互联网科技 互联网科技美容 金融科技和互联网金融 互联网科技生活的内容 博兴的互联网电子科技公司 成都玖崟互联网科技有限公司乐商圈怎么样 济南华为互联网科技产业总部基地 互联网金融科技公司干啥的 互联网科技有哪些公司 武汉健翔互联网络科技有限公司 杭州壁岐互联网科技有限公司 从那以后互联网科技有限公司 2021世界互联网领先科技成果发布 互联网公司属于科技吗 西安左小互联网科技有限公司 好易买互联网科技 绵阳真晨互联网科技有限公司 重庆科技产业互联网有哪些 美国互联网科技 卓越科技(互联网 ) 蓝色互联网科技 福州新华互联网科技学校 知乎 重庆互联网医院沙龙医盟信息科技 互联网金融科技展 卓翼科技产业互联网合作 互联网领先科技活动 宁波允成互联网科技有限公司 知域互联网科技有限公司官网
0