MyBatis-Plus 基础教程

天才阿梓 2024-5-4 153 5/4

MyBatis-Plus介绍:

 

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

 

基础使用示例:

1、导入依赖坐标

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.5.3.2</version>
</dependency>

2、继承BaseMapper,调用mybatis-plus内置方法

// 不想努力直接继承mybatis-plus的家产 (Mapper层)
@Mapper
public interface UserMapper extends BaseMapper<User> {

}
// 调用BaseMapper的方法 (Controller层)
void contextLoads() {
    userMapper.selectById(1L);
}

MyBatis-Plus 基础教程

这些BaseMapper的方法直接调用,大大提高开发效率!          Mybatis-Plus官网:https://baomidou.com/

3、yaml配置

mybatis-plus:
  type-aliases-package: com.forest.mp.domain.po # 别名扫描包
  mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,默认值
  configuration:
    map-underscore-to-camel-case: true # 是否开启下划线和驼峰的映射cache-
    enabled: false # 是否开启二级缓存
  global-config:
    db-config:
      id-type: assign_id # id为雪花算法生成
      update-strategy: not_null # 更新策略:只更新非空字段

 

高级用法-条件构造器

1、Mapper层的写法

@Mapper
public interface UserMapper extends BaseMapper<User> {

}

2、Service层的写法

public interface UserService extends IService<User> {
    boolean deductionUserMoney(Long id, Integer money);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public boolean deductionUserMoney(Long id, Integer money) {
        User user = this.getById(id);
        if (user.getStatus() == null || user.getStatus() == 2) {
            throw new RuntimeException("该用户状态异常!");
        }

        user.setBalance(user.getBalance() - money);
        return this.updateById(user);
    }
}

 

3、Controller层的写法

@Api(tags = "用户相关接口")
@RestController("/users")
@RequiredArgsConstructor // lombok工具 构造必要的Bean
public class UserController {

    private final UserServiceImpl userService; // 加上final可被lombok自动构造

    @ApiOperation("新增用户")
    @PostMapping
    public boolean save(@ApiParam("用户Id") @RequestBody User user) {
        return userService.save(user);
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public boolean delete(@ApiParam("用户Id") @PathVariable Long id) {
        return userService.removeById(id);
    }

    @ApiOperation("根据id查询用户")
    @GetMapping("/{id}")
    public User get(@PathVariable Long id) {
        return userService.getById(id);
    }

    @ApiOperation("扣减用户余额")
    @PutMapping("/{id}/deduction/{money}")
    public boolean deduction(@ApiParam("用户Id") @PathVariable Long id, @ApiParam("扣除的钱") @PathVariable Integer money) {
        return userService.deductionUserMoney(id,money);
    }

}

 

MP — 代码生成功能

1、安装Mybatis-plus插件

MyBatis-Plus 基础教程

2、配置mysql连接

MyBatis-Plus 基础教程

配置好url、用户名和密码

3、 点击code generator 填写配置

MyBatis-Plus 基础教程

配置好,点击提交就大功告成啦!你会发现代码帮你自动生成好了。

 

静态工具查询

当service出现相互调用时,未避免循环依赖。可以使用Db静态工具来去调用。

用一个小的案例来讲解吧~

需求: ①改造根据id查询用户的接口,查询用户的同时,查询出用户对应的所有地址 ( 利用Db静态工具 )

User user = this.getById(id);
if (user.getStatus() == null || user.getStatus() == 2) {
    throw new RuntimeException("该用户状态异常!");
}

List<Address> addressList = Db.lambdaQuery(Address.class).eq(Address::getUserId, user.getId()).list();
UserVo userVo = new UserVo();
BeanUtils.copyProperties(user, userVo);
userVo.setAddressList(addressList);

return userVo;

 

逻辑删除

逻辑删除就是基于代码逻辑模拟删除效果,但并不会真正删除数据。思路如下:

    • 在表中添加一个字段标记数据是否被删除
    • 当删除数据时把标记置为1
    • 查询时只查询标记为0的数据

例如逻辑删除字段为deleted:MyBatis-Plus 基础教程

MybatisPlus提供了逻辑删除功能,无需改变方法调用的方式,而是在底层帮我们自动修改CRUD的语句。我们要做的就是在application.yaml文件中配置逻辑删除的字段名称和值即可:

 

1、将数据表添加一个deleted字段

`deleted` bit(1) DEFAULT b'0' COMMENT '逻辑删除'

2、修改yml配置文件

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名,字段类型可以是boolean, integer
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

 

枚举处理器

业务场景(假设:User类中有一个用户状态字段)

我们需要用枚举类型来代表user的状态,可以数据库的字段是int类型。两者并不相通,于是我们与要一个预处理器来自动的将枚举类型的字段转换为int类型的字段,并存储到数据库里面。

MyBatis-Plus 基础教程

1、使用@EnumValue注解来标记需要处理的枚举类

@Getter
public enum UserStatus {
    NORMAL(1, "正常"),
    FROZEN(0, "冻结"),
    ;
    @EnumValue /* 标记 mybatis-plus 需要处理的枚举 */
    @JsonValue /* SpringMvc 在处理enum返回值的时候默认会返回`NORMAL`这类英文的数据。这并不优雅,我们可以用`@JsonValue`来指定返回的是value还是desc还是enum */
    private final int value;
    private final String description;
    
    UserStatus(int value, String description) {
        this.value = value;
        this.description = description;
    }
}

2、修改yml配置文件,指定枚举的预处理器。

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

MyBatis-Plus 基础教程

视频链接:https://www.bilibili.com/video/BV1S142197x7?t=89.6&p=17

 

JSON处理器

当数据表出现json类型的字段时,Java实体类无法与其对应。这时可以使用json处理器来将json类型的字段转换为Java实体类。

1、创建于MySQL字段json类型对应的实体类

MyBatis-Plus 基础教程

@Data
public class UserDetail {
    private Integer age;
    private String intro;
    private String gender;
}

1、添加类型预处理器

/* 开启自动结果映射 */
@TableName(value = "user", autoResultMap = true)
@ApiModel(description = "用户表单实体")
@Data
public class User {

    @ApiModelProperty("用户id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("密码")
    private String password;

    @ApiModelProperty("注册手机号")
    private String phone;

    /* 添加类型处理器 */
    @TableField(typeHandler = JacksonTypeHandler.class)
    @ApiModelProperty("详细信息")
    private UserDetail info;

    @ApiModelProperty("使用状态(1正常")
    private Integer status;

    @ApiModelProperty("账户余额")
    private Integer balance;

    @ApiModelProperty("创建时间")
    private LocalDateTime createTime;

    @ApiModelProperty("更新时间")
    private LocalDateTime updateTime;
}

 

分页插件

mybatis-plus自带的有很多插件,其中最常用的就是分页插件,我们一起来看看把

 

1、添加MybatisConfig配置类

@Configuration
public class MybatisConfiguration {
    @Bean /* 重写Mybatis-plus拦截器哦 */
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        // 创建一个mybatis-plus拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 创建MySql分页插件,将他添加到mybatis-plus里
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);

        return mybatisPlusInterceptor;
    }
}

2、使用分页查询

void contextLoads() {

    int pageNum = 1;
    int pageSize = 10;

    /* 开启分页查询 */
    Page<User> page = new Page<>(pageNum, pageSize);
    page.addOrder(new OrderItem("balance", true)/* 排序字段,是否降序 */);
    page.addOrder(new OrderItem("id", true)/* 排序字段,是否降序 */);

    /* lambda条件构造器 */
    LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>()
            .eq(User::getStatus, 1);

    /* 开始查询 */
    Page<User> userPage = userMapper.selectPage(page, lambdaQueryWrapper);

    /* 结果封装 */
    long total = userPage.getTotal();
    List<User> records = userPage.getRecords();
}

 

原理: MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。

固定的约定

MyBatis-Plus 基础教程

如果你没有遵守约定,也不用担心Mybatis-Plus 自带的注解可以自定义的配置!

 

自定义配置

MybatisPlus  中比较常用的几个注解如下:

@TableName — 用来指定表名

@Tableld — 用来指定表中的主键字段信息

@TableField — 用来指定表中的普通字段信息

MyBatis-Plus 基础教程

IdType枚举:AUTO:

AUTO:数据库自增长

INPUT:通过set方法自行输入

ASSIGN_ID: 分配 ID·接口IdentifierGenerator的方法nextld来生成id默认实现类 为DefaultldentifierGenerator雪花算法

使用@TableField的常见场景:

  • 成员变量名与数据库字段名不一致
  • 成员变量名以is开头,且是布尔值
  • 成员变量名与数据库关键字冲突
  • 成员变量不是数据库字段
  • 成员变量名与数据库字段名不一致

 

总结:

灵魂拷问?

1、MybatisPlus是如何获取实现CRUD的数据库表信息的?

温馨提示:此处内容需要评论本文后才能查看。

2、MybatisPlus的常用注解有哪些?

温馨提示:此处内容需要评论本文后才能查看。

3、IdType的常见类型有哪些?

温馨提示:此处内容需要评论本文后才能查看。

4、使用@TableField的常见场景是?

温馨提示:此处内容需要评论本文后才能查看。

 

相关文章:

- THE END -

天才阿梓

5月08日21:17

最后修改:2024年5月8日
31

非特殊说明,本博所有文章均为博主原创。

共有 2 条评论

    1. 天才阿梓博主

      @FGHRSH 的博客: 学到了吧,哈哈