mybatis-plus(保姆教学)

文章目录

  • mybatis-plus初始使用
    • 介绍
    • 原理
    • SpringBoot2.x整合MybatisPlus + Lombok
    • 创建bean
    • 创建mapper
    • 创建service
    • 创建controller
    • 单元测试和打印日志
    • BaseMapper介绍
    • QueryWrapper介绍
    • 查询API测试
  • mybatis-plus常见增删改查和分页
    • mybatis-plus常见注解
    • 新增、删除测试
    • 修改测试
    • QueryWrapper介绍
    • 分页插件

mybatis-plus初始使用

介绍

  • 官网 https://baomidou.com/
  • 是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生
  • 是怎么增强的呢?已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,类似JPA但优于JPA
  • 更多特性

损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

原理

MyBatis-Plus的原理是通过扩展MyBatis的功能来实现的。它通过自定义的Mapper接口和Mapper XML文件,使用MyBatis的注解和动态SQL等特性,来实现更加灵活和高效的数据库访问。

MyBatis-Plus的核心原理包括代码生成和SQL解析两个方面

  • 代码生成:MyBatis-Plus通过代码生成器自动生成实体类、Mapper接口和Mapper XML文件,可以大大减少手写代码的工作量。同时,MyBatis-Plus还支持自定义模板,可以根据项目规范生成符合要求的代码。
  • SQL解析:MyBatis-Plus通过解析Mapper接口的方法名和注解来生成对应的SQL语句。它支持常见的CRUD操作,如查询、插入、更新和删除等。同时,MyBatis-Plus还提供了丰富的查询条件构造器,可以灵活地构建复杂的查询条件

SpringBoot2.x整合MybatisPlus + Lombok

  • 添加依赖
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!--mybatis plus和springboot整合-->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.1</version>
  </dependency>
  • 配置数据库信息
server.port=8081
#==============================数据库相关配置========================================
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username =root
spring.datasource.password =123456
  • 工程结构初始化
    mybatis-plus(保姆教学)_第1张图片

  • 创建接口返回统一对象

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor //会生成一个包含所有变量
@NoArgsConstructor //生成一个无参数的构造方法
public class JsonData {
    /**
     * 状态码 0 表示成功,1表示处理中,-1表示失败
     */
    private Integer code;
    /**
     * 数据
     */
    private Object data;
    /**
     * 描述
     */
    private String msg;

    // 成功,传入数据
    public static JsonData buildSuccess() {
        return new JsonData(0, null, null);
    }

    // 成功,传入数据
    public static JsonData buildSuccess(Object data) {
        return new JsonData(0, data, null);
    }

    // 失败,传入描述信息
    public static JsonData buildError(String msg) {
        return new JsonData(-1, null, msg);
    }

    // 失败,传入描述信息,状态码
    public static JsonData buildError(String msg, Integer code) {
        return new JsonData(code, null, msg);
    }

}

创建bean

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("banner") // 指定数据库的表名,如果类名和数据库表名不一致需要指定
public class BannerDO {

    private Integer id;
    private String img;
    private String url;
    private Integer weight;

}

创建mapper

/**
 * 创建mapper接口,继承BaseMapper,并指定bean
 */
public interface BannerMapper extends BaseMapper<BannerDO> {
}

创建service

创建接口

import java.util.List;

public interface BannerService {

    public List<BannerDO> list();

}

创建接口实现类

import java.util.List;

@Service
public class BannerServiceImpl implements BannerService {

    @Autowired
    private BannerMapper bannerMapper;

    @Override
    public List<BannerDO> list() {
        //查询全部
        List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
        return list;
    }
}

创建controller

@RestController
@RequestMapping("/api/banner/v1")
public class BannerController {

    @Autowired
    private BannerService bannerService;
    
    @RequestMapping("list")
    public JsonData list(){
        return JsonData.buildSuccess(bannerService.list());
    }
}

单元测试和打印日志

添加依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
</dependency>

添加单元测试类

@SpringBootTest(classes = MybatisplusLombokSwagger3Application.class)
@Slf4j
class BannerTests {

    @Autowired
    private BannerService bannerService;

    @Test
    public void testBannerList(){
        List<BannerDO> list = bannerService.list();
        log.info("轮播图列表:{}",list);
    }

}

添加打印sql的配置

#配置mybatis plus打印sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

BaseMapper介绍

Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能

BaseMapper是MyBatis-Plus提供的一个通用Mapper接口,可以用于快速开发数据访问层。它提供了常见的CRUD操作方法,如插入、修改、删除和查询等,适用于各种实体类的操作。

方法很多:记住常用的几个就行。可以查看源码的说明,如下

/**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * 

这个 Mapper 支持 id 泛型

* * @author hubin * @since 2016-01-23 */
public interface BaseMapper<T> extends Mapper<T> { /** * 插入一条记录 * * @param entity 实体对象 */ int insert(T entity); /** * 根据 ID 删除 * * @param id 主键ID */ int deleteById(Serializable id); /** * 根据 columnMap 条件,删除记录 * * @param columnMap 表字段 map 对象 */ int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); /** * 根据 entity 条件,删除记录 * * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) */ int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 删除(根据ID 批量删除) * * @param idList 主键ID列表(不能为 null 以及 empty) */ int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); /** * 根据 ID 修改 * * @param entity 实体对象 */ int updateById(@Param(Constants.ENTITY) T entity); /** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 (set 条件值,可以为 null) * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) */ int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); /** * 根据 ID 查询 * * @param id 主键ID */ T selectById(Serializable id); /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表(不能为 null 以及 empty) */ List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); /** * 查询(根据 columnMap 条件) * * @param columnMap 表字段 map 对象 */ List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); /** * 根据 entity 条件,查询一条记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 entity 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录 *

注意: 只返回第一个字段的值

* * @param queryWrapper 实体对象封装操作类(可以为 null) */
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 entity 条件,查询全部记录(并翻页) * * @param page 分页查询条件(可以为 RowBounds.DEFAULT) * @param queryWrapper 实体对象封装操作类(可以为 null) */ <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询全部记录(并翻页) * * @param page 分页查询条件 * @param queryWrapper 实体对象封装操作类 */ <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); }

QueryWrapper介绍

QueryWrapper是MyBatis Plus中非常方便的查询封装类,可以大大简化查询语句的编写,提高开发效率。可以封装多数查询条件,泛型指定返回的实体类

List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());

查询API测试

在测试类中测试这些API

@SpringBootTest
@Slf4j
public class BaseMapperTest {

    @Autowired
    private BannerMapper bannerMapper;


    /**
     * 主键id查找
     */
    @Test
    public void selectByIdTest(){
        BannerDO bannerDO = bannerMapper.selectById(1);
        log.info("bannerDO:{}",bannerDO);
    }

    /**
     * 主键批量查找
     */
    @Test
    public void selectBatchIdsTest(){
        List<BannerDO> list  = bannerMapper.selectBatchIds(Arrays.asList("1","2"));
        log.info("list:{}",list);
    }

    /**
     * 查询一条
     */
    @Test
    public void selectOneTest(){
        BannerDO bannerDO = bannerMapper.selectOne(new QueryWrapper<BannerDO>().eq("id",1));
        log.info("bannerDO:{}",bannerDO);
    }

    /**
     * 查询条数
     */
    @Test
    public void selectCountTest(){
        int count = bannerMapper.selectCount(null);
        log.info("bannerDO:{}",count);
    }
}

mybatis-plus常见增删改查和分页

mybatis-plus常见注解

  • @TableName 用于定义表名
  • @TableId 用于定义表的主键
    • 属性
      • value 用于定义主键字段名
      • type 用于定义主键类型(主键策略 IdType),具体策略如下:
IdType.AUTO          主键自增,系统分配,不需要手动输入
IdType.NONE          未设置主键
IdType.INPUT         需要自己输入 主键值
IdType.ASSIGN_ID     系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)
IdType.ASSIGN_UUID   系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)
  • 统一配置主键策略
  • 配置全局默认主键类型,实体类就不用加 @TableId(value = “id”, type = IdType.AUTO)
mybatis-plus.global-config.db-config.id-type=auto
  • @TableField 用于定义表的非主键字段
    • 属性
      • value 用于定义非主键字段名,用于别名匹配,假如java对象属性和数据库属性不一样
      • exist 用于指明是否为数据表的字段, true 表示是,false 为不是,假如某个java属性在数据库没对应的字段则要标记为faslse
      • fill 用于指定字段填充策略(FieldFill,用的不多)
字段填充策略:一般用于填充 创建时间、修改时间等字段
     FieldFill.DEFAULT         默认不填充
     FieldFill.INSERT          插入时填充
     FieldFill.UPDATE          更新时填充
     FieldFill.INSERT_UPDATE   插入、更新时填充。

新增、删除测试

/**
     * 新增
     */
    @Test
    public void insertTest(){
        BannerDO bannerDO = new BannerDO();
        bannerDO.setImg("img");
        bannerDO.setUrl("URL");

        int count = bannerMapper.insert(bannerDO);
        log.info("bannerDO:{}",count);
    }

    @Test
    public void deleteByIdTest(){
        int rows = bannerMapper.deleteById(4);
        log.info("rows:{}",rows);
    }

    /**
     * 通用删除操作 deleteByMap  map要写列名条件 不能是实体属性名
     */
    @Test
    public void commonDeleteByMapTest() {
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("weight",12);
        columnMap.put("url","bbb");
        int result=bannerMapper.deleteByMap(columnMap);
        System.out.println("*******************"+result);
    }

修改测试

  /**
     * 根据主键更新
     */
    @Test
    public void updateByIdTest() {
        BannerDO bannerDO = new BannerDO();
        bannerDO.setId(2);
        bannerDO.setImg("jjjjjj");
        //空字段不会更新
        bannerMapper.updateById(bannerDO);
    }

    /**
     * 条件更新
     */
    @Test
    public void updateTest() {
        BannerDO bannerDO = new BannerDO();
        bannerDO.setImg("iiiii");
        //空字段不会更新
        bannerMapper.update(bannerDO,new QueryWrapper<BannerDO>().eq("id","1"));
    }

    /**
     * 使用updateWrapper更新
     */
    @Test
    public void updateWrapperTest() {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        //设置要更新的字段和值,key是db的属性名称
        updateWrapper.set("img","uuuu");
        //条件
        updateWrapper.eq("id",1);
        bannerMapper.update(null,updateWrapper);
    }

QueryWrapper介绍

  • QueryWrapper介绍
    • 可以封装sql对象,包括where条件,order by排序,select哪些字段等等
    • 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
  • 核心API
    • eq:判断两个值是否相等,返回一个QueryWrapper对象。
    • ne:判断两个值是否不相等,返回一个QueryWrapper对象。
    • gt:判断第一个值是否大于第二个值,返回一个QueryWrapper对象。
    • lt:判断第一个值是否小于第二个值,返回一个QueryWrapper对象。
    • ge:判断第一个值是否大于等于第二个值,返回一个QueryWrapper对象。
    • le:判断第一个值是否小于等于第二个值,返回一个QueryWrapper对象。
    • like:模糊查询,返回一个QueryWrapper对象。
    • notLike:非模糊查询,返回一个QueryWrapper对象。
    • in:判断某个字段的值是否在指定范围内,返回一个QueryWrapper对象。
    • notIn:判断某个字段的值是否不在指定范围内,返回一个QueryWrapper对象。
    • between:判断某个字段的值是否在指定范围内,返回一个QueryWrapper对象。
    • notBetween:判断某个字段的值是否不在指定范围内,返回一个QueryWrapper对象。
    • isNull:判断某个字段的值是否为空,返回一个QueryWrapper对象。
    • isNotNull:判断某个字段的值是否不为空,返回一个QueryWrapper对象。
    • orderByAsc:按升序排序,返回一个QueryWrapper对象。
    • orderByDesc:按降序排序,返回一个QueryWrapper对象。

分页插件

配置分页插件

@Configuration
public class MybatisPlusPageConfig {

    /**
     * 新的分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

测试分页代码

 /***
     * 测试分页
     */
    @Test
    public void testPage() {
        QueryWrapper<BannerDO> wrapper = new QueryWrapper<>();
        wrapper.eq("weight",4);
        //第1页,每页2条
        Page<BannerDO> page = new Page<>(1, 2);
        IPage<BannerDO> bannerDOIPage = bannerMapper.selectPage(page, wrapper);
        System.out.println("总条数"+bannerDOIPage.getTotal());
        System.out.println("总页数"+bannerDOIPage.getPages());
        //获取当前数据
        System.out.println(bannerDOIPage.getRecords().toString());
    }

你可能感兴趣的:(1024程序员节,mybatis-plus)