锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. Mybatis-Plus 详解

Mybatis-Plus 详解

0
  • 软件开发
  • 发布于 2024-07-23
  • 76 次阅读
黄健
黄健

原文链接 https://blog.csdn.net/m0_73829332/article/details/134856020

一、Mybatis-Plus 简介


(一)什么是 Mybatis-Plus


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


(二)Mybatis-Plus 特性


  1. 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。

  2. 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作。

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

  4. 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错。

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

  6. 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作。

  7. 支持自定义全局通用操作:支持全局通用方法注入(Write once, use anywhere)。

  8. 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper、Model、Service、Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用。

  9. 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询。

  10. 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库。

  11. 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。

  12. 内置全局拦截插件:提供全表 delete、update 操作智能分析阻断,也可自定义拦截规则,预防误操作。


二、代码生成器


(一)SpringBoot + MybatisPlus 工程搭建


  1. 创建一个初始化 SpringBoot 项目。

  2. pom.xml 添加依赖:


收起


xml

复制

<!--代码生成器-->
<dependency><!-- mybatis-plus 代码生成器 -->
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 模板引擎 -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
<!--阿里巴巴数据源-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.2</version>
</dependency>


(二)配置 application.yml(连接数据库)


收起


yaml

复制

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/gcxy_teach
    password: 123456
    username: root
    type: com.alibaba.druid.pool.DruidDataSource


(三)编码


在 com.gcxy.utils 包下创建 CodeGenerator 类(快速生成):


收起


java

复制

public class CodeGenerator {

    public static void main(String[] args){
        String url = "jdbc:mysql://localhost:3306/gcxy_teach";
        String username = "root";
        String password = "123456";
        String module = "";//表示项目的模块名称
        String outPath = System.getProperty("user.dir") + "/" + module + "/src/main/java";//文件输出路径
        String parent = "com.gcxy";//父包的名称
        String moduleName = "";//模块名称
        String entity = "entity";
        String mapper = "mapper";
        String service = "service";
        String serviceImpl = "service.Impl";
        String controller = "controller";
        String mapperXml = "mapper.xml";

        List<String> tables = new ArrayList<>();
        tables.add("account");
        tables.add("phone");
        tables.add("dep");
        tables.add("stu");


        FastAutoGenerator.create(url, username, password)
                //全局配置
               .globalConfig(builder -> {
                    builder.author("zxy") // 设置作者
//                           .enableSwagger() // 开启 swagger 模式
                           .fileOverride() // 覆盖已生成文件
                           .outputDir(outPath) // 指定输出目录
                           .disableOpenDir();// 生成后不打开目录
                })

                //包配置
               .packageConfig(builder -> {
                    builder.parent(parent) // 设置父包名
                           .moduleName(moduleName) // 设置父包模块名
                           .entity(entity)//设置实体类文件名
                           .mapper(mapper)
                           .service(service)
                           .serviceImpl(serviceImpl)
                           .controller(controller)
                           .xml(mapperXml);// 设置 mapperXml 生成路径
                })
                //策略配置
               .strategyConfig(builder -> {
                    builder.addInclude(tables) // 设置需要生成的表名
//                           .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                           .entityBuilder()// 开启生成实体类
                           .enableLombok()// 开启lombox 模型
                           .mapperBuilder()//开启生成 mapper
                           .superClass(BaseMapper.class)
                           .enableMapperAnnotation()// 开启 mapper 注解
                           .formatMapperFileName("%sMapper")//格式化 mapper 名称
                           .formatXmlFileName("%sMapper")//格式化 xml 名称
                           .serviceBuilder()//开启生成 service
                           .formatServiceFileName("%sService")//格式化 service 接口文件名称
                           .formatServiceImplFileName("%sServiceImpl")
                           .controllerBuilder()//开启生成 controller
                           .formatFileName("%sController")
                           .enableRestStyle();
                })
               .templateEngine(new VelocityTemplateEngine()) // 使用 Freemarker 引擎模板,默认的是 Velocity 引擎模板
               .execute();
    }
}


运行结果如下:


三、执行 SQL 的分析打印


(一)pom.xml 添加依赖


收起


xml

复制

<!--  p6spy-->
<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.1</version>
</dependency>


(二)配置 application.yml


收起


yaml

复制

spring:
  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://localhost:3306/gcxy_teach
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost:3306/gcxy_teach
    password: 123456
    username: root
    type: com.alibaba.druid.pool.DruidDataSource
  main:
    banner-mode: off  # 关闭 SpringBoot 启动图标(banner)


(三)配置 spy.properties


收起


properties

复制

#3.2.1 以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1 以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消 JDBC URL 前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有 error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢 SQL 记录
outagedetection=true
# 慢 SQL 记录标准 2 秒
outagedetectioninterval=2


四、主要注解及其作用


(一)@TableName


描述:表名注解,标识实体类对应的表。
使用位置:实体类。
示例:


收起


java

复制

@Data
@Getter
@Setter
@TableName("t_user")
//@Builder
public class User {
    private Long id;
    private String name;
    private Integer age;
    private Integer gender;
}


(二)@TableId


描述:主键注解。
使用位置:实体类主键字段。
示例:


收起


java

复制

@Data
@Getter
@Setter
@TableName("t_user")
//@Builder
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private Integer gender;
}


(三)@TableLogic


描述:表字段逻辑处理注解(逻辑删除)。

五、CURD 

(一) 增删改查

@SpringBootTest
class Mybatisplus001ApplicationTests {
 
//    @Autowired
//    private StuService stuService ;
//    @Test
//    void contextLoads() {
//        List<Stu> list = stuService.list();
//        for(Stu stu :list){
//            System.out.println(stu.toString());
//        }
//    }
 
    @Autowired
    private UserService1 userService1;
    @Autowired
    private UserMapper1 userMapper1;
 
    /**
     * 插入数据
     * 使用mapper层查询数据,在mapper中只封装了insert()方法
     */
    @Autowired
    private UserMapper userMapper;
 
    @Autowired
    private UsersMapper usersMapper;
 
    @Autowired
    private UserService userService ;
//    @Test
//    void test(){
//        User user = new User() ;
//        user.setName("小赵");
//        user.setAge(18);
//        user.setGender(1);
//        userMapper.insert(user);
//    }
 
    //    service层添加
//    @Test
//    void test1(){
//        User user = new User() ;
//        user.setName("张三");
//        user.setAge(19);
//        user.setGender(1);
//
//        //这service中封装的插入方法 save
//        boolean save = userService.save(user);
//        Long id = user.getId();
//        System.out.println("结果为:"+ save + "信息是"+ id +user);
//    }
 
    // 伪批量插入:saveBatch()
    @Test
    void test2(){
        List<User>  userList = new ArrayList<>();
        for(int i = 0 ; i <20 ; i ++){
            User user = new User() ;
            user.setName("欣欣"+i);
            user.setAge(18);
            user.setGender(1 + i);
            userList.add(user);
        }
        boolean isSuccess  = userService.saveBatch(userList);
        System.out.println("返回结果:"+ isSuccess );
    }
 
 
    // 批量保存或者更新
//    @Test
//    void test3(){
//        List<User> userList = new ArrayList<>();
//        for(int i = 3 ; i <10 ; i ++){
//            User user = new User() ;
//            user.setName("王五"+i);
//            user.setAge(20+i);
//            user.setGender(1 + i);
//            userList.add(user);
//        }
//        boolean isSuccess  = userService.saveBatch(userList , 1);
//        System.out.println("返回结果:"+ isSuccess );
//    }
 
    //Mapper层删除功能
    @Test
    void test4() {
        //根据主键id删除数据(直接传id)
        int count = userMapper.deleteById(14L);
        System.out.println("删除了:"+ count);
 
    }
 
//    @Test
//    void test5() {
//        //根据主键id删除(传实体类)
//        User user = new User();
//        user.setId(8L);
//        int count = userMapper.deleteById(user);
//        System.out.println("删除了:"+ count);
//
//    }
 
    @Test
    void test6() {
        //根据主键id批量删除数据
        List<Long> ids = new ArrayList<>();
        ids.add(12L);
        ids.add(13L);
//        delete from user where id in (12,13);
        userMapper.deleteBatchIds(ids);
 
    }
 
    @Test
    void test7() {
        //通过构造器Wrapper构造器删除
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("name","王五4");
        wrapper.eq("age","24");
 
//        delete from user where (name="xianmi" and age=11);
        userMapper.delete(wrapper);
        //lambda表达式
        userMapper.delete(new QueryWrapper<User>()
                .lambda()
                .eq(User::getName,"王五4")
                .eq(User::getAge,24)
        );
    }
 
    @Test
    void test8() {
        //使用map设置条件删除
        Map<String, Object> col = new HashMap<>();
        col.put("name","王五5");
        col.put("age",25);
 
        int count = userMapper.deleteByMap(col);
        System.out.println("删除了:" + count);
 
    }
 
    //更新数据
    //mapper层
//    @Test
//    void test9() {
//        User user = User.builder()
//                .name("刘六")
//                .id(7l)
//                .gender(2)
//                .build();
//        int count = userMapper.updateById(user);
//        System.out.println("更新了:" + count);
//
//    }
 
    //通过wrapper进行更新
//    @Test
//    void test10() {
//        User user = User.builder().name("哈哈").gender(3).build();
//        UpdateWrapper<User> userUpdateWrapper = new  UpdateWrapper<>();
//        userUpdateWrapper.eq("age",21);
//        int count = userMapper.update(user,userUpdateWrapper);
//
//    }
 
    //service层
    @Test
    void test11() {
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.set("name","嘻嘻");
        userUpdateWrapper.eq("id",5L).eq("age",5);
        userService.update(userUpdateWrapper);
 
    }
 
    //查询数据(mapper层)
    @Test
    void test12() {
        //12-1 根据 id 查询数据
//        User user = userMapper.selectById(5L);
//        System.out.println(user.toString());
 
        //12-2 通过构造wrapper条件查询一条数据
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        //设置查询字段;仅查询name id字段
//        queryWrapper.select("id","name");
//        //添加查询条件
//        queryWrapper.eq("id",6L);
//        User user1 = userMapper.selectOne(queryWrapper);
//        System.out.println(user1.toString());
 
        //12-3 根据 id 批量查询
        userMapper.selectBatchIds(Arrays.asList(5L,6L,7L));
 
        //12-4 通过Wrapper组装查询条件,查询全部数据
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //设置查询字段;仅查询name id字段
        queryWrapper.select("id","name");
        //添加查询条件
        queryWrapper.eq("age",18);
        List<User> users = userMapper.selectList(queryWrapper);//查询全部数据
 
        //12-5 根据columnMap设置查询条件
        Map<String,Object> colMap = new HashMap<>();
        colMap.put("name","哈哈");
        colMap.put("age",21);
//        select * from user where name="哈哈" and age="21";
        List<User> userList1 = userMapper.selectByMap(colMap);//使用map构造查询
 
        //12-6 根据Wrapper条件,查询记录总数
//        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
//        queryWrapper1.eq("name","哈哈").eq("age",21);
//        long count = userMapper.selectCount(queryWrapper1);//获取总量
    }
 
    //查询数据(service层)
    @Test
    void test13() {
        //13-1 根据id获取数据
        User user = userService.getById(6L);
 
        //13-2 通过wrapper条件查询一条数据,当结果出现多条数据会抛出异常
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name","哈哈").eq("id",6L);
        //select * from user where id=6 and name="哈哈";
        User user1 = userService.getOne(queryWrapper);
 
        //13-3 通过list开头的方法来查询多条数据
 
        //条件查询
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("name","哈哈").eq("id",6L);
        //select * from user where id=6 and name="哈哈";
        List<User> users = userService.list(queryWrapper1);
 
        //13-4 根据id列表查询数据
//        select * from user where id in(5,6);
        List<User> userList = userService.listByIds(Arrays.asList(5L,6L));
 
        //13-5 通过map构造查询条件
        Map<String,Object> colMap = new HashMap<>();
        colMap.put("name","哈哈");
        colMap.put("age",21);
//        select * from user where name="哈哈" and age="21";
        List<User> userList1 = userService.listByMap(colMap);//使用map构造查询
 
        //13-6 获取查询总数
        QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("name","哈哈").eq("age",21);
        userService.count(queryWrapper2);//获取总量
    }
}

(二)逻辑删除

配置application.yml

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

 测试代码如下:

    @Autowired
    private UsersService usersService ;
 
    @Autowired
    private UsersMapper usersMapper ;
 
    @Test
    void test18() {
        //添加数据
        Users users = Users.builder()
                .name("小赵")
                .age(18)
                .gender(11)
                .build();
        usersMapper.insert(users);
 
        //修改数据
//        Users users = Users.builder()
//                .id(1L)
//                .name("xixi")
//                .build();
//        usersMapper.updateById(users);
 
        //删除数据
//        usersMapper.deleteById(1L);
 
    }

相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.