MyBatis-Plus

MyBatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上进行了扩展和优化,提供了更多便捷的功能和特性,大大提高了开发效率。

安装与配置

  1. 引入依赖
    在项目的 pom.xml 文件中添加 MyBatis-Plus 的依赖:
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
  1. 配置数据源
    在配置文件(如 application.yml )中配置数据库连接信息:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_name
    username: root
    password: 123456
  1. 配置 MyBatis-Plus
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml

实体类

  1. 注解使用
    • @TableName :指定表名。
    • @TableId :标识主键。
    • @TableField :设置字段属性。
  2. 示例
@TableName("user")
public class User {

    @TableId("id")
    private Long id;

    @TableField("name")
    private String name;

    // 省略 getter 和 setter 方法
}

Mapper 接口

继承 BaseMapper 接口即可获得基本的 CRUD 方法。

public interface UserMapper extends BaseMapper<User> {}

条件构造器(Wrapper)

MyBatis-Plus 为我们提供了强大的条件构造器,用于构建各种复杂的查询、更新和删除条件,避免了手动拼接 SQL 字符串的繁琐和易错性。

  1. QueryWrapper(查询条件构造器):主要用于构建查询条件,可通过一系列方法添加不同的条件。常用方法如下:

    • allEq(Map params):全部相等(或个别isNull)。它接受一个 Map,其中键是数据库字段名,值是要匹配的值。如果值为null,则根据null2IsNull参数的设置来决定是否作为IS NULL条件。例如:

      Map<String, Object> params = new HashMap<>();
      params.put("name", "小明");
      params.put("age", null);
      QueryWrapper queryWrapper = new QueryWrapper<>();
      queryWrapper.allEq(params, false); 
      
    • eq(R column, Object val):等于。用于添加字段等于某个值的条件。例如:queryWrapper.eq("name", "小明");

    • ne(R column, Object val):不等于。

    • gt(R column, Object val):大于。

    • ge(R column, Object val):大于等于。

    • lt(R column, Object val):小于。

    • le(R column, Object val):小于等于。

    • in(R column, Collection<?> coll):字段在给定的集合中。例如:queryWrapper.in("age", Arrays.asList(1, 2, 3));

    • notIn(R column, Collection<?> coll):字段不在给定的集合中。

    • inSql(R column, String inValue):字段IN(SQL 语句)。例如:queryWrapper.inSql("age", "select age from other_table where some_condition");

    • notInSql(R column, String inValue):字段NOT IN(SQL 语句)。

    • groupBy(R... columns):分组。可以指定多个字段进行分组。

    • orderByAsc(R... columns):按照指定字段升序排序。

    • orderByDesc(R... columns):按照指定字段降序排序。

    • orderBy(boolean isAsc, R... columns):更灵活的排序方式,可指定排序顺序和字段。

    • having(String sqlHaving, Object... params)HAVING子句条件。

    • func(Consumer<AbstractWrapper> consumer):用于在出现if...else情况下调用不同方法且保持条件构造器链不断。例如:

      queryWrapper.func(i -> if (true) {
          i.eq("id", 1);
      } else {
          i.ne("id", 1);
      });
      
    • or():拼接OR条件。可以与其他条件方法嵌套使用,如queryWrapper.eq("name", "小明").or().eq("age", 18);

    • and(Consumer<AbstractWrapper> consumer)AND嵌套条件。例如:queryWrapper.eq("name", "小明").and(i -> i.eq("age", 18));

    • apply(String applySql, Object... params):拼接 SQL 片段。注意该方法可用于数据库函数,动态入参的params对应前面applySql内部的{index}部分,这样不会有 SQL 注入风险。例如:queryWrapper.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = '2023-07-03'");

    • last(String lastSql):无视优化规则直接拼接到 SQL 的最后。例如:queryWrapper.last("LIMIT 1");

    • exists(String existsSql):拼接EXISTS(SQL 语句)。

    • notExists(String notExistsSql):拼接NOT EXISTS(SQL 语句)。

  2. UpdateWrapper(更新条件构造器):与 QueryWrapper 类似,主要用于构建更新条件。例如:

    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper.eq("id", 1).set("name", "新名字"); 
    
  3. LambdaQueryWrapper / LambdaUpdateWrapper:这是基于 lambda 表达式的条件构造器,使用起来更加简洁和类型安全。例如:

    LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();
    lambdaQueryWrapper.like(User::getName, "字母").lt(User::getAge, 18); 
    

在使用条件构造器时,需要注意以下几点:

  • 方法中的参数R column表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的需要用转义符包裹),而不是实体类数据字段名。
  • 几乎所有的条件构造函数都提供了condition参数用于实现动态 SQL,即根据该参数判断是否返回true,如果返回false,则该条件不成立。
  • 入参中出现的MapList为空时,对应的条件不会加入到最终生成的 SQL 中。

IService

IService 接口提供了许多常用的方法,方便进行数据的增删改查等操作,减少了重复代码的编写。

  1. IService 介绍:IService 里面已经提供了很多常用方法,例如批量保存、批量更新等。只需要配置好直接调用即可。以下是一些常见的方法示例:

    • default boolean save(T entity):保存单个实体对象。
    • default boolean saveBatch(Collection<T> entityList):批量保存实体对象列表。
    • boolean saveBatch(Collection<T> entityList, int batchSize):批量保存实体对象列表,可指定批量大小。
    • default boolean saveOrUpdateBatch(Collection<T> entityList):批量保存或更新实体对象列表。
  2. IService 使用配置

    • 创建相应的 Mapper 接口,继承BaseMapper。例如:

      @Repository("sysUserMapper")
      public interface SysUserMapper extends BaseMapper<SysUser> {
      }
      
    • 创建 Service 类,继承ServiceImpl,并指定对应的 Mapper 和实体类型。例如:

      @Component
      public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> {
      }
      
  3. IService 调用示例

    public void insert() {
        List<SysUser> sysUsers = new ArrayList<>();
        for (int i = 1; i < 100; i++) {
            SysUser sysUser = new SysUser();
            sysUser.setUsername("长伞");
            sysUser.setPassword("123456");
            sysUsers.add(sysUser);
        }
        sysUserService.saveBatch(sysUsers);
    }
    

此外,IService 还提供了其他方法,如getOne方法可根据条件获取单个实体,如果结果不止一条则会抛出异常,也可通过传递第二个参数false来默认取第一条结果;saveOrUpdateBatch方法用于批量新增或修改等。同时,基于 lambda 表达式也可以进行查询、修改和删除等操作,例如:

  • lambdaQueryList<User> list = userService.lambdaQuery().eq(User::getAge, 18).list();
  • lambdaUpdateboolean update = userService.lambdaUpdate().eq(User::getAge, 18).set(User::getAge, 31).update();
  • lambdaRemoveboolean remove = userService.lambdaUpdate().eq(User::getAge, 18).remove();

分页查询

MyBatis-Plus 中的分页查询功能通常需要使用分页插件来实现,它支持物理分页,返回部分数据,占用内存小,能够获取数据库最新的状态,适用于数据量较大、数据更新频繁的场景。

配置分页插件:首先创建一个 MybatisPlusConfig 配置类,添加一个返回 PaginationInterceptor 对象的方法,并在 Spring Boot 启动类或配置类上使用 @Bean 注解将其注册为一个 Bean。

@Configuration
public class MyBatisPlusConfig { 
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

分页查询方法:MyBatis-Plus 的 Wrapper 提供了两种分页查询的方式,在 Mapper 接口中提供了相应的方法。

  • IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper):根据 entity 条件和分页参数进行查询,并返回一个 IPage 对象。
  • IPage<T> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper):与上一个方法类似,但返回的是包含查询结果映射为 Map 的 IPage 对象。

使用示例如下:

@Test
public void selectByPage() {
    QueryWrapper wrapper = new QueryWrapper();
    wrapper.like("name", "xxx").lt("age", 40); 
    Page page = new Page<>(1, 2); 
    // IPage<User> userIPage = userMapper.selectPage(page, wrapper); 
    IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, wrapper); 
    System.out.println("总页数: " + mapIPage.getPages()); 
    System.out.println("总记录数: " + mapIPage.getTotal()); 
    List<Map<String, Object>> records = mapIPage.getRecords(); 
    records.forEach(System.out::println); 
}

不关心总记录数的分页查询:如果只需要查询数据,而不关心总记录数,可以在创建 Page 对象时传入第三个参数为 false。

Page page = new Page<>(1, 2, false); 

自定义 SQL 分页查询:有时候需要进行多表连接查询或复杂的 SQL 语句分页查询。首先在 Mapper 文件中编写对应的分页查询接口,然后在 XML 中编写对应的 SQL 语句。如果想在自定义的 SQL 语句中使用 Wrapper 查询条件构造器,需要在 Mapper 接口中添加参数,以及在 XML 中进行相应的配置。

Mapper 接口中的方法定义:

IPage selectMyPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);

XML 中的 SQL 语句示例:

SELECT * FROM user ${ew.customSqlSegment} 

测试方法示例:

@Test
public void selectByMyPage() {
    QueryWrapper wrapper = new QueryWrapper();
    wrapper.like("name", "雨").lt("age", 40); 
    Page page = new Page<>(1, 2); 
    IPage<Map<String, Object>> mapIPage = userMapper.selectMyPage(page, wrapper); 
    System.out.println("总页数: " + mapIPage.getPages()); 
    System.out.println("总记录数: " + mapIPage.getTotal()); 
    List<Map<String, Object>> records = mapIPage.getRecords(); 
    records.forEach(System.out::println); 
}

多表 SQL 分页查询:与单表分页查询类似,在 Mapper 接口中定义分页查询方法,传入分页参数,并在 XML 中编写相应的多表连接查询语句。

例如,有两张表 his_ipd_encounterhis_user,根据用户的真实姓名进行多表分页查询的 Mapper 接口定义如下:

public interface UserMapper extends MyMapper { 
    IPage selectByHisName(IPage page); 
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小果呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值