【Mybatis-Plus】 Mapper 接口使用总结

本文展示了如何使用MyBatisPlus的Mapper接口进行数据库的基本CRUD操作,包括插入、删除(按条件、按ID和批量)、更新(按条件、按ID)和查询(按ID、按条件、批量和分页)。每个操作都附带了对应的SQL执行情况和返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要内容是 Mapper接口的使用 示例。

注意:我们需要方法 执行的SQL 是什么样的,以及返回值。

Mapper CRUD 接口

新增

insert方法

==>  Preparing: INSERT INTO user ( user_id, user_name, create_time ) VALUES ( ?, ?, ? ) 
==> Parameters: halo(String), 哈喽啊(String), 2023-07-11 14:01:59.864(Timestamp)
<==    Updates: 1

删除

delete

根据 entity 条件,删除记录

注意:queryWrapper后面可以跟条件构造器

@Test
public void delete() {
    QueryWrapper queryWrapper = new QueryWrapper<>();
    System.out.println(userDao.delete(queryWrapper));
}
==>  Preparing: DELETE FROM user 
==> Parameters: 
<==    Updates: 1

deleteBatchIds

删除(根据ID 批量删除)

@Test
public void deleteBatchIds() {
    List<Integer>  deleteIds = new ArrayList<>();
    deleteIds.add(1);
    deleteIds.add(2);
    deleteIds.add(3);
    System.out.println(userDao.deleteBatchIds(deleteIds));
}
==>  Preparing: DELETE FROM user WHERE id IN ( ? , ? , ? ) 
==> Parameters: 1(Integer), 2(Integer), 3(Integer)
<==    Updates: 1

deleteById

根据 ID 删除

 @Test
public void deleteById(){
        Integer id=1;
        System.out.println(userDao.deleteById(id));
}

执行的SQL语句

==>  Preparing: DELETE FROM user WHERE id=? 
==> Parameters: 1(Integer)
<==    Updates: 0

deleteByMap

根据 columnMap 条件,删除记录

  @Test
    public void deleteByMap() {
        Map<String,Object> params = new HashMap<>();
        params.put("user_id","halo");
        System.out.println(userDao.deleteByMap(params));
    }
==>  Preparing: DELETE FROM user WHERE user_id = ? 
==> Parameters: halo(String)
<==    Updates: 0

修改

update

根据 whereWrapper 条件,更新记录

@Test
public void update() {
    User user = new User();
    user.setUserId("tony");
    QueryWrapper queryWrapper = new QueryWrapper();
    System.out.println(userDao.update(user,queryWrapper));
}
==>  Preparing: UPDATE user SET user_id=? 
==> Parameters: tony(String)
<==    Updates: 1

updateById

根据 ID 修改

@Test
    public void updateById() {
        User user = new User();
        user.setUserId("halo");
        user.setUserName("哈喽啊");
        user.setCreateTime(new Date());
        user.setId(1);
        System.out.println(userDao.updateById(user));
    }
==>  Preparing: UPDATE user SET user_id=?, user_name=?, create_time=? WHERE id=? 
==> Parameters: halo(String), 哈喽啊(String), 2023-07-11 14:17:01.184(Timestamp), 1(Integer)
<==    Updates: 0

查询

selectById
根据 ID 查询

  @Test
    public void selectById() {
        Integer i = 1;
        System.out.println(userDao.selectById(i));
    }
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user WHERE id=? 
==> Parameters: 1(Integer)
<==      Total: 0

selectOne

根据 entity 条件,查询一条记录

注意:如果 查询出来的记录是多条的话,会报错的哦

 @Test
public void selectOne() {
        System.out.println(userDao.selectOne(new QueryWrapper<User>().eq("user_id","halo")));
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user WHERE (user_id = ?) 
==> Parameters: halo(String)
<==      Total: 0

selectBatchIds

查询(根据ID 批量查询)

@Test
public void selectBatchIds() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
     userDao.selectBatchIds(list);   
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user WHERE id IN ( ? , ? ) 
==> Parameters: 1(Integer), 2(Integer)
<==      Total: 0

selectList

根据 entity 条件,查询全部记录

 @Test
public void selectList() {
    System.out.println(userDao.selectList(new QueryWrapper<>()));
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user 
==> Parameters: 
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==        Row: 6, halo1, 哈喽啊2, 2023-07-11 14:35:42.0, null
<==        Row: 7, halo3, 哈喽啊24, 2023-07-11 14:35:51.0, null
<==      Total: 3

selectByMap

查询(根据 columnMap 条件)

注意:这里的返回值与selectMaps 返回值的区别哦

@Test
public void selectByMap() {
    Map<String,Object> params = new HashMap();
    params.put("user_id","halo");
    System.out.println(userDao.selectByMap(params));
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user 
==> Parameters: 
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==        Row: 6, halo1, 哈喽啊2, 2023-07-11 14:35:42.0, null
<==        Row: 7, halo3, 哈喽啊24, 2023-07-11 14:35:51.0, null
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a451491]
[User(id=5, userId=tony, userName=哈喽啊, createTime=Tue Jul 11 14:11:20 CST 2023, deptId=null), 
User(id=6, userId=halo1, userName=哈喽啊2, createTime=Tue Jul 11 14:35:42 CST 2023, deptId=null), 
User(id=7, userId=halo3, userName=哈喽啊24, createTime=Tue Jul 11 14:35:51 CST 2023, deptId=null)]

selectMaps

查询(根据 columnMap 条件)

注意返回值哦

  @Test
public void selectMaps() {
  List<Map<String, Object>>  list = userDao.selectMaps(new QueryWrapper<>());
  System.out.println(list);
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user 
==> Parameters: 
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==        Row: 6, halo1, 哈喽啊2, 2023-07-11 14:35:42.0, null
<==        Row: 7, halo3, 哈喽啊24, 2023-07-11 14:35:51.0, null
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a451491]
[{create_time=2023-07-11 14:11:20.0, user_id=tony, user_name=哈喽啊, id=5},
 {create_time=2023-07-11 14:35:42.0, user_id=halo1, user_name=哈喽啊2, id=6}, 
 {create_time=2023-07-11 14:35:51.0, user_id=halo3, user_name=哈喽啊24, id=7}]

selectObjs

根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值

@Test
public void selectObjs() {
    List<Object> list =  userDao.selectObjs(new QueryWrapper<>());
    System.out.println(list);
}
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user 
==> Parameters: 
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==        Row: 6, halo1, 哈喽啊2, 2023-07-11 14:35:42.0, null
<==        Row: 7, halo3, 哈喽啊24, 2023-07-11 14:35:51.0, null
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7ceb4478]
[5, 6, 7]

selectPage

根据 entity 条件,查询全部记录(并翻页)

注意;这里我们需要配置一下分页哦

@Configuration
public class MyBatisPlusConfig {
    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
 @Test
public void selectPage() {
        Page page = new Page();
        page.setCurrent(1);
        page.setPages(10);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id","tony");
        IPage<Map<String, Object>> iPage = userDao.selectPage(page,queryWrapper);
        System.out.println(iPage.toString());
        }
JsqlParserCountOptimize sql=SELECT  id,user_id,user_name,create_time,dept_id  FROM user 
 
 WHERE (user_id = ?)
==>  Preparing: SELECT COUNT(1) FROM user WHERE (user_id = ?) 
==> Parameters: tony(String)
<==    Columns: COUNT(1)
<==        Row: 1
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user WHERE (user_id = ?) LIMIT ?,? 
==> Parameters: tony(String), 0(Long), 10(Long)
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==      Total: 1

selectMapsPage

根据 Wrapper 条件,查询全部记录(并翻页)

   @Test
    public void selectMapsPage() {
        Page page = new Page();
        page.setCurrent(1);
        page.setPages(10);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id","tony");
        IPage<Map<String, Object>> iPage = userDao.selectMapsPage(page,queryWrapper);
        System.out.println(iPage);
    }

JsqlParserCountOptimize sql=SELECT  id,user_id,user_name,create_time,dept_id  FROM user 
 
 WHERE (user_id = ?)
==>  Preparing: SELECT COUNT(1) FROM user WHERE (user_id = ?) 
==> Parameters: tony(String)
<==    Columns: COUNT(1)
<==        Row: 1
==>  Preparing: SELECT id,user_id,user_name,create_time,dept_id FROM user WHERE (user_id = ?) LIMIT ?,? 
==> Parameters: tony(String), 0(Long), 10(Long)
<==    Columns: id, user_id, user_name, create_time, dept_id
<==        Row: 5, tony, 哈喽啊, 2023-07-11 14:11:20.0, null
<==      Total: 1

selectCount

根据 Wrapper 条件,查询总记录数

@Test
public void selectCount() {
    System.out.println(userDao.selectCount(new QueryWrapper<>()));
}
==>  Preparing: SELECT COUNT( 1 ) FROM user 
==> Parameters: 
<==    Columns: COUNT( 1 )
<==        Row: 3
<==      Total: 1
### MyBatis-Plus Mapper 在多线程环境下的安全性分析 MyBatis-PlusMapper 是基于 MyBatis 的基础之上进行扩展的,其核心仍然是 MyBatis 的 SqlSession 和 Mapper 接口机制。在多线程环境下,MyBatis-PlusMapper 是否安全取决于底层的 SqlSession 实现是否线程安全[^1]。 #### 1. SqlSession 的线程安全性 MyBatis 的 SqlSession 是非线程安全的,因此在多线程环境中不能共享同一个 SqlSession 实例。Spring 框架通过 AOP 和代理模式为每个线程创建独立的 SqlSession 实例,从而确保了线程安全性。在 Spring Boot 集成 MyBatis-Plus 的场景下,Mapper 接口实际上是通过动态代理实现的,每次调用都会从当前线程绑定的事务中获取 SqlSession 实例[^2]。 因此,在 Spring 环境中,MyBatis-PlusMapper 是线程安全的,因为每个线程都有独立的 SqlSession 实例。 #### 2. 性能分析插件对多线程的支持 MyBatis-Plus 提供了性能分析插件(PerformanceInterceptor),可以监控 SQL 执行时间并设置最大执行时间限制。如果 SQL 执行时间超过设定值,则会抛出异常或停止执行[^3]。性能分析插件本身是线程安全的,因为它不会直接操作线程共享的数据结构,而是通过拦截器机制对每个线程的 SQL 执行进行独立监控。 以下是一个配置性能分析插件的示例代码: ```java @Bean @Profile({"dev", "test"}) // 设置开发和测试环境启用 public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(100); // 设置 SQL 执行的最大时间为 100 毫秒 performanceInterceptor.setFormat(true); // 格式化 SQL 输出 return performanceInterceptor; } ``` #### 3. 解决方案与最佳实践 为了确保 MyBatis-Plus 在多线程环境下的安全性与性能,可以采取以下措施: - **使用 Spring 管理的事务**:确保每个线程都使用独立的 SqlSession 实例,避免手动管理 SqlSession 导致的线程安全问题。 - **启用乐观锁拦截器**:通过配置 OptimisticLockerInnerInterceptor,可以有效防止并发更新时的数据不一致问题[^1]。 - **合理配置性能分析插件**:根据实际业务需求调整 SQL 执行时间的最大限制,避免长时间运行的 SQL 影响系统性能。 - **隔离开发与生产环境**:性能分析插件应仅在开发和测试环境中启用,避免对生产环境的性能造成影响。 以下是一个启用乐观锁拦截器的示例代码: ```java @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } ``` ### 注意事项 虽然 MyBatis-PlusMapper 在 Spring 环境中是线程安全的,但在高并发场景下仍需关注以下几点: - 数据库连接池的配置是否合理,以避免连接耗尽。 - SQL 语句的设计是否优化,以减少锁竞争和死锁的风险。 - 是否存在长事务,导致资源占用过久。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值