mybatis-plus学习笔记

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: mybatis-plus学习笔记

@[TOC]

1 简介

MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatis-Plus提供了通用的mapper和service,可以在不编写任何SQL语句的情况下,快速的实现对单表的CRUD、批量、逻辑删除、分页等操作。

2 初始化项目

2.1引入pom

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

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

        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- 简化实体类开发 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

2.2 引入lombok插件

在这里插入图片描述

2.3 配置信息

spring:
# 配置数据源信息
  datasource:
# 配置数据源类型(spring默认的数据源)
    type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库信息(配置驱动类,版本为8)
    driver-class-name: com.mysql.cj.jdbc.Driver
#mysql8版本的写法
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
    username: root
    password: yuan159951.

# mysql5版本的写法
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false

2.4 创建实体类

import lombok.Data;

@Data //lombok注解
public class User {
   
   
        private Long id;
        private String name;
        private Integer age;
        private String email;   
}

2.5 创建mapper

import com.yunfeng.mybatisplus.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface UserMapper extends BaseMapper<User> {
   
   
}

2.6 配置注解MapperScan

@SpringBootApplication
//扫描mapper接口所在的包
@MapperScan("com.yunfeng.mybatisplus.mapper")
public class MybatisplusApplication {
   
   

    public static void main(String[] args) {
   
   
        SpringApplication.run(MybatisplusApplication.class, args);
    }

}

2.7 编写测试类

import com.yunfeng.mybatisplus.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class MybatisPlusTest {
   
   

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectList(){
   
   
        //selectList()根据MP内置的条件构造器查询一个list集合,null表示没有条件,即查询所有
        userMapper.selectList(null).forEach(System.out::println);
    }
}

2.8 配置MyBatis日志

# 配置MyBatis日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3 测试基本的CRUD

3.1 新增

@Test
    public void testInsert(){
   
   
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        user.setEmail("302976975@qq.com");
        int row = userMapper.insert(user);
        System.out.println("row = " + row);
        System.out.println(user.getId());
    }

3.2 查询

    @Test
    public void testSelectById(){
   
   
//        User user = userMapper.selectById(1L);
//        System.out.println(user);
//        List<Long> longs = Arrays.asList(1l, 2l, 3l);
//        List<User> users = userMapper.selectBatchIds(longs);
//        System.out.println("users = " + users);
//        Map<String,Object> map = new HashMap<>();
//        map.put("name","jack");
//        map.put("age",20);
//        List<User> users = userMapper.selectByMap(map);
//        System.out.println("users = " + users);
        List<User> users = userMapper.selectList(null);
        System.out.println("users = " + users);
    }

3.3 修改

@Test
    public void testUpdateById(){
   
   
        User user = new User();
        user.setId(4L);
        user.setName("李四");
        int result = userMapper.updateById(user);
        System.out.println("受影响行数:"+result);
    }

3.4 删除

    @Test
    public void testDeleteById(){
   
   
//        int result = userMapper.deleteById(1595594324846141442L);
//        System.out.println("受影响行数:"+result);
//        Map<String,Object> map = new HashMap<>();
//        map.put("name","张三");
//        map.put("age",18);
//        userMapper.deleteByMap(map);
        List<Long> longs = Arrays.asList(1l, 2l, 3l);
        int rows = userMapper.deleteBatchIds(longs);
        System.out.println("rows = " + rows);
    }

4 自定义动态sql

  • 默认位置可以不写!
    在这里插入图片描述
  • 新增mybatis模板文件
    在这里插入图片描述
  • 官方模板文件
    ```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    

* UserMapper接口代码
```java
Map<String,Object> selectMapById(Long id);
  • UserMapper.xml代码
    <select id="selectMapById" resultType="map">
          select * from user where id = #{id}
      </select>
    
  • 测试类
    Map<String, Object> map = userMapper.selectMapById(1l);
          System.out.println("map = " + map);
    

    5 Service 层使用mybatis-plus方法

    5.1 service层代码

  • 接口
    public interface UserService  extends IService<User> {
         
         
    }
    
  • 实现类
    ```java
    @Service
    public class UserServiceImpl extends ServiceImpl implements UserService{

}

## 5.2 测试查询总记录数
```java
@Test
    public void testGetCount(){
        long count = userService.count();
        System.out.println("count = " + count);
    }

5.3 测试批量新增

    @Test
    public void testSaveBatch(){
   
   
// SQL长度有限制,海量数据插入单条SQL无法实行,
// 因此MP将批量插入放在了通用Service中实现,而不是通用Mapper
        ArrayList<User> users = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
   
   
            User user = new User();
            user.setName("ybc" + i);
            user.setAge(20 + i);
            users.add(user);
        }
//SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
        boolean bool = userService.saveBatch(users);
        System.out.println("bool = " + bool);
    }

6 id不是用雪花算法,自己定义

@Data //lombok注解
@TableName("user")
public class User {
   
   

//IdType.AUTO就是自增
        @TableId(value = "id",type = IdType.AUTO)
        private Long id;
        @TableField("name")
        private String name;
        private Integer age;
        private String email;
        //逻辑删除
        @TableLogic
        private Integer isDeleted;
}
  • 配置方法
    # 配置MyBatis
    mybatis-plus:
    configuration:
      # 日志信息
      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    global-config:
      db-config:
        # 配置MyBatis-Plus的主键策略
        id-type: auto
      # 配置MyBatis-Plus操作表的默认前缀
    #      table-prefix:
    # 配置类型别名所对应的包
    type-aliases-package: com.yunfeng.mybatisplus.pojo
    # 配置扫描通用枚举
    type-enums-package: com.yunfeng.mybatisplus.enums
    

    7 雪花算法

    雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的
    主键的有序性。
  • 和时间有关。
  • ①核心思想:
    长度共64bit(一个long型)。
    首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负
    数是1,所以id一般是正数,最高位是0。
    41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。
    10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。
    12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。
  • ②优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。
    在这里插入图片描述

    8 wapper条件构造器

    8.1 QueryWrapper(查询、删除、修改)

  • 查询
      @Test
      public void test01(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.like("name","a")
                  .between("age",20,30)
                  .isNotNull("email");
          List<User> users = userMapper.selectList(queryWrapper);
          users.forEach(System.out::println);
      }
    
  • 查询排序
     @Test
     public void test02(){
         
         
         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
         queryWrapper.orderByDesc("age")
                 .orderByAsc("id");
         List<User> users = userMapper.selectList(queryWrapper);
         users.forEach(System.out::println);
     }
    
  • 删除
      @Test
      public void test03(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.isNull("email");
          int row = userMapper.delete(queryWrapper);
          System.out.println("row = " + row);
      }
    
  • 条件修改
      @Test
      public void test04(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.gt("age",20)
                  .like("name","a")
                  .or()
                  .isNull("email");
          User user = new User();
          user.setName("张三");
          int rows = userMapper.update(user, queryWrapper);
          System.out.println("rows = " + rows);
      }
    
  • lambda中的条件优先执行
    @Test
      public void test05(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          //lambda中的条件优先执行
          queryWrapper.like("name","a")
                  .and(i -> i.gt("age",20).or().isNull("email"));
          User user = new User();
          user.setName("李四");
          int rows = userMapper.update(user, queryWrapper);
          System.out.println("rows = " + rows);
      }
    
  • 查询部分字段
    //查询部分字段
      @Test
      public void test06(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.select("name","age");
          List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
          maps.forEach(System.out::println);
      }
    
  • 子查询
    // 子查询
      @Test
      public void test07(){
         
         
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.inSql("age","select age from user where age < 20");
          List<User> users = userMapper.selectList(queryWrapper);
          users.forEach(System.out::println);
      }
    

    8.2 UpdateWrapper

  • UpdateWrapper修改不需要new实体类
    @Test
      public void test08(){
         
         
          UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
          updateWrapper.like("name","a")
                  .and( i -> i.gt("age",20).or().isNull("email"));
          updateWrapper.set("name","王五");
          int rows = userMapper.update(null, updateWrapper);
          System.out.println("rows = " + rows);
      }
    
  • 条件组装
    @Test
      public void test10(){
         
         
          String name = "";
          Integer ageBegin = 20;
          Integer ageEnd = 30;
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.like(StringUtils.isNotBlank(name),"name",name)
                  .ge(ageBegin != null,"age",ageBegin)
                  .gt(ageEnd != null,"age",ageEnd);
          List<User> users = userMapper.selectList(queryWrapper);
          users.forEach(System.out::println);
      }
    

    8.3 LambdaQueryWrapper

    @Test
      public void test11(){
         
         
          String name = "";
          Integer ageBegin = 20;
          Integer ageEnd = 30;
          LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
          queryWrapper.like(StringUtils.isNotBlank(name),User::getName,name)
                  .ge(ageBegin != null,User::getAge,ageBegin)
                  .gt(ageEnd != null,User::getAge,ageEnd);
          List<User> users = userMapper.selectList(queryWrapper);
          users.forEach(System.out::println);
      }
    

    8.4 LambdaUpdateWrapper

    @Test
      public void test12(){
         
         
          LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
          updateWrapper.like(User::getName,"a")
                  .and( i -> i.gt(User::getAge,20).or().isNull(User::getEmail));
          updateWrapper.set(User::getName,"赵六");
          int rows = userMapper.update(null, updateWrapper);
          System.out.println("rows = " + rows);
      }
    

    9 插件

    9.1 分页插件

  • 写配置类
    ```java
    import com.baomidou.mybatisplus.annotation.DbType;
    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
//扫描mapper接口所在的包
@MapperScan("com.atguigu.mybatisplus.mapper")
public class MyBatisPlusConfig {

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

}

* 测试
```java
@Test
    public void testPage(){
        Page<User> page = new Page<>(2,3);
        userMapper.selectPage(page, null);
        System.out.println("page = " + page);
    }

9.2 乐观锁和悲观锁

  • 添加@Version注解
    @Data
    public class Product {
         
         
    private Long id;
    private String name;
    private Integer price;
    @Version
    private Integer version;
    }
    
  • 添加插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
         
         
      MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
      //添加分页插件
      interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
      //添加乐观锁插件
      interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
      return interceptor;
    }
    

    10 代码生成器

  • 官网地址:https://baomidou.com/pages/779a6e/#%E5%AE%89%E8%A3%85

    10.1引入以依赖

    <!-- 代码生成器 -->
          <dependency>
              <groupId>com.baomidou</groupId>
              <artifactId>mybatis-plus-generator</artifactId>
              <version>3.5.1</version>
          </dependency>
    
          <dependency>
              <groupId>org.freemarker</groupId>
              <artifactId>freemarker</artifactId>
              <version>2.3.31</version>
          </dependency>
    

    10.2 生成代码

    public static void main(String[] args) {
         
         
          FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&userSSL=false", "root", "yuan159951.")
                  .globalConfig(builder -> {
         
         
                      builder.author("logic") // 设置作者
                              //.enableSwagger() // 开启 swagger 模式
                              .fileOverride() // 覆盖已生成文件
                              .outputDir("D://mybatis_plus"); // 指定输出目录
                  })
                  .packageConfig(builder -> {
         
         
                               builder.parent("com.yunfeng") // 设置父包名
                                      .moduleName("mybatisplus") // 设置父包模块名
                                      .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://mybatis_plus")); // 设置mapperXml生成路径
                  })
                  .strategyConfig(builder -> {
         
         
                              builder.addInclude("user") // 设置需要生成的表名
                                     .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                  })
                  .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker 引擎模板,默认的是Velocity引擎模板
                  .execute();
      }
    
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2天前
|
SQL Java 数据库连接
MyBatis-Plus学习笔记(1):环境搭建以及基本的CRUD操作
MyBatis-Plus学习笔记(1):环境搭建以及基本的CRUD操作
|
9月前
|
SQL Java 数据库连接
|
1月前
|
SQL Java 关系型数据库
MyBatisPlus学习笔记(SpringBoot版)
MyBatisPlus学习笔记(SpringBoot版)
223 0
|
10月前
|
XML Java 数据库连接
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
42 0
|
9月前
|
SQL Java 关系型数据库
|
9月前
|
SQL Java 关系型数据库
|
9月前
|
SQL Java 关系型数据库
|
10月前
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
26 0
|
10月前
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
37 0