MybatisPlus介绍与应用

发布于:2024-12-20 ⋅ 阅读:(9) ⋅ 点赞:(0)

简介

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MyBatis-Plus 官网:  MyBatis-Plus (baomidou.com)

Mybatis-plus特性

1、无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性

2、依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring

3、损耗小:启动即会自动注入基本CRUD,性能基本无损耗,直接面向对象操作

4、通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

5、多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题

6、支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作

7、支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )

8、内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询

9、内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询

10、内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

快速入门

1. 常见配置

1.1 引入MyBatisPlus相关依赖(因为要操作数据库,所以这里也引入了MySQL依赖)

MybatisPlus提供了starter,实现了自动Mybatis以及MybatisPlus的自动装配功能,坐标如下

 <!--MybatisPlus依赖-->
    <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
     </dependency>
 <!--数据库依赖-->
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
     </dependency>

1.2  创一个application.yaml,进行配置  

实体类+全局id类型

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po    # 实体类包所在路径
  global-config:
    db-config:
      id-type: auto   # 全局id类型为自增长

数据源

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root

1.3  扫描Mapper包  加在启动类上


 2. 定义Mapper层

为了简化单表增删查改,MybatisPlus提供了一个BaseMapper基础的接口,其中已经实现了单表的增删查改

  在Mapper接口上继承BaseMapper,这样就使用它里面所有的方法了

方法的使用: 

  1. 增删改方法

    • delete(Wrapper<T>): int:根据条件删除记录,返回受影响的行数。
    • deleteBatchIds(Collection<? extends Serializable>): int:根据主键集合批量删除记录,返回受影响的行数。
    • deleteById(Serializable): int:根据主键删除单条记录,返回受影响的行数。
    • deleteByMap(Map<String, Object>): int:根据 Map 中的条件删除记录,返回受影响的行数。
    • insert(T): int:插入一条记录,返回受影响的行数。
    • update(T, Wrapper<T>): int:根据条件更新记录,返回受影响的行数。
    • updateById(T): int:根据主键更新记录,返回受影响的行数。
  2. 查询方法

    • selectBatchIds(Collection<? extends Serializable>): List<T>:根据主键集合批量查询记录,返回记录列表。
    • selectById(Serializable): T:根据主键查询单条记录,返回记录对象。
    • selectByMap(Map<String, Object>): List<T>:根据 Map 中的条件查询记录,返回记录列表。
    • selectCount(Wrapper<T>): Long:根据条件查询记录数量,返回记录数量。
    • selectList(Wrapper<T>): List<T>:根据条件查询记录列表,返回记录列表。
    • selectMaps(Wrapper<T>): List<Map<String, Object>>:根据条件查询记录,返回 Map 列表,每个 Map 代表一条记录。
    • selectMapsPage(P, Wrapper<T>): P:分页查询记录,返回 Map 列表,每个 Map 代表一条记录。
    • selectObjs(Wrapper<T>): List<Object>:根据条件查询记录,返回对象列表。
    • selectOne(Wrapper<T>): T:根据条件查询单条记录,返回记录对象。
    • selectPage(P, Wrapper<T>): P:分页查询记录,返回记录列表
  3. 测试
  4. package com.itheima.mp.service;
    
    import com.itheima.mp.domain.po.User;
    import com.itheima.mp.domain.po.UserInfo;
    import com.itheima.mp.mapper.UserMapper;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.time.LocalDateTime;
    import java.util.Collection;
    import java.util.List;
    
    @SpringBootTest
    public class IUserMapperTest {
        @Autowired
        UserMapper iUserMapper;
    
        // 新增
        @Test
        public void testSaveUser() {
            User user = new User();
            //user.setId(5L);
            user.setUsername("如柴3号");
            user.setPassword("123");
            user.setPhone("18688990022");
            user.setBalance(200);
            user.setInfo(UserInfo.of(24, "英文老师", "female"));
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            iUserMapper.insert(user);
        }
    
        // 批量查询
        @Test
        void tesQuery() {
            Collection<User> userList = iUserMapper.selectBatchIds(List.of(1L, 2L, 4L));
            userList.forEach(System.out::println);
        }
    
    
        // 修改
        @Test
        void testUpdateById() {
            User user = new User();
            user.setId(5L);
            user.setBalance(20000);
            iUserMapper.updateById(user);
        }
    
        // 删除
        @Test
        void testDelete() {
            iUserMapper.deleteById(5L);
        }
    
    
    }


 3. 定义Service层和ServiceImpl实现类

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

  • save:新增

  • remove:删除

  • update:更新

  • get:查询单个结果

  • list:查询集合结果

  • count:计数

  • page:分页查询

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

 Service层

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> {

}

 ServiceImpl层

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;

@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
   
}

方法的使用:  

  • 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条数据

  • getBaseMapper:获取Service内的BaseMapper实现,某些时候需要直接调用Mapper内的自定义SQL时可以用这个方法获取到Mapper

  • listByIds:根据id批量查询

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

  • list():查询所有

  • count():统计所有数量

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

测试

package com.itheima.mp.service;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.po.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

@SpringBootTest
public class IUserServiceTest {
    @Autowired
    IUserService iUserService;

    @Test
    public void testSaveUser() {
        User user = new User();
        //user.setId(5L);
        user.setUsername("如柴3号");
        user.setPassword("123");
        user.setPhone("18688990022");
        user.setBalance(200);
        user.setInfo(UserInfo.of(24, "英文老师", "female"));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        iUserService.save(user);
    }

    @Test
    void tesQuery() {
        Collection<User> userList = iUserService.listByIds(List.of(1L, 2L, 4L));
        userList.forEach(System.out::println);
    }

    @Test
    void testPageQuery() {
        int pageNo = 1, pageSize = 3;
        Page<User> page = Page.of(pageNo, pageSize);
        // 排序 先按照金额 升序,再按照id 升序
        page.addOrder(new OrderItem("balance", true));
        page.addOrder(new OrderItem("id", true));

        Page<User> p = iUserService.page(page);

        long total = p.getTotal();
        System.out.println("总记录数:" + total);
        long pages = p.getPages();
        System.out.println("总页数:" + pages);
        List<User> users = p.getRecords();
        users.forEach(System.out::println);
    }


}


4.Controller层

直接将Mapper层或Service层注入即可使用,和Mybatis时没什么区别

package com.itheima.mp.controller;

import com.itheima.mp.domain.po.User;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping(value = "/users")
@Api(tags = "用户管理接口")
public class UserController {

    @Autowired
    IUserService userService;

    @GetMapping("/list")
    public List<User> getEricUserList() {
        List<User> list = userService.list();
        return list;
    }

}

5.常用注解

数据表字段带有_的可以自动映射到驼峰式命名的属性上(t_user——>tUser)。

Mapper 接口

  1. @Mapper
    • 作用:表明这是一个 MyBatis 的 Mapper 接口。该接口通常会继承BaseMapper<User>,这样就提供了基本的 CRUD(增删改查)操作方法。
  2. @Select
    • 作用:用于定义查询方法。通过在接口方法上添加这个注解,并在注解中编写 SQL 查询语句,就可以实现自定义的查询操作。
  3. @Insert
    • 作用:用于定义插入方法。在接口方法上添加此注解并编写 SQL 插入语句,即可实现数据插入操作。
  4. @Update
    • 作用:用于定义更新方法。在接口方法上添加这个注解并编写 SQL 更新语句,能够实现数据更新操作。
  5. @Delete
    • 作用:用于定义删除方法。在接口方法上添加此注解并编写 SQL 删除语句,可实现数据删除操作

实体类注解:

1.数据库名不同,在类上增加@TableName(“mp_address”)
2.主键ID的驼峰一般无法识别,在主键属性上增加@TableId
3.属性与字段名不相同,在属性上增加@TableField(“name”)

  1. @TableName("address")
    • 作用:指定实体类对应的数据库表名为address。当实体类名与表名不一致时,使用这个注解来建立映射关系。
  2. @TableId(type = IdType.AUTO)
    • 作用:指定id字段为主键,并且使用自增策略。在向数据库插入数据时,id字段的值会按照数据库的自增规则自动生成。
  3. @TableFieId("is_default")
    • 作用:指定实体类中的isDefault字段对应数据库中的is_default列。用于建立实体类字段与数据库表列之间的映射关系。