java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot整合mybatis-plus

全网最新springboot整合mybatis-plus的过程

作者:! 恰同学少年!

在本文中,介绍了 MyBatis-Plus 的核心功能和使用方法,包括如何配置分页插件、编写分页查询代码、使用各种 Wrapper 构建复杂查询条件等,通过这些内容,相信你已经对 MyBatis-Plus 有了更深入的了解,并能够在实际项目中灵活应用这些功能,感兴趣的朋友跟随小编一起看看吧

一,简介

1. 什么是mybatis-plus

MyBatis-Plus(简称MP)是一个MyBatis的增强工具,旨在在MyBatis的基础上只做增强不做改变,以简化开发、提高效率。MyBatis-Plus保持了MyBatis原有的所有特性,同时增加了一些实用的功能,使得开发者能够更加便捷地进行数据库操作。以下是MyBatis-Plus的一些主要特点和功能:

2.mybatis-plus特点

二,搭建基本环境

1. 导入基本依赖:

      <!--mybatis-plus依赖-->
      <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
		<!--mysql连接依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <!--连接池依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.18</version>
        </dependency>

2. 编写配置文件

spring:
  data:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_study?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

3. 创建实体类

package org.example.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
@TableName("student")
public class Student {
    @TableId(type = IdType.AUTO)
    private int id;
    private String studentNumber;
    private String name;
    private int gender; 
    // 0 表示女性,1 表示男性
    private Date dateOfBirth;
   // Getters and Setters
    }

4. 编写controller层

package org.example.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/students")
public class StudentController {
}

5. 编写service接口

package org.example.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.example.pojo.Student;
public interface StudentService extends IService<Student> {
}

6. 编写service层

package org.example.service.serviceImpl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.mapper.StudentMapper;
import org.example.pojo.Student;
import org.example.service.StudentService;
import org.springframework.stereotype.Service;
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
}

7. 编写mapper层

package org.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.pojo.Student;
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}

三,基本知识介绍

1. 基本注解 @TableName

主要用于指定表名,实现实体类与表名的绑定,作用于类上,适用于表名与实体类名称不统一的情况,统一的情况可以不用写。

import com.baomidou.mybatisplus.annotation.TableName;
//此处表名称为t_user,实体类名称为User不统一
@TableName("t_user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    // Getters and Setters
}

如果所有的表结构与实体类只是多了一个前缀,可以直接在配置文件里面配置全局的前缀,就可以不使用注解了,两种方式都可以,根据具体场景选择,配置如下:

mybatis-plus:
  global-config:
    db-config:
      table-prefix: t_

@TableId

作用于主键上,指明主键字段,并设置主键的生成方式。

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
@TableName("user_info") // 指定该实体类对应的数据表名
public class UserInfo {
//此处value也可以作用于映射,当实体类中
//的id字段名和数据库中的字段名不相同时,可以使用其属性做增强
    @TableId(value = "id", type = IdType.AUTO) // 标记为主键,并指定主键生成策略为自增
    private Long id;
    private String username;
    private String password;
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

注解属性:
   value:指定表中主键字段,多用于主键字段和实体类字段不同意
    type:id生成策略

对于IdType做出如下说明:

属性说明适用场景
AUTO数据库自增主键适用于 MySQL、SQL Server 等支持自增主键的数据库
NONE不使用任何主键生成策略通常用于主键已经存在的情况
ASSIGN_ID全局唯一ID(默认基于Snowflake算法生成)适用于分布式系统,确保全局唯一性
ASSIGN_UUID全局唯一UUID,生成32位的字符串适用于需要字符串主键的场景
INPUT自定义输入主键值适用于某些特殊场景,如导入数据时需要手动指定主键

改注解作用众多,多用于表字段和实体类字段名称不统一,做映射处理,也可用于零时字段,不存入数据库,或者是一些字段的填充处理(此处需要编写填充处理器)。

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import java.util.Date;
@TableName("user_info")
public class UserInfo {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @TableField("username")
    private String username;
	//此字段不参与查询
    @TableField("password", select=false )
    private String password;
    @TableField("email")
    private String email;
	//注意,此处应该编写相应的填充逻辑
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(value = "update_time", fill = FieldFill.UPDATE)
    private Date updateTime;
    @TableField(exist = false)
    private String tempField; // 临时字段,不在数据库中
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public String getTempField() {
        return tempField;
    }
    public void setTempField(String tempField) {
        this.tempField = tempField;
    }
}

属性说明:
    value:同上面注解一样,用于字段绑定,单个属性的时候可以不写
    select:在值为false的情况下用于设置不参查询,查询之后不会返回回来
    exist :用于类中的零时变量,数据库中没有该字段,只在java中使用
    fill:用于自动填充,比如create_time,update_time这一类,但需要编写相应的处理器

对应处理器代码:

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

@TableLogic

该字段用于指定逻辑删除的字段,当执行删除语句时,做更新操作,只改变当前字段的值,设置为删除状态,数据不做真实处理,查询时也只查询状态为未删除的数据(此过程不需要手动实现,mybatis-plus已经帮忙实现了,我们只需要添加字段,设置相应的状态值)注:该字段也需要加入到对应的表里

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
@TableName("user_info")
public class UserInfo {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String username;
    private String password;
    private String email;
    @TableLogic
    private Integer isDeleted;
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getIsDeleted() {
        return isDeleted;
    }
    public void setIsDeleted(Integer isDeleted) {
        this.isDeleted = isDeleted;
    }
}

在配置文件中添加如下配置:

mybatis-plus:
  global-config:
    db-config:
      # 逻辑删除字段名
      logic-delete-field: deleted
      # 逻辑删除字面值:未删除为0
      logic-not-delete-value: 0
      # 逻辑删除字面值:删除为1
      logic-delete-value: 1

@Version

用于配置乐观锁字段,配置之后的更新操作都会先去比较版本,然后在去操作,整体采用cas机制实现。注:该字段也需要加入到对应的表里

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.Version;
@TableName("order_info")
public class OrderInfo {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String orderNo;
    private Double amount;
    @Version
    private Integer version;
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getOrderNo() {
        return orderNo;
    }
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }
    public Double getAmount() {
        return amount;
    }
    public void setAmount(Double amount) {
        this.amount = amount;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
}

此处需加相关的拦截器:

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

乐观锁的作用:
    乐观锁假设在并发环境中冲突较少,因此在操作数据时不立即获取锁,而是等到提交更新时才检查是否有其他事务修改过数据。如果发现数据已被修改,则更新失败,通常会抛出异常。
    特点:在提交更新时检查版本号,如果版本号匹配则更新成功,否则更新失败。
    效果:多个事务可以同时读取和处理数据,但在提交更新时会检查版本号,确保数据的一致性。

@Transient

作用于实体类字段,使其不参与数据库的操作,其中包括(Insert,Update,Select),@TableField(exist=false)作用相同,充当零时变量。

@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    @Transient
    private String tempField;
    // getters and setters
}

2. Wrapper的介绍*

概念:MyBatisPlus提供了QueryWrapper、LambdaQueryWrapper、UpdateWrapper和LambdaUpdateWrapper等条件类,大大简化了我们的开发,可以使代码更加清晰和易于管理,其中包括多条件查询、排序、条件优先级以及有条件时才加入条件的场景,并提供了示例代码展示如何进行数据库查询和更新操作。

大致的条件(此处粗略列举):

方法描述
eq等于
ne不等于
gt大于
ge大于等于
lt小于
le小于等于
like模糊查询
notLike反向模糊查询
in在某集合内
notIn不在某集合内
isNull为空
isNotNull不为空
between在某个区间内
notBetween不在某个区间内
set设置字段值

QueryWrapper

作用于查询设置查询条件。

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
public class UserService {
    private UserMapper userMapper;
    public List<User> getUsersByConditions() {
        // 创建 QueryWrapper 对象
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 添加查询条件
        queryWrapper.eq("name", "张三")
                    .ge("age", 18)
                    .orderByDesc("create_time");
        // 执行查询
        return userMapper.selectList(queryWrapper);
    }
}

此处执行的sql语句:

SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;

UpdateWrapper

作用于更新设置条件。

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
public class UserService {
    private UserMapper userMapper;
    public int updateUserById() {
        // 创建 UpdateWrapper 对象
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        // 添加更新条件
        updateWrapper.eq("id", 1);
        // 创建要更新的对象
        User user = new User();
        user.setName("李四");
        // 执行更新
        return userMapper.update(user, updateWrapper);
    }
}

此处执行的sql语句:

UPDATE user SET name = '李四' WHERE id = 1;

LambdaQueryWrapper

在QueryWrapper做了增强,作用一样,用于设置查询条件。

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
public class UserService {
    private UserMapper userMapper;
    public List<User> getUsersByLambdaConditions() {
        // 创建 LambdaQueryWrapper 对象
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件
        lambdaQueryWrapper.eq(User::getName, "张三")
                          .ge(User::getAge, 18)
                          .orderByDesc(User::getCreateTime);
        // 执行查询
        return userMapper.selectList(lambdaQueryWrapper);
    }
}

此处执行的sql语句:

SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;

LambdaUpdateWrapper

在UpdateWrapper做了增强,作用一样,用于设置跟新条件。

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
public class UserService {
    private UserMapper userMapper;
    public int updateUserByIdWithLambda() {
        // 创建 LambdaUpdateWrapper 对象
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        // 添加更新条件
        lambdaUpdateWrapper.eq(User::getId, 1);
        // 创建要更新的对象
        User user = new User();
        user.setName("李四");
        // 执行更新
        return userMapper.update(user, lambdaUpdateWrapper);
    }
}

此处执行的sql语句:

UPDATE user SET name = '李四' WHERE id = 1;

Wrappers

用于更简便的条件设置

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
public class UserService {
    private UserMapper userMapper;
    public List<User> getUsersByConditionsUsingWrappers() {
        // 创建 QueryWrapper 对象
        QueryWrapper<User> queryWrapper = Wrappers.<User>query()
                                                  .eq("name", "张三")
                                                  .ge("age", 18)
                                                  .orderByDesc("create_time");
        // 执行查询
        return userMapper.selectList(queryWrapper);
    }
}

此处执行的sql语句:

SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;

3. 分页查询

1. 配置相应的拦截器

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

2. 实现分页逻辑

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public IPage<User> getUserPage(int current, int size) {
        // 创建 Page 对象,传入当前页码和每页大小
        Page<User> page = new Page<>(current, size);
        // 创建 QueryWrapper 对象,添加查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1)
                    .orderByDesc("create_time");
        // 执行分页查询
        IPage<User> userPage = userMapper.selectPage(page, queryWrapper);
		// 获取分页数据
		List<User> users = userPage.getRecords();
		// 获取总记录数
		long total = userPage.getTotal();
		// 获取当前页码
		int current = userPage.getCurrent();
		// 获取每页大小
		int size = userPage.getSize();
		// 获取总页数
		int pages = userPage.getPages();
        return userPage;
    }
}

执行对应的sql语句是:

-- 分页查询
SELECT * 
FROM user 
WHERE status = 1 
ORDER BY create_time DESC 
LIMIT 0, 10; -- 当前页码为1,每页大小为10

四,结语

在本文中,我们详细介绍了 MyBatis-Plus 的核心功能和使用方法,包括如何配置分页插件、编写分页查询代码、使用各种 Wrapper 构建复杂查询条件等。通过这些内容,相信你已经对 MyBatis-Plus 有了更深入的了解,并能够在实际项目中灵活应用这些功能。
MyBatis-Plus 作为一个强大的 MyBatis 增强工具,不仅简化了数据访问层的开发工作,还提供了许多便捷的功能,如分页查询、链式编程、乐观锁等。它能够显著提升开发效率,减少重复代码,使你的项目更加简洁和高效。
如果你在阅读本文后对 MyBatis-Plus 感兴趣,不妨在自己的项目中尝试一下。实践是最好的老师,通过实际操作,你会更加深刻地理解这些功能的奥妙。同时,也欢迎你在评论区分享你的使用经验和遇到的问题,我们一起探讨和解决。
最后,感谢你花时间阅读本文,希望本文能为你带来帮助。如果你觉得本文对你有帮助,别忘了点赞和分享,让更多的人受益。让我们一起在技术的道路上不断前行,共同成长!

您可能感兴趣的文章:
阅读全文