MyBatis-Plus学习笔记

使用SpringBoot创建工程并添加依赖pom.xml

版本:SpringBoot2.3 JDK1.8

<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义项目元数据,基于Maven POM 4.0.0模型 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- 指定项目版本格式 -->
    <modelVersion>4.0.0</modelVersion>
    <!-- 父项目定义,继承自Spring Boot的starter parent,简化配置 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <!-- 相对路径引用父POM,Maven会自动从仓库下载 -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <!-- 项目唯一标识,groupId、artifactId、version构成项目的坐标 -->
    <groupId>com.huang</groupId>
    <artifactId>mybatisplus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 项目名称 -->
    <name>mybatisplus</name>
    <!-- 项目描述 -->
    <description>Demo project for Spring Boot</description>
    <!-- 项目属性,如Java版本定义 -->
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <!-- 项目依赖定义 -->
    <dependencies>
        <!-- Spring Boot的Thymeleaf模板引擎支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Spring Boot的Web支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- MyBatis Plus支持,用于简化MyBatis的使用 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!-- MyBatis Plus代码生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!-- Velocity模板引擎,用于代码生成等场景 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <!-- MySQL数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- Lombok支持,简化JavaBean的开发 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Spring Boot的测试依赖,排除了Vintage引擎,以适应新的JUnit 5 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <!-- 项目构建配置 -->
    <build>
        <!-- 插件配置,如Spring Boot的Maven插件用于构建和打包 -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

配置application.yml文件

# 配置数据库连接信息
spring:
  datasource:
    # 数据库URL,指定数据库地址、端口、数据库名称以及相关连接参数
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    # 数据库驱动类名
    driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动
    # 数据库用户名
    username: root
    # 数据库密码
    password: 123456

# 配置Mybatis-Plus相关设置
mybatis-plus:
  configuration:
    # 设置日志实现类,此处启用标准输出日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #打印sql语句

连接数据库并创建实体类

实体内属性要与数据库中属性一致

创建mapper接口并继承BaseMapper<>

配置启动类并添加@MapperScan("mapper包所在位置")注解

启动测试类

package com.huang;

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

@SpringBootTest
class MybatisPlusApplicationTests {

    @Autowired
    private UserMapper userMapper;
    @Test
    /**
     * 当应用程序上下文加载时执行的方法。
     * 该方法演示了如何在上下文加载时调用数据访问对象(DAO)进行数据操作。
     * 它没有参数和返回值,主要用于初始化或测试时检查数据层是否正常工作。
     *
     * @see UserMapper#selectList(Object)
     */
    void contextLoads() {
        // 调用UserMapper的selectList方法,传入null作为查询条件,获取所有用户列表
        // 使用forEach方法遍历查询结果并打印每个用户的信息
        userMapper.selectList(null).forEach(System.out::println);
    }

}

常用注解

@TableName(vallue="表名")映射数据库表名

@Data
@TableName(value = "users")
public class Account {
    private Long uid;
    private String uname;
    private Integer uage;
}

@TableId(value = "与表中id名对应"  type=IdType.INPUT(默认为NONE))

设置主键映射 value映射主键字段名

type 设置主键类型,主键的生成策略,默认为NONE

描述
AUTO数据库自增

NONE

MP set主键,使用雪花算法实现

INPUT需要开发者手动赋值
AASIGN_IDMP分配ID,Long,Integer,String
ASSIGN_UUID分配UUID,String

INPUT 如果开发者没有手动赋值则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。

AUTO 默认就是数据库自增,开发者无需赋值。

ASSIGN_ID MP自动赋值,使用雪花算法

ASSIGN_UUID 主键的数据类型必须是String 自动生成UUID进行赋值


@TableField

映射非主键字段,value映射字段名

exist 表示是否为数据库字段 如果实体类中的成员变量在数据库中没有对应的字段,则可以使用exist、VO,DTO

select 表示是否查询该字段false

file 表示是否自动填充,将对象存入数据库的时候由MyBatis Plus 自动给某些字段赋值,create_time,update_tame

        1.给表添加create_time,update_time字段

        2.实体类中添加成员变量

 @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

        3.创建自动填充处理器

        

package com.huang.controller;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 自动填充数据实体的创建时间和更新时间。
 * 通过实现MetaObjectHandler接口,利用MyBatis-Plus的自动填充功能,
 * 在插入和更新数据时自动为createTime和updateTime字段赋值当前时间。
 */
@Component
public class MyMetaObjectControlletr implements MetaObjectHandler {

    /**
     * 在插入数据时自动填充createTime和updateTime字段。
     * @param metaObject MyBatis的元对象,用于反射字段并赋值。
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    /**
     * 在更新数据时自动填充updateTime字段。
     * @param metaObject MyBatis的元对象,用于反射字段并赋值。
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

        4.测试

 @Test
    void update(){
        Users users = userMapper.selectById(6);
        users.setTitle("小红");
        userMapper.updateById(users);
    }

@Version

标记乐观锁,通过version字段来保证数据的安全性,当修改数据的时候,会以version作为条件,当条件成立时才会修改成功

version = 1

线程1:update... set version = 2 where version =1

线程2:update... set version = 2 where version =1

1.数据库表添加version字段,默认值为1

2.实体类添加version成员变量,并添加@Version

3.注册一个配置类

package com.huang.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * MyBatisPlus配置类
 * 用于配置MyBatisPlus的乐观锁插件
 */
@Configuration
public class MyBatisPlusConfig {

    /**
     * 配置乐观锁插件
     *
     * @return 返回乐观锁插件实例
     * OptimisticLockerInterceptor用于处理乐观锁机制,
     * 它会在更新数据时自动检查数据是否被其他事务修改,
     * 从而保证数据的一致性。
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
}

@EnumValue

通过枚举注解,将数据库字段映射成实体类的枚举类型成员变量

1.通过注解


package com.huang.enums;

/**
 * 状态枚举类,用于定义系统中各种状态的枚举值。
 * 包含了上班和休息两种状态。
 */
public enum StatusEnum {
    /**
     * 上班状态枚举值。
     * code值为1,代表上班状态。
     * msg值为"上班",用于直观显示状态信息。
     */
    WORK(1,"上班"),
    /**
     * 休息状态枚举值。
     * code值为0,代表休息状态。
     * msg值为"休息",用于直观显示状态信息。
     */
    REST(0,"休息");

    /**
     * 构造方法,用于初始化枚举值。
     * @param code 状态代码,用于系统中标识状态的数字码。
     * @param msg 状态信息,用于直观显示状态的描述信息。
     */
    StatusEnum(Integer code, String msg){
        this.code = code;
        this.msg = msg;
    }

    /**
     * 注解@EnumValue用于MyBatis-Plus框架,将枚举的code值映射到数据库中。
     * 这样可以以数字形式存储枚举值,同时保持枚举的可读性。
     */
    @EnumValue
    private Integer code;
    private String msg;
}
private StatusEnum status;//变量名要与数据库中字段一致!
//或者使用注解
@TableField(value = "status")
private StatusEnum statusEnum;

application.yml

  type-enums-package: com.huang.enums #枚举包

2.实现接口

package com.huang.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.core.enums.IEnum;

public enum AgeEnum implements IEnum<Integer> {
    /**
     * 上一岁状态枚举值。
     * code值为1,代表一岁。
     * msg值为"一岁",用于直观显示状态信息。
     */
    ONE(1,"一岁"),

    TWO(2,"二岁"),

    THREE(3,"三岁");
    /**
     * 构造方法,用于初始化枚举值。
     * @param code 状态代码,用于系统中标识状态的数字码。
     * @param msg 状态信息,用于直观显示状态的描述信息。
     */
    AgeEnum(Integer code, String msg){
        this.code = code;
        this.msg = msg;
    }

    /**
     * 注解@EnumValue用于MyBatis-Plus框架,将枚举的code值映射到数据库中。
     * 这样可以以数字形式存储枚举值,同时保持枚举的可读性。
     */
    @EnumValue
    private Integer code;
    private String msg;

    @Override
    public Integer getValue() {
        return code;
    }
}

实体类类型改为AgeEnum类型

private Integer uage;
    ||    ||
private AgeEnum uage;

@TableLogic

映射逻辑删除(假删)

1.数据表添加delete字段

2.实体类添加注解即可

@TableLogic
    private Integer delete;

3.在application.yml中添加配置

  # 全局配置部分,用于定义应用范围内的通用设置
  global-config:
    # 数据库配置,用于定义与数据库交互的相关参数
    db-config:
      # 逻辑未删除的值,通常用于标记数据的状态,表示数据未被删除
      logic-not-delete-value: 0
      # 逻辑已删除的值,同样用于标记数据的状态,表示数据已被逻辑删除
      lo

CRUD(增,删,改,查)

查询

    /**
     * 测试选择用户的方法。
     * 该方法演示了使用QueryWrapper类构造查询条件,并执行查询。
     * 通过设置不同的查询条件,可以灵活地筛选用户数据。
     * 当前实现中,查询条件包括年龄的升序排序和用户ID大于3的筛选。
     */
    @Test
    void select(){
        // 初始化查询条件对象
        QueryWrapper wrapper = new QueryWrapper();
        
        // 设置查询条件:年龄大于2
        //wrapper.gt("uage",2);
        
        // 设置查询条件:用户名不等于"张三"
        //wrapper.ne("uname","张三");
        
        // 设置查询条件:用户名以"张"开头
        //wrapper.likeLeft("uname","张");
        
        // 设置查询条件:用户ID在查询结果中
        //wrapper.inSql("uid","select uid from users where uid < 10");
        
        // 设置查询结果按年龄升序排列
        wrapper.orderByAsc("uage");
        
        // 设置查询条件:拥有者的ID大于3
        wrapper.having("uid > 3");
        
        // 执行查询并打印结果
        userMapper.selectList(wrapper).forEach(System.out::println);
        // 通过ID查询用户信息并打印
        System.out.println(userMapper.selectById(3));

        // 批量查询指定ID的用户信息并打印
        userMapper.selectBatchIds(Arrays.asList(4,5,6)).forEach(System.out::println);
        // 使用Map查询条件来查询用户信息并打印
        // Map只能做等值判断,逻辑判断需要用Wrapper来处理
        Map<String,Object> map = new HashMap<>();
        map.put("uid",3);
        userMapper.selectByMap(map).forEach(System.out::println);

        // 分页查询用户信息
        ///分页查询 需要配置Bean
        Page<Users> page = new Page<>(1,3);
        Page<Users> result =  userMapper.selectPage(page,null);
        // 打印分页信息:页大小、总记录数
        System.out.println(result.getSize());
        System.out.println(result.getTotal());
        // 打印分页内的用户记录
        result.getRecords().forEach(System.out::println);

        // 分页查询用户信息(以Map形式)
        Page<Map<String,Object>> page1 = new Page<>(1,3);
        userMapper.selectMapsPage(page1,null).getRecords().forEach(System.out::println);

        // 查询所有用户信息(以Object形式)
        userMapper.selectObjs(null).forEach(System.out::println);

    }

自定义SQL(多表关联查询)

        1.VO

package com.huang.entity;

import lombok.Data;

@Data
public class OrderVO {
    private String productName;
    private Integer price;
    private Integer number;
    private Integer userId;
    private String uname;
}

        2.mapper自定义SQL语句

public interface UserMapper extends BaseMapper<Users> {
    @Select("select t.*,u.uname from users u ,tb_order t where u.uid=t.userid and uid=3;")
    List<OrderVO> orderList(Integer id);
}

添加

    /**
     * 测试保存用户信息的功能。
     * 该方法创建一个用户对象,设置用户标题(名字),然后通过用户映射器插入到数据库中。
     * 这里注释掉了一行代码,因为可能是未完成的代码或临时被禁用的功能。
     */
    @Test
    void save() {
        // 创建一个用户对象
        Users users = new Users();
        // 设置用户的标题(名字)
        users.setTitle("李四");
        // 设置用户年龄
        users.setUage(28);
        // 调用用户映射器的insert方法将用户信息插入数据库
        userMapper.insert(users);
    }

删除

    /**
     * 测试用户删除功能。
     * 本方法通过多种方式演示如何删除用户记录,包括单个删除、批量删除和条件删除。
     * 使用了编号为5、6的用户作为批量删除的示例,以及条件删除中年龄为4的用户。
     */
    @Test
    void delete(){
        // 删除用户ID为6的单个用户记录
        userMapper.deleteById(6);
        
        // 批量删除用户ID为5和6的用户记录
        userMapper.deleteBatchIds(Arrays.asList(5,6));
        
        // 创建查询包装器,设定条件为年龄等于4,然后删除满足条件的所有用户记录
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("uage",4);
        userMapper.delete(wrapper);
        
        // 使用Map指定条件,删除uid为2的用户记录
        Map<String,Object> map = new HashMap<>();
        map.put("uid",2);
        userMapper.deleteByMap(map);
    }

修改

    /**
     * 测试更新用户信息的方法。
     * 本方法旨在展示不同的更新策略,包括通过ID更新和通过条件更新。
     * 它演示了如何更新单个用户属性以及如何批量更新满足特定条件的用户属性。
     */
    @Test
    void update(){
        // 通过ID加载用户,准备进行更新操作
        //update... version = 3  where version = 2
        Users users = userMapper.selectById(6);
        // 设置用户标题为"一号",准备进行更新
        users.setTitle("一号");
        // 再次通过ID加载相同用户,演示如何处理并发更新场景
        //update... version = 3  where version = 2
        Users users1 = userMapper.selectById(6);
        // 将用户标题设置为"二号",与前一个更新操作冲突,用于测试并发控制机制
        users1.setTitle("二号");

        // 提交第一个用户的更新
        userMapper.updateById(users1);
        // 提交第二个用户的更新,此时可能因版本控制等原因导致更新失败
        userMapper.updateById(users);

        // 加载另一个用户,准备进行条件更新操作
        Users users2 = userMapper.selectById(1);
        // 设置用户标题为"小红"
        users2.setTitle("小红");
        // 创建查询包装器,用于指定更新条件
        QueryWrapper wrapper = new QueryWrapper();
        // 设置条件:更新年龄为2的用户
        wrapper.eq("uage",2);
        // 执行条件更新操作,更新所有满足条件的用户的标题
        userMapper.update(users2,wrapper);
    }

MyBatisPlus自动生成

根据数据表自动生成实体类,Mapper,Service,ServiceImpl,Controller

1.pom.xml导入MybatisPlus Generator

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>

Velocity(默认),Freemarker,Beetl

2、启动类

package com.huang;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class Main {
    public static void main(String[] args) {
        //创建generator对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("123456");
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        autoGenerator.setDataSource(dataSourceConfig);
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
        globalConfig.setOpen(false);
        globalConfig.setAuthor("Huang");
        autoGenerator.setGlobalConfig(globalConfig);
        //包信息
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.huang");
        globalConfig.setServiceName("%sService");
        packageConfig.setModuleName("generator");
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setMapper("mapper");
        packageConfig.setEntity("entity");
        autoGenerator.setPackageInfo(packageConfig);
        //配置策略
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setInclude("users","tb_order");//指定生成哪个表
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        autoGenerator.setStrategy(strategyConfig);
        //执行
        autoGenerator.execute();

    }
}
  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值