MybatisPlus教程

目录

一、 介绍

二、 快速入门

2.1 使用MybatisPlus步骤

引入MybatisPlus的起步依赖

定义Mapper

2.2 常见注解

2.2.1.@TableName

2.2.2.@TableId

2.2.3.@TableField

2.3 常见配置

三.核心功能

3.1.条件构造器

3.1.1.QueryWrapper

3.1.2.UpdateWrapper

3.1.3.LambdaQueryWrapper

3.2.自定义SQL

3.3.Service接口

3.3.1.常用方法

3.3.2.基本用法

3.3.3.Lambda


一、 介绍

在日常开发中单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。

目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是MybatisPlus.

MyBatisPlus是针对于Mybatis框架的增强。官方网站如下:MybatisPlus官网

二、 快速入门

2.1.使用MybatisPlus步骤

引入MybatisPlus的起步依赖

MyBatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。

因此我们可以用MybatisPlus的starter代替Mybatis的starter:

在pom文件中

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

定义Mapper

自定义的Mapper继承MybatisPlus提供的BaseMapper接口

在接口中会有很多方法

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;


public interface UserMapper extends BaseMapper<User> {


}

编写一个测试类进行测试

package com.itheima.mp.mapper;

import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setId(5L);
        user.setUsername("Lucy");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
    }

    @Test
    void testSelectById() {
        User user = userMapper.selectById(5L);
        System.out.println("user = " + user);
    }


    @Test
    void testQueryByIds() {
        List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(5L);
        user.setBalance(20000);
        userMapper.updateById(user);
    }

    @Test
    void testDeleteUser() {
        userMapper.deleteById(5L);
    }
}

经过测试,没有任何问题

2.2.常见注解

在刚刚的案例中,我们仅仅引入了依赖,继承了BaseMapper就能使用MybatisPlus,非常简单。但是问题来了: MybatisPlus如何知道我们要查询的是哪张表?表中有哪些字段呢?

可以看到在UserMapper在继承BaseMapper的时候指定了一个泛型:

泛型中的User就是与数据库对应的PO.

MybatisPlus就是根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • MybatisPlus会把PO实体的类名驼峰转下划线作为表名
  • MybatisPlus会把名为id的字段作为主键
  • MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型

但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供了一些注解便于我们声明表信息。

2.2.1.@TableName

说明:

  • 描述:表名注解,标识实体类对应的表

  • 使用位置:实体类

2.2.2.@TableId

说明:

  • 描述:主键注解,标识实体类中的主键字段

  • 使用位置:实体类的主键字段

TableId注解支持两个属性:

属性

类型

必须指定

默认值

描述

value

String

" "

表名

type

Enum

IdType.NONE

指定主键类型

IdType支持的类型有:

常见的有三种:

  • AUTO:利用数据库的id自增长

  • INPUT:手动生成id

  • ASSIGN_ID:雪花算法生成Long类型的全局唯一id,这是默认的ID策略(如果不指定的话就是这个)

2.2.3.@TableField

说明:

  • 描述:普通字段注解

一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:

  • 成员变量名与数据库字段名不一致
  • 成员变量是以isXXX命名,按照JavaBean的规范,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。
  • 成员变量名与数据库一致,但是与数据库的关键字冲突。使用@TableField注解给字段名添加转义字符:``

@Data
@TableName("user") //与数据库中表名一致
public class User {

    /**
     * 用户id
     */
    @TableId(value = "id", type = IdType.AUTO) //id实现自增长
    private Long id;

    /**
     * 用户名
     */
    @TableField("'username") //假设这是一个数据库中的关键字,给它转义
    private String username;

    /**
     * 密码
     */
    @TableField(exist = false) //假设该字段不是数据库中的字段
    private String password;

}

2.3.常见配置

MybatisPlus也支持基于yaml文件的自定义配置,详见官方文档:

使用配置 | MyBatis-Plus

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

  • 实体类的别名扫描包

  • 全局id类型

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po
  global-config:
    db-config:
      id-type: auto # 设置全局id类型为自增长(注意:注解的优先级大于配置文件)

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置:

mybatis-plus:
  mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。

总结:

三、核心功能

刚才的案例中都是以id为条件的简单CRUD,一些复杂条件的SQL语句就要用到一些更高级的功能了

3.1.条件构造器

除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。因此BaseMapper中提供的相关方法除了以id作为where条件以外,还支持更加复杂的where条件。

3.1.1.QueryWrapper

无论是修改、删除、查询,都可以使用QueryWrapper来构建查询条件。接下来看一些例子

查询:①查询出名字中带o的,存款大于等于1000元的人的id、username、info、balance字段

    @Test
    void testQueryWrapper(){
        // Select id,username,info,balance From user where username like ? and balance >= ?
        // 查询条件
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .select("id","username","info","balance")
                .like("username","o")
                .ge("balance",1000);
        // 查询
        List<User> users = userMapper.selectList(wrapper);
        //     遍历语句
        users.forEach(System.out::println);
    }

②更新用户名为Rose的用户的余额为2000

    @Test
    void testUpdateBYQueryWrapper(){
        // update user set balance = 2000 where (username = "Rose")

        //要更新的数据
        User user = new User();
        user.setBalance(2000);
        // 更新的条件
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .eq("username","Rose");

        //       user是更新的数据,wrapper是更新的条件
        userMapper.update(user,wrapper);

    }

3.1.2.UpdateWrapper

基于BaseMapper中的update方法更新时只能直接赋值,对于一些复杂的需求就难以实现。 例如:更新id为1,2,4的用户的余额,扣200,对应的SQL应该是

UPDATE user SET balance = balance - 200 WHERE id in (1, 2, 4)

SET的赋值结果是基于字段现有值的,这个时候就要利用UpdateWrapper中的setSql了

setSql可以直接手写sql语句

    @Test
    void testUpdateWrapper(){
        // update user set balance = balance - 200 where id in(1, 2, 4)

        List<Long> ids = List.of(1L,2L,4L);
        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                .setSql("balance = balance - 200") //直接手写sql语句
                        .in("id",ids);
        userMapper.update(null,wrapper);

    }

3.1.3.LambdaQueryWrapper

无论是QueryWrapper还是UpdateWrapper在构造条件的时候都需要写死字段名称,会出现字符串魔法值。这在编程规范中显然是不推荐的。 那怎么样才能不写字段名,又能知道字段名呢?其中一种办法是基于变量的gettter方法结合反射技术。因此我们只要将条件对应的字段的getter方法传递给MybatisPlus,它就能计算出对应的变量名了。而传递方法可以使用JDK8中的方法引用和Lambda表达式。 因此MybatisPlus又提供了一套基于Lambda的Wrapper,包含两个:

LambdaQueryWrapper

LambdaUpdateWrapper

分别对应QueryWrapper和UpdateWrapper

其使用方式如下:

@Test
void testLambdaQueryWrapper() {
    // 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.lambda()
            .select(User::getId, User::getUsername, User::getInfo, User::getBalance)
            .like(User::getUsername, "o")
            .ge(User::getBalance, 1000);
    // 2.查询
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

总结:条件构造器的用法:

  • •QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的where条件部分
  • •UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
  • •尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码

3.2.自定义SQL

我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

使用mybatis:

使用MybatisPlus:

需求:将id在指定范围的用户(例如1、2、4)的余额扣减指定值

@Test
void testCustomWrapper() {
    // 1.准备自定义查询条件
    List<Long> ids = List.of(1L, 2L, 4L);
    QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);
 
    // 2.调用mapper的自定义方法,直接传递Wrapper
    userMapper.deductBalanceByIds(200, wrapper);
}

然后在UserMapper中自定义SQL:

package com.itheima.mp.mapper;
 
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.Param;
 
public interface UserMapper extends BaseMapper<User> {
    @Select("UPDATE user SET balance = balance - #{money} ${ew.customSqlSegment}")
    void deductBalanceByIds(@Param("money") int money, @Param("ew") QueryWrapper<User> wrapper);
}

3.3.Service接口

MybatisPlus不仅提供了BaseMapper,还提供了通用的Service接口及默认实现,封装了一些常用的service模板方法。 通用接口为IService,默认实现为ServiceImpl,其中封装的方法可以分为以下几类:

  • save:新增

  • remove:删除

  • update:更新

  • get:查询单个结果

  • list:查询集合结果

  • count:计数

  • page:分页查询

3.3.1.常用方法

 新增

  • save是新增单个元素

  • saveBatch是批量新增

  • saveOrUpdate是根据id判断,如果数据存在就更新,不存在则新增

  • saveOrUpdateBatch是批量的新增或修改

删除:

  • removeById:根据id删除

  • removeByIds:根据id批量删除

  • removeByMap:根据Map中的键值对为条件删除

  • remove(Wrapper<T>):根据Wrapper条件删除

修改:

  • updateById:根据id修改

  • update(Wrapper<T>):根据UpdateWrapper修改,Wrapper中包含setwhere部分

  • update(T,Wrapper<T>):按照T内的数据修改与Wrapper匹配到的数据

  • updateBatchById:根据id批量修改

查询:

  • getById:根据id查询1条数据

  • getOne(Wrapper<T>):根据Wrapper查询1条数据

  • listByIds:根据id批量查询

  • list(Wrapper<T>):根据Wrapper条件查询多条数据

  • list():查询所有

  • count():统计所有数量

  • count(Wrapper<T>):统计符合Wrapper条件的数据数量

3.3.2.基本用法

由于Service中经常需要定义与业务有关的自定义方法,因此我们不能直接使用IService,而是自定义Service接口,然后继承IService以拓展方法。同时,让自定义的Service实现类继承ServiceImpl,这样就不用自己实现IService中的接口了。关系如下图:

案例需求:基于Restful风格实现下面的接口

编号

接口

请求方式

请求路径

请求参数

返回值

1

新增用户

POST

/users

用户表单实体

2

删除用户

DELETE

/users/{id}

用户id

3

根据id查询用户

GET

/users/{id}

用户id

用户VO

4

根据id批量查询

GET

/users

用户id集合

用户VO集合

5

根据id扣减余额

PUT

/users/{id}/deduction/{money}

用户id

扣减金额

首先,定义IUserService,继承IService

package com.itheima.mp.service;
 
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;
 
public interface IUserService extends IService<User> {
    // 拓展自定义方法
}

然后,编写UserServiceImpl类,继承ServiceImpl,实现UserService

package com.itheima.mp.service.impl;
 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.po.service.IUserService;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;
 
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
                                                                                                        implements IUserService {
}

首先,我们在项目中引入几个依赖:

<!--swagger-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>
<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后需要配置swagger信息,在浏览器中输入localhost:8080/doc.html即可测试:

knife4j:
  enable: true
  openapi:
    title: 用户管理接口文档
    description: "用户管理接口文档"
    email: zhanghuyi@itcast.cn
    concat: 虎哥
    url: https://www.itcast.cn
    version: v1.0.0
    group:
      default:
        group-name: default
        api-rule: package
        api-rule-resources:
          - com.itheima.mp.controller

然后,接口需要两个实体:

  • UserFormDTO:代表新增时的用户表单

  • UserVO:代表查询的返回结果

首先是UserFormDTO:

package com.itheima.mp.domain.dto;
 
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
 
@Data
@ApiModel(description = "用户表单实体")
public class UserFormDTO {
 
    @ApiModelProperty("id")
    private Long id;
 
    @ApiModelProperty("用户名")
    private String username;
 
    @ApiModelProperty("密码")
    private String password;
 
    @ApiModelProperty("注册手机号")
    private String phone;
 
    @ApiModelProperty("详细信息,JSON风格")
    private String info;
 
    @ApiModelProperty("账户余额")
    private Integer balance;
}

然后是UserVO:

package com.itheima.mp.domain.vo;
 
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
 
@Data
@ApiModel(description = "用户VO实体")
public class UserVO {
    
    @ApiModelProperty("用户id")
    private Long id;
    
    @ApiModelProperty("用户名")
    private String username;
    
    @ApiModelProperty("详细信息")
    private String info;
 
    @ApiModelProperty("使用状态(1正常 2冻结)")
    private Integer status;
    
    @ApiModelProperty("账户余额")
    private Integer balance;
}

最后,按照Restful风格编写Controller接口方法:

package com.itheima.mp.controller;
 
import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
 
import java.util.List;
 
@Api(tags = "用户管理接口")
@RequiredArgsConstructor //必备的构造函数,只会对一开始需要初始化的变量去做构造
@RestController
@RequestMapping("users")
public class UserController {
 
    // @Resource
    // private IUserService userService;
    // 加了final表示这是一个常量,必须在初始化的时候完成对变量的初始化
    private final IUserService userService;
 
    @PostMapping
    @ApiOperation("新增用户")
    public void saveUser(@RequestBody UserFormDTO userFormDTO){
        // 1.转换DTO为PO
        User user = BeanUtil.copyProperties(userFormDTO, User.class);
        // 2.新增
        userService.save(user);
    }
 
    @DeleteMapping("/{id}")//占位符
    @ApiOperation("删除用户")
    public void removeUserById(@PathVariable("id") Long userId){
        userService.removeById(userId);
    }
 
    @GetMapping("/{id}")
    @ApiOperation("根据id查询用户")
    public UserVO queryUserById(@PathVariable("id") Long userId){
        // 1.查询用户
        User user = userService.getById(userId);
        // 2.处理vo
        return BeanUtil.copyProperties(user, UserVO.class);
    }
 
    @GetMapping
    @ApiOperation("根据id集合查询用户")
    public List<UserVO> queryUserByIds(@RequestParam("ids") List<Long> ids){
        // 1.查询用户
        List<User> users = userService.listByIds(ids);
        // 2.处理vo
        return BeanUtil.copyToList(users, UserVO.class);
    }
}

可以看到上述接口都直接在controller即可实现,无需编写任何service代码,非常方便。

不过,一些带有业务逻辑的接口则需要在service中自定义实现了。例如下面的需求:

  • 根据id扣减用户余额

这看起来是个简单修改功能,只要修改用户余额即可。但这个业务包含一些业务逻辑处理:

  • 判断用户状态是否正常

  • 判断用户余额是否充足

这些业务逻辑都要在service层来做,另外更新余额需要自定义SQL,要在mapper中来实现。因此,我们除了要编写controller以外,具体的业务还要在service和mapper中编写。

首先在UserController中定义一个方法:

@PutMapping("{id}/deduction/{money}")
@ApiOperation("扣减用户余额")
public void deductBalance(@PathVariable("id") Long id, @PathVariable("money")Integer money){
    userService.deductBalance(id, money);
}

然后是UserService接口:

package com.itheima.mp.service;
 
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;
 
public interface IUserService extends IService<User> {
    void deductBalance(Long id, Integer money);
}

最后是UserServiceImpl实现类:

package com.itheima.mp.service.impl;
 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;
 
// 第一个参数是对应的mapper,第二个是实体
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {


    // @Resource
    // private UserMapper userMapper;

    @Override
    public void deductBalance(Long id, Integer money) {
          // 先查询用户的状态
        // User user = userMapper.selectById(id); //方法1
        // baseMapper.selectById(id); //方法2
        User user = getById(id); //方法3

        // 2.判断用户状态
        if (user == null || user.getStatus() == 2) {
            throw new RuntimeException("用户状态异常");
        }
        // 3.判断用户余额
        if (user.getBalance() < money) {
            throw new RuntimeException("用户余额不足");
        }
        // 4.扣减余额
        baseMapper.deductMoneyById(id, money);
    }
}

最后是mapper:

@Update("UPDATE user SET balance = balance - #{money} WHERE id = #{id}")
void deductMoneyById(@Param("id") Long id, @Param("money") Integer money);

3.3.3.Lambda

IService中还提供了Lambda功能来简化我们的复杂查询及更新功能。我们通过两个案例来学习一下。

案例一:实现一个根据复杂条件查询用户的接口,查询条件如下:

  • name:用户名关键字,可以为空

  • status:用户状态,可以为空

  • minBalance:最小余额,可以为空

  • maxBalance:最大余额,可以为空

可以理解成一个用户的后台管理界面,管理员可以自己选择条件来筛选用户,因此上述条件不一定存在,需要做判断。

我们首先需要定义一个查询条件实体,UserQuery实体:

package com.itheima.mp.domain.query;
 
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
 
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery {
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态:1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
    @ApiModelProperty("余额最大值")
    private Integer maxBalance;
}

接下来我们在UserController中定义一个controller方法:

    @GetMapping("/list")
    @ApiOperation("根据复杂条件查询用户接口")
    public List<UserVO> queryUsers(UserQuery userQuery){
        // 查询用户po集合
        List<User> users = userService.queryUsers(userQuery.getName(),userQuery.getStatus(),userQuery.getMinBalance(),userQuery.getMaxBalance());
        return BeanUtil.copyToList(users, UserVO.class);
    }

Service中对LambdaQueryWrapperLambdaUpdateWrapper的用法进一步做了简化。我们无需自己通过new的方式来创建Wrapper,而是直接调用lambdaQuerylambdaUpdate方法:

/**
     * 根据复杂条件查询用户接口
     * @param name
     * @param minBalance
     * @param maxBalance
     * @return
     */
    @Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {

        List<User> users = 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(); //查到的数据是一个列表

        return users;
    }

可以发现lambdaQuery方法中除了可以构建条件,还需要在链式编程的最后添加一个list(),这是在告诉MP我们的调用结果需要是一个list集合。这里不仅可以用list(),可选的方法有

  • .one():最多1个结果

  • .list():返回集合结果

  • .count():返回计数结果

MybatisPlus会根据链式编程的最后一个方法来判断最终的返回结果。

与lambdaQuery方法类似,IService中的lambdaUpdate方法可以非常方便的实现复杂更新业务。

需求:改造根据id修改用户余额的接口,要求如下

  • 如果扣减后余额为0,则将用户status修改为冻结状态(2)

业务逻辑:也就是说我们在扣减用户余额时,需要对用户剩余余额做出判断,如果发现剩余余额为0,则应该将status修改为2,这就是说update语句的set部分是动态的。

/**
     * 扣减用户余额接口
     * @param id
     * @param money
     */
    @Override
    @Transactional
    public void deductBalance(Long id, Integer money) {
        System.out.println(id+" "+money);
        // 先查询用户的状态
        // User user = userMapper.selectById(id); //方法1
        // baseMapper.selectById(id); //方法2
        User user = getById(id); //方法3

        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户状态异常");
        }
        // 检验余额是否充足
        if(user.getBalance() < money){
            throw new RuntimeException("用户余额不足!");
        }
        //扣减余额
        // baseMapper.deductBalance(id,money);
        int remainBalance = user.getBalance() - money;
        lambdaUpdate()
                .set(User::getBalance,remainBalance)
                .set(remainBalance == 0,User::getStatus,2)
                .eq(User::getId,id)
                .eq(User::getBalance,user.getBalance()) //乐观锁 防止并发 判断一下
                .update();
    }

四、总结

Mybatis-Plus特点:

  • 无侵入:只做增强不做改变,不会对现有的工程产生影响
  • 损耗小:启动即会自动注入基本CRUD,直接面向对象操作
  • 强大的CRUD操作:内置通用Mapper、通用Service,通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求。
  • 支持Lambda形式调用:通过Lambda表达式,方便的编写各类查询条件,无需担心字段写错。
  • 支持主键自动生成:支持多达4种主键策略(内含分布式唯一ID生成器 - Sequence),可自由配置,完美解决主键问题。
  • 支持ActiveRecord模式:支持ActiveRecord形式调用,实体类只需要继承Model类即可进行强大的CRUD操作。
  • 内置代码生成器:采用代码或者Maven插件可以快速生成Mapper、Model、Service、Controller层代码,支持模板引擎。
  • 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上扩展了一些功能,使得使用Mybatis更加方便、高效。它提供了很多实用的功能,比如自动填充、多租户、分页插件等。 下面是Mybatis-Plus的教程: 1. 添加Mybatis-Plus依赖 在pom.xml文件中添加Mybatis-Plus的依赖: ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.3</version> </dependency> ``` 2. 配置Mybatis-Plus 在application.yml文件中配置Mybatis-Plus: ``` mybatis-plus: mapper-locations: classpath:/mapper/*.xml global-config: db-config: id-type: auto field-strategy: not_null table-prefix: mp_ configuration: map-underscore-to-camel-case: true ``` 其中,mapper-locations指定了Mapper.xml文件的位置,global-config配置全局的参数,configuration配置Mybatis的参数。 3. 创建实体类 创建一个实体类,类名与数据库中表名对应,属性名与数据库中字段名对应,使用注解@TableField指定数据库中的字段名: ``` @Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; @TableField("name") private String username; private String password; private Integer age; private String email; } ``` 4. 创建Mapper接口 创建一个Mapper接口,继承BaseMapper接口,即可使用Mybatis-Plus提供的通用方法: ``` public interface UserMapper extends BaseMapper<User> { } ``` 5. 使用Mybatis-Plus 使用Mybatis-Plus进行数据库操作非常简单,只需要调用Mapper接口中的方法即可,如: ``` @Autowired private UserMapper userMapper; public void addUser(User user) { userMapper.insert(user); } public User getUserById(Long id) { return userMapper.selectById(id); } public List<User> getUserList() { return userMapper.selectList(null); } public void updateUser(User user) { userMapper.updateById(user); } public void deleteUser(Long id) { userMapper.deleteById(id); } ``` 以上就是使用Mybatis-Plus的基本教程,如果需要更多的高级功能,可以查看Mybatis-Plus的官方文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值