Mybatis-plus

158 阅读3分钟

因为经常使用到mybatis和mybatis-plus,现在整理一下,经常性会用着用着忘记

mybatis-plus

1.引入依赖

image.png

2.集成BaseMapper

image.png

2.1 两者区别

  • MyBatisPlus 是 MyBatis 的升级版,可以直接将 MyBatis 框架替换成 MyBatisPlus 框架代码无需改动即可运行。mybatis主要是mqpper接口需要自定义方法,然后根据方法写XML文件,mybatis-plus直接继承BaseMapper,可以免掉自定义方法和XML文件,直接调用接口。

  • MyBatisPlus 在 MyBatis 的不支持 Lambda 形式调用上改为:支持 Lambda 形式调用

  • MyBatisPlus 在实体类配置中添加了:@TableName(value=“”)、@TableId(value=“”)、@TableField(value = "") 三个注解,用来映射数据库表及表字段 与 实体类的关系

  • 增加了:主键策略(4 种)分页插件全局拦截插件(智能拦截 delete、update 操作)性能分析插件 等等。

3.常见注解

image.png

4.常用配置

image.png

5.条件构造器

image.png

image.png

image.png

image.png

6.自定义Sql

image.png

image.png

7.IService接口使用

image.png

image.png image.png

8.controller接口业务(代码传输github)

github地址:

@Api -> @Tag 
@ApiIgnore -> @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden @ApiImplicitParam -> @Parameter
@ApiImplicitParams -> @Parameters
@ApiModel -> @Schema 
@ApiModelProperty(hidden = true) -> @Schema(accessMode = READ_ONLY)
@ApiModelProperty -> @Schema 
@ApiOperation(value = "foo", notes = "bar") -> @Operation(summary = "foo", description = "bar") @ApiParam -> @Parameter
@ApiResponse(code = 404, message = "foo") -> @ApiResponse(responseCode = "404", description = "foo")

image.png

8.1 Api+ApiOperation+ApiParam

image.png

8.2 RequestBody(对象传参)+Pathvariable(占位符参数)+RequestParam(占位符传参)

image.png

image.png

image.png

8.3 BeanUtils(复制给其他对象)

image.png

9. 复杂controller业务

image.png

image.png

image.png

访问界面:http://localhost:8080/doc.html

注意:这个是swagger的UI界面:http://localhost:8080/swagger-ui/index.html

image.png

10.Iservice的Lambda方法

@GetMapping("/list1")
@Operation(summary = "多条件查询用户-基于QueryWrapper")
public List<UserVO> queryUsers(UserQuery query){
    // 1.组织条件
    String username = query.getName();
    Integer status = query.getStatus();
    Integer minBalance = query.getMinBalance();
    Integer maxBalance = query.getMaxBalance();
    LambdaQueryWrapper<User> wrapper = new QueryWrapper<User>().lambda()
            .like(username != null, User::getUsername, username)
            .eq(status != null, User::getStatus, status)
            .ge(minBalance != null, User::getBalance, minBalance)
            .le(maxBalance != null, User::getBalance, maxBalance);
    // 2.查询用户
    List<User> users = userService.list(wrapper);
    // 3.处理vo
    return BeanUtil.copyToList(users, UserVO.class);
}

@GetMapping("/list2")
@Operation(summary = "多条件查询用户-基于lambdaQuery")
public List<UserVO> queryUsersByLamdba(UserQuery query){
    // 1.组织条件
    String username = query.getName();
    Integer status = query.getStatus();
    Integer minBalance = query.getMinBalance();
    Integer maxBalance = query.getMaxBalance();
    // 2.查询用户
    List<User> users = userService.lambdaQuery()
            .like(username != null, User::getUsername, username)
            .eq(status != null, User::getStatus, status)
            .ge(minBalance != null, User::getBalance, minBalance)
            .le(maxBalance != null, User::getBalance, maxBalance)
            .list();//one():最多1个结果,list():返回集合结果,count():返回计数结果
    // 3.处理vo
    return BeanUtil.copyToList(users, UserVO.class);
}

@GetMapping("/list3")
@Operation(summary = "多条件查询用户-自定义查询")
public List<UserVO> queryUsersByCondition(UserQuery query){
    List<User> list = userService.queryUsers(query.getName(),query.getStatus(),query.getMaxBalance(),query.getMinBalance());
    return BeanUtil.copyToList(list,UserVO.class);
}

11.批量新增

save和savebatch的效率问题

@Test
void testSaveOneByOne() {
    long b = System.currentTimeMillis();
    for (int i = 1; i <= 100000; i++) {
        userService.save(buildUser(i));
    }
    long e = System.currentTimeMillis();
    System.out.println("耗时:" + (e - b));
}

private User buildUser(int i) {
    User user = new User();
    user.setUsername("user_" + i);
    user.setPassword("123");
    user.setPhone("" + (18688190000L + i));
    user.setBalance(2000);
    user.setInfo("{"age": 24, "intro": "英文老师", "gender": "female"}");
    user.setCreateTime(LocalDateTime.now());
    user.setUpdateTime(user.getCreateTime());
    return user;
}
@Test
void testSaveBatch() {
    // 准备10万条数据
    List<User> list = new ArrayList<>(1000);
    long b = System.currentTimeMillis();
    for (int i = 1; i <= 100000; i++) {
        list.add(buildUser(i));
        // 每1000条批量插入一次
        if (i % 1000 == 0) {
            userService.saveBatch(list);
            list.clear();
        }
    }
    long e = System.currentTimeMillis();
    System.out.println("耗时:" + (e - b));
}

MySQL的客户端连接参数中有这样的一个参数:rewriteBatchedStatements。顾名思义,就是重写批处理的statement语句,可以将多条SQL合并为一条

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: MySQL123