d41:MyBatisPlus入门,注解,配置,条件构造器,自定义SQL,IService

MyBatisPlus入门与实践指南

导航

  • 学习内容:MyBatisPlus入门,注解,配置,条件构造器,自定义SQL,IService

1. MyBatisPlus入门

MyBatisPlus(MP)是MyBatis的增强工具,提供了更便捷的CRUD操作。以下是入门步骤:

引入依赖

首先,在项目中引入MyBatisPlus的依赖:

xml 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

如果项目中已经使用了MyBatis,可以移除原有的MyBatis依赖。

继承MP的Mapper接口

创建一个Mapper接口,继承BaseMapper

java 复制代码
public interface UserMapper extends BaseMapper<User> {
}

这样就可以直接使用MP提供的CRUD方法,无需手动编写SQL语句。

示例代码
java 复制代码
@Test
void testSelectById() {
    User user = userMapper.queryUserById(5L);
    System.out.println("user = " + user);
}

注意 :如果定义了与BaseMapper方法同名的方法,BaseMapper的方法将被优先使用。


2. 常用注解和配置

MyBatisPlus通过实体类的反射来映射数据库表信息,支持多种注解和配置。

实体类注解
  • 指定表名

    java 复制代码
    @TableName("tb_user")
    public class User {
    }
  • 指定主键及其策略

    java 复制代码
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    • IdType.AUTO:自增ID
    • IdType.INPUT:手动输入
    • IdType.ASSIGN_ID:雪花算法(随机),也是默认策略
  • 指定字段名

    java 复制代码
    @TableField("username")
    private String username;
    • 布尔值字段,is前缀会被自动去除:

      java 复制代码
      @TableField("is_right")
      private Boolean isRight;
    • 避免与数据库的关键字段冲突:

      java 复制代码
      @TableField("`other`")
      private Integer other;
全局配置

MyBatisPlus支持MyBatis的原生配置,并提供了全局策略配置:

yaml 复制代码
mybatis-plus:
  mapper-locations: classpath*:mapper/**/*.xml
  type-aliases-package: com.itheima.mp.domain.po
  configuration:
    map-underscore-to-camel-case: true # 开启驼峰命名
    cache-enabled: false # 禁用二级缓存
  global-config:
    db-config:
      id-type: auto # 全局主键策略
      update-strategy: not_null # 默认更新策略

3. 条件构造器和自定义SQL

MyBatisPlus提供了强大的条件构造器,用于动态构造SQL语句。

QueryWrapper
java 复制代码
@Test
void testQueryWrapper() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .select("id", "username", "phone", "info", "balance")
            .like("username", "o")
            .ge("balance", 1000);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}
LambdaWrapper

通过反射获取字段名称,更加类型安全:

java 复制代码
@Test
void testLambdaWrapper() {
    LambdaQueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .lambda()
            .select(User::getId, User::getUsername, User::getPhone, User::getInfo, User::getBalance)
            .like(User::getUsername, "o")
            .ge(User::getBalance, 1000);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}
自定义SQL

可以直接编写SQL语句:

java 复制代码
@Test
void testUpdateWrapper() {
    List<Long> ids = List.of(1L, 2L, 4L);
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>()
            .setSql("balance = balance - 100")
            .in("id", ids);
    userMapper.update(null, updateWrapper);
}
条件比较函数
  • gt:大于(>
  • ge:大于等于(>=
  • lt:小于(<
  • le:小于等于(<=
  • eq:等于(=
  • ne:不等于(!=<>
条件构造器与Mapper混合使用
java 复制代码
@Test
void testCustomSql() {
    List<Long> ids = List.of(1L, 2L, 4L);
    int amount = 200;
    LambdaQueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .lambda()
            .in(User::getId, ids);
    userMapper.updateBalance(queryWrapper, amount);
}

注意 :构造器固定以"ew"为参数值:

java 复制代码
void updateBalance(@Param("ew") LambdaQueryWrapper<User> queryWrapper, int amount);

在Mapper XML中:

xml 复制代码
<update id="updateBalance">
    update user set balance = balance + #{amount}
    ${ew.customSqlSegment}
</update>

4. IService

通过IService进一步简化操作。

继承IService

在接口中继承IService

java 复制代码
public interface IUserService extends IService<User> {
}
实现类

实现类继承ServiceImpl

java 复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
使用IService方法

可以直接使用IService的内置方法:

java 复制代码
@ApiOperation("新增用户")
@PostMapping
public void saveUser(@RequestBody UserFormDTO userFormDTO) {
    User user = BeanUtil.copyProperties(userFormDTO, User.class);
    userService.save(user);
}
业务处理

ServiceImpl中,可以直接使用IServiceMapper层的方法:

java 复制代码
public void deductBalance(Long id, Integer money) {
    User user = this.getById(id);
    baseMapper.deductBalance(id, money);
}

也可以使用Lambda构造业务逻辑:

java 复制代码
@Override
@Transactional
public void deductBalance(Long id, Integer money) {
    User user = this.getById(id);
    if (user == null || user.getStatus() == 2) {
        throw new RuntimeException("用户不存在或已冻结");
    }
    if (user.getBalance() < money) {
        throw new RuntimeException("余额不足");
    }
    int balance = user.getBalance() - money;
    lambdaUpdate()
            .set(User::getBalance, balance)
            .set(balance < 0, User::getStatus, 2)
            .eq(User::getId, id)
            .eq(User::getBalance, user.getBalance()) // 乐观锁
            .update();
}
Lambda查询
java 复制代码
@Override
public List<User> queryUsers(UserQuery userQuery) {
    String name = userQuery.getName();
    Integer status = userQuery.getStatus();
    Integer minBalance = userQuery.getMinBalance();
    Integer maxBalance = userQuery.getMaxBalance();
    return lambdaQuery()
            .like(name != null, User::getUsername, name)
            .eq(status != null, User::getStatus, status)
            .ge(minBalance != null, User::getBalance, minBalance)
            .le(maxBalance != null, User::getBalance, maxBalance)
            .list();
}

5. 批量操作

批量新增

采取分组发送的方式,避免通信传输和内存占用过大:

java 复制代码
@Test
void testSaveBatch() {
    List<User> list = new ArrayList<>(1000);
    long b = System.currentTimeMillis();
    for (int i = 1; i < 100000; i++) {
        list.add(buildUser(i));
        if (i % 1000 == 0) {
            userService.saveBatch(list);
            list.clear();
        }
    }
    long e = System.currentTimeMillis();
    System.out.println("耗时:" + (e - b));
}

注意 :尽管开启了批量保存,但MySQL默认会逐条插入。需要额外开启rewriteBatchedStatements=true


6. 小技巧

Lombok注解

使用Lombok的@RequiredArgsConstructor注解可以自动生成构造器,简化依赖注入:

java 复制代码
@RequiredArgsConstructor
public class UserController {
    private final IUserService userService;
}
相关推荐
色空大师4 小时前
【mybatisPlus详解】
java·mybatis·mybatisplus
尘下吹霜4 小时前
【鉴权架构】SpringBoot + Sa-Token + MyBatis + MySQL + Redis 实现用户鉴权、角色管理、权限管理
spring boot·mysql·mybatis
武子康5 小时前
Java-146 深入浅出 MongoDB 数据插入、批量写入、BSON 格式与逻辑查询and or not操作指南
java·开发语言·数据库·sql·mongodb·性能优化·nosql
IT 小阿姨(数据库)6 小时前
PostgreSQL wal_e 工具详解
运维·数据库·sql·postgresql·centos
小陈爱coding15 小时前
SaaS多租户数据隔离实战:MyBatis拦截器实现行级安全方案
安全·云原生·mybatis·多租户
lubiii_17 小时前
SQLMap常用命令指南(参数及其用法)
sql·web安全·网络安全
lang2015092821 小时前
MyBatis入门指南:从零掌握数据库操作
mybatis
222you21 小时前
Mybatis(1)
java·tomcat·mybatis
编程充电站pro1 天前
SQL 索引速查:CREATE / DROP / SHOW INDEX 用法全解
数据库·sql