0


springboot整合mybatis-plus【详细版】

目录

一,简介

1. 什么是mybatis-plus

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

2.mybatis-plus特点

  1. 无侵入:引入MyBatis-Plus不会对现有的MyBatis工程产生影响,可以无缝集成到现有的项目中。 损耗小:启动时自动注入基本的CRUD操作,几乎不消耗额外的性能,可以直接面向对象操作数据库。
  2. 强大的CRUD操作:内置通用Mapper、通用Service,通过少量配置即可实现单表的大部分CRUD操作。同时,MyBatis-Plus提供了强大的条件构造器,满足复杂的查询需求。
  3. 支持Lambda形式调用:利用Lambda表达式方便地编写查询条件,避免了字段名称错误的问题。
  4. 支持主键自动生成:提供了多种主键生成策略,包括分布式唯一ID生成器,解决了主键问题。
  5. 支持ActiveRecord模式:通过继承特定的基类,可以像操作对象一样操作数据库。
  6. 支持自定义全局通用操作:允许开发者注入自己的通用方法。
  7. 内置分页插件:基于MyBatis的物理分页,开发者可以轻松实现分页查询。
  8. 支持多种数据库:兼容MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、PostgreSQL、SQL Server等多种数据库。
  9. 内置性能分析插件:可以输出SQL语句及其执行时间,有助于快速定位慢查询。
  10. 内置全局拦截插件:提供全表删除、更新操作的智能分析阻断,防止误操作。

二,搭建基本环境

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=falseusername: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

3. 创建实体类

packageorg.example.pojo;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importjava.util.Date;@TableName("student")publicclassStudent{@TableId(type =IdType.AUTO)privateint id;privateString studentNumber;privateString name;privateint gender;// 0 表示女性,1 表示男性privateDate dateOfBirth;// Getters and Setters}

4. 编写controller层

packageorg.example.controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/students")publicclassStudentController{}

5. 编写service接口

packageorg.example.service;importcom.baomidou.mybatisplus.extension.service.IService;importorg.example.pojo.Student;publicinterfaceStudentServiceextendsIService<Student>{}

6. 编写service层

packageorg.example.service.serviceImpl;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importorg.example.mapper.StudentMapper;importorg.example.pojo.Student;importorg.example.service.StudentService;importorg.springframework.stereotype.Service;@ServicepublicclassStudentServiceImplextendsServiceImpl<StudentMapper,Student>implementsStudentService{}

7. 编写mapper层

packageorg.example.mapper;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importorg.apache.ibatis.annotations.Mapper;importorg.example.pojo.Student;@MapperpublicinterfaceStudentMapperextendsBaseMapper<Student>{}

三,基本知识介绍

1. 基本注解

@TableName

主要用于指定表名,实现实体类与表名的绑定,作用于类上,适用于表名与实体类名称不统一的情况,统一的情况可以不用写。
在这里插入图片描述

importcom.baomidou.mybatisplus.annotation.TableName;//此处表名称为t_user,实体类名称为User不统一@TableName("t_user")publicclassUser{privateLong id;privateString name;privateInteger age;privateString email;// Getters and Setters}

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

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

@TableId

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

importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.annotation.IdType;@TableName("user_info")// 指定该实体类对应的数据表名publicclassUserInfo{//此处value也可以作用于映射,当实体类中//的id字段名和数据库中的字段名不相同时,可以使用其属性做增强@TableId(value ="id", type =IdType.AUTO)// 标记为主键,并指定主键生成策略为自增privateLong id;privateString username;privateString password;// Getters and SetterspublicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetUsername(){return username;}publicvoidsetUsername(String username){this.username = username;}publicStringgetPassword(){return password;}publicvoidsetPassword(String password){this.password = password;}}
注解属性:
   value:指定表中主键字段,多用于主键字段和实体类字段不同意
    type:id生成策略

对于IdType做出如下说明:
属性说明适用场景

AUTO

数据库自增主键适用于 MySQL、SQL Server 等支持自增主键的数据库

NONE

不使用任何主键生成策略通常用于主键已经存在的情况

ASSIGN_ID

全局唯一ID(默认基于Snowflake算法生成)适用于分布式系统,确保全局唯一性

ASSIGN_UUID

全局唯一UUID,生成32位的字符串适用于需要字符串主键的场景

INPUT

自定义输入主键值适用于某些特殊场景,如导入数据时需要手动指定主键

@TableFiled

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

importcom.baomidou.mybatisplus.annotation.TableField;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.FieldFill;importcom.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;importjava.util.Date;@TableName("user_info")publicclassUserInfo{@TableId(value ="id", type =IdType.AUTO)privateLong id;@TableField("username")privateString username;//此字段不参与查询@TableField("password", select=false)privateString password;@TableField("email")privateString email;//注意,此处应该编写相应的填充逻辑@TableField(value ="create_time", fill =FieldFill.INSERT)privateDate createTime;@TableField(value ="update_time", fill =FieldFill.UPDATE)privateDate updateTime;@TableField(exist =false)privateString tempField;// 临时字段,不在数据库中// Getters and SetterspublicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetUsername(){return username;}publicvoidsetUsername(String username){this.username = username;}publicStringgetPassword(){return password;}publicvoidsetPassword(String password){this.password = password;}publicStringgetEmail(){return email;}publicvoidsetEmail(String email){this.email = email;}publicDategetCreateTime(){return createTime;}publicvoidsetCreateTime(Date createTime){this.createTime = createTime;}publicDategetUpdateTime(){return updateTime;}publicvoidsetUpdateTime(Date updateTime){this.updateTime = updateTime;}publicStringgetTempField(){return tempField;}publicvoidsetTempField(String tempField){this.tempField = tempField;}}
属性说明:
    value:同上面注解一样,用于字段绑定,单个属性的时候可以不写
    select:在值为false的情况下用于设置不参查询,查询之后不会返回回来
    exist :用于类中的零时变量,数据库中没有该字段,只在java中使用
    fill:用于自动填充,比如create_time,update_time这一类,但需要编写相应的处理器

对应处理器代码:

importcom.baomidou.mybatisplus.core.handlers.MetaObjectHandler;importorg.apache.ibatis.reflection.MetaObject;importorg.springframework.stereotype.Component;importjava.util.Date;@ComponentpublicclassMyMetaObjectHandlerimplementsMetaObjectHandler{@OverridepublicvoidinsertFill(MetaObject metaObject){this.strictInsertFill(metaObject,"createTime",Date.class,newDate());this.strictInsertFill(metaObject,"updateTime",Date.class,newDate());}@OverridepublicvoidupdateFill(MetaObject metaObject){this.strictUpdateFill(metaObject,"updateTime",Date.class,newDate());}}

@TableLogic

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

importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableLogic;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.annotation.IdType;@TableName("user_info")publicclassUserInfo{@TableId(value ="id", type =IdType.AUTO)privateLong id;privateString username;privateString password;privateString email;@TableLogicprivateInteger isDeleted;// Getters and SetterspublicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetUsername(){return username;}publicvoidsetUsername(String username){this.username = username;}publicStringgetPassword(){return password;}publicvoidsetPassword(String password){this.password = password;}publicStringgetEmail(){return email;}publicvoidsetEmail(String email){this.email = email;}publicIntegergetIsDeleted(){return isDeleted;}publicvoidsetIsDeleted(Integer isDeleted){this.isDeleted = isDeleted;}}

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

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

@Version

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

importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableLogic;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.Version;@TableName("order_info")publicclassOrderInfo{@TableId(value ="id", type =IdType.AUTO)privateLong id;privateString orderNo;privateDouble amount;@VersionprivateInteger version;// Getters and SetterspublicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetOrderNo(){return orderNo;}publicvoidsetOrderNo(String orderNo){this.orderNo = orderNo;}publicDoublegetAmount(){return amount;}publicvoidsetAmount(Double amount){this.amount = amount;}publicIntegergetVersion(){return version;}publicvoidsetVersion(Integer version){this.version = version;}}

此处需加相关的拦截器:

importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassMyBatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptor interceptor =newMybatisPlusInterceptor();
        interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());return interceptor;}}
乐观锁的作用:
    乐观锁假设在并发环境中冲突较少,因此在操作数据时不立即获取锁,而是等到提交更新时才检查是否有其他事务修改过数据。如果发现数据已被修改,则更新失败,通常会抛出异常。
    特点:在提交更新时检查版本号,如果版本号匹配则更新成功,否则更新失败。
    效果:多个事务可以同时读取和处理数据,但在提交更新时会检查版本号,确保数据的一致性。

@Transient

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

@TableName("user")publicclassUser{@TableId(type =IdType.AUTO)privateLong id;privateString name;@TransientprivateString 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

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

importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;publicclassUserService{privateUserMapper userMapper;publicList<User>getUsersByConditions(){// 创建 QueryWrapper 对象QueryWrapper<User> queryWrapper =newQueryWrapper<>();// 添加查询条件
        queryWrapper.eq("name","张三").ge("age",18).orderByDesc("create_time");// 执行查询return userMapper.selectList(queryWrapper);}}

此处执行的sql语句:

SELECT*FROMuserWHERE name ='张三'AND age >=18ORDERBY create_time DESC;

UpdateWrapper

作用于更新设置条件。

importcom.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;publicclassUserService{privateUserMapper userMapper;publicintupdateUserById(){// 创建 UpdateWrapper 对象UpdateWrapper<User> updateWrapper =newUpdateWrapper<>();// 添加更新条件
        updateWrapper.eq("id",1);// 创建要更新的对象User user =newUser();
        user.setName("李四");// 执行更新return userMapper.update(user, updateWrapper);}}

此处执行的sql语句:

UPDATEuserSET name ='李四'WHERE id =1;

LambdaQueryWrapper

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

importcom.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;publicclassUserService{privateUserMapper userMapper;publicList<User>getUsersByLambdaConditions(){// 创建 LambdaQueryWrapper 对象LambdaQueryWrapper<User> lambdaQueryWrapper =newLambdaQueryWrapper<>();// 添加查询条件
        lambdaQueryWrapper.eq(User::getName,"张三").ge(User::getAge,18).orderByDesc(User::getCreateTime);// 执行查询return userMapper.selectList(lambdaQueryWrapper);}}

此处执行的sql语句:

SELECT*FROMuserWHERE name ='张三'AND age >=18ORDERBY create_time DESC;

LambdaUpdateWrapper

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

importcom.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;publicclassUserService{privateUserMapper userMapper;publicintupdateUserByIdWithLambda(){// 创建 LambdaUpdateWrapper 对象LambdaUpdateWrapper<User> lambdaUpdateWrapper =newLambdaUpdateWrapper<>();// 添加更新条件
        lambdaUpdateWrapper.eq(User::getId,1);// 创建要更新的对象User user =newUser();
        user.setName("李四");// 执行更新return userMapper.update(user, lambdaUpdateWrapper);}}

此处执行的sql语句:

UPDATEuserSET name ='李四'WHERE id =1;

Wrappers

用于更简便的条件设置

importcom.baomidou.mybatisplus.core.toolkit.Wrappers;publicclassUserService{privateUserMapper userMapper;publicList<User>getUsersByConditionsUsingWrappers(){// 创建 QueryWrapper 对象QueryWrapper<User> queryWrapper =Wrappers.<User>query().eq("name","张三").ge("age",18).orderByDesc("create_time");// 执行查询return userMapper.selectList(queryWrapper);}}

此处执行的sql语句:

SELECT*FROMuserWHERE name ='张三'AND age >=18ORDERBY create_time DESC;

3. 分页查询

1. 配置相应的拦截器

importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassMyBatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptor interceptor =newMybatisPlusInterceptor();
        interceptor.addInnerInterceptor(newPaginationInnerInterceptor());return interceptor;}}

2. 实现分页逻辑

importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.example.entity.User;importcom.example.mapper.UserMapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@ServicepublicclassUserService{@AutowiredprivateUserMapper userMapper;publicIPage<User>getUserPage(int current,int size){// 创建 Page 对象,传入当前页码和每页大小Page<User> page =newPage<>(current, size);// 创建 QueryWrapper 对象,添加查询条件QueryWrapper<User> queryWrapper =newQueryWrapper<>();
        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*FROMuserWHEREstatus=1ORDERBY create_time DESCLIMIT0,10;-- 当前页码为1,每页大小为10

四,结语

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


本文转载自: https://blog.csdn.net/dfd_123456789/article/details/143890263
版权归原作者 ! 恰同学少年! 所有, 如有侵权,请联系我们删除。

“springboot整合mybatis-plus【详细版】”的评论:

还没有评论