Mybatis-Plus学习笔记


title: Mybatis-Plus学习笔记
date: 2021-06-15 10:21:39

1.快速入门

官网文档也有入门介绍,如果有耐心和一定基础的小伙伴可以直接看官网

传送门

1.1、准备依赖

1.mybatis-plus依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
</dependency>

2.mysql驱动JDBC依赖

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
</dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

3.mysql驱动、JDBC和其他springboot依赖可以在IDEA中构建springboot项目时选择添加,这里就不加概述。

1.2、准备数据

创建user表

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

对应的数据

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

1.3、初始化工程

用IDEA初始化一个springboot项目

1.4、配置数据源

在resource目录下的配置文件里配置自己的数据源,建议在application.yml中配置

spring:
  datasource:
    username: root
    password: yourpassword
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=true&useUnicode=true&characterEcoding=utf-8
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

注意,我这里使用的mysql驱动是8+,在url中还需要配置时区,因为我在mysql配置文件中设置了默认时区,所以这里我没有配置时区。如果没有设置时区请加上serverTimezone=Asia/Shanghai.

另外,如果mysql驱动用的5+版本则应这样driver-class-name: com.mysql.jdbc.Driver配置驱动。

下面的mybatis-plus配置是开启日志,因为我没有导入其他的日志依赖,所以用的是自带的日志

1.5、创建User实体类

在pojo包下创建User对象,这里我引入了Lombok,用Lombok给对象创建构造器以及getter和setter

注意:若之前在IDEA中并未使用过Lombok,请先在IDEA中安装Lombok插件,Lombok

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

import java.util.Date;

@ToString //重写toString方法
@AllArgsConstructor //创建有参构造
@Data //创建getter和setter
@NoArgsConstructor //创建无参构造,用了创建有参构造的注解是默认没有无参构造的,需要手动创建
public class User {
    @TableId(type = IdType.AUTO) //主键注解,具体参考官方文档,注意使用AUTO创建表时请把主键设置为自增
    private long id;
    private String name;
    private int age;
    private String email;

    @TableField(fill = FieldFill.INSERT)//字段注解,具体参考官方文档
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

这里的@TableField后面会讲到,可以先暂时跳过

1.6、配置Mybatis-Plus

在main/src目录下创建mapper文件夹,在mapper文件夹下创建UserMapper这个接口,让这个接口继承BaseMapper ,注意泛型里面是要操作的实体类

package com.mybatis_plus.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mybatis_plus.pojo.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {
	//这里可以自己写sql,用法和mybatis一样。现在暂时不写,仅测试mybatis-plus的实现类
}

然后还要在springboot启动类上添加扫描注解,扫描这个mapper

注意:扫描包名千万别写错了,否则后面的代码全部白写

package com.mybatis_plus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.mybatis_plus.Mapper")
@SpringBootApplication
public class DemoApplication {

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

}

1.7、测试

在spring boot测试类里面编写测试类

1.7.1、查询

查询所有用户

package com.mybatis_plus;

import com.mybatis_plus.Mapper.UserMapper;
import com.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        List<User> users = userMapper.selectList(null);//这里的参数是一个条件构造器wrapper,这里先暂时不讲,后面会讲到
        users.forEach(System.out::println);
    }
}

运行测试,得到结果(因为开启了日志,所以在控制台看到了sql这个执行过程,因为我之前测试过,所以表里的数据有些不一样)

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7d4d65f5] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@564787547 wrapping com.mysql.cj.jdbc.ConnectionImpl@2804b13f] will not be managed by Spring
==>  Preparing: SELECT id,name,age,email,create_time,update_time FROM user
==> Parameters: 
<==    Columns: id, name, age, email, create_time, update_time
<==        Row: 1, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 2, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 3, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 4, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 5, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 6, jhon, 19, 1792243149@qq.com, null, 2021-06-15 13:35:22
<==        Row: 7, jhon, 19, 1792243149@qq.com, 2021-06-14 18:21:05, 2021-06-15 13:35:22
<==        Row: 8, jhon, 19, 1792243149@qq.com, 2021-06-14 18:24:40, 2021-06-15 13:35:22
<==      Total: 8
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7d4d65f5]
User(id=1, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=2, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=3, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=4, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=5, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=6, name=jhon, age=19, email=1792243149@qq.com, createTime=null, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=7, name=jhon, age=19, email=1792243149@qq.com, createTime=Mon Jun 14 18:21:05 CST 2021, updateTime=Tue Jun 15 13:35:22 CST 2021)
User(id=8, name=jhon, age=19, email=1792243149@qq.com, createTime=Mon Jun 14 18:24:40 CST 2021, updateTime=Tue Jun 15 13:35:22 CST 2021)

除此之外,除了selectList()方法以外,mybatis-plus还带有很多其他的查询方法方法,在此不一一演示

,读者可以自行探索

1.7.2、删除

这里我们准备把最后一条数据删除掉

Mybatis-Plus学习笔记

运行测试代码

package com.mybatis_plus;

import com.mybatis_plus.Mapper.UserMapper;
import com.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        System.out.println(userMapper.deleteById(8));
    }

}

运行代码,得到结果
Mybatis-Plus学习笔记

删除成功

另外,在mybatis-plus中还有逻辑删除的用法,逻辑删除的本质就是在表中有一个deleted字段,如果被删除该字段就为1,未被删除就是0.其本质还是一个update,只是配置逻辑删除后并不会被查询出来,而表中还是存在这条数据。

其他的操作我就不一一演示了,读者请自行查阅官方文档

2、条件构造器

我猜看到这里的小伙伴肯定想问那条件查询怎么办,嘿嘿,别急,下面就来演示如何在mybatis-plus中条件查询

2.1、通过map进行条件查询

比如我们要查询id=7的数据

package com.mybatis_plus;

import com.mybatis_plus.Mapper.UserMapper;
import com.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        Map<String,Object> map=new HashMap<>();
        map.put("id",7);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }

}

运行结果

Parameters: 7(Integer)
<==    Columns: id, name, age, email, create_time, update_time
<==        Row: 7, jhon, 19, 1792243149@qq.com, 2021-06-14 18:21:05, 2021-06-15 13:35:22
<==      Total: 1

如果有多个条件向map添加键值对就行,其他的删除,更新也是如此

2.2、通过条件构造器wrapper查询

编写测试代码

package com.mybatis_plus;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mybatis_plus.Mapper.UserMapper;
import com.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
    
@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        //创建一个条件构造器
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        // 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
        wrapper.isNotNull("email")
                .isNotNull("name")
                .ge("age",12);
        //传入条件构造器
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

}

3.自动填充

创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新!

在需要填充的字段上加上@TableFiled注解

 	@TableField(fill = FieldFill.INSERT)//在插入时更新数据
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新都插入数据
    private Date updateTime;

加完注解后还需要编写处理器来处理这个注解

package com.mybatis_plus.handler;

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

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {//继承MetaObjectHandler
    @Override //重写方法
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

编写测试代码

package com.mybatis_plus;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mybatis_plus.Mapper.UserMapper;
import com.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() {
        User user=new User();
        user.setName("jack");
        user.setEmail("123@qq.com");
        user.setAge(12);
        userMapper.insert(user);
    }

}

运行得到结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@33f349ae] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@501419057 wrapping com.mysql.cj.jdbc.ConnectionImpl@1cc93da4] will not be managed by Spring
==>  Preparing: INSERT INTO user ( name, age, email, create_time, update_time ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: jack(String), 12(Integer), 123@qq.com(String), 2021-06-15 14:59:18.162(Timestamp), 2021-06-15 14:59:18.162(Timestamp)
<==    Updates: 1

这里通过sql日志可知,我们创建对象时并没有设置时间,但是我们在插入数据时mybatis-plus自动为我们更新了时间

注意:测试自动填充时,请在User表里添加create_time、 update_time这两个字段

4、代码自动生成器

mybatis-plus可以通过代码自动生成代码

需要导入如下依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
</dependency>
<dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
</dependency>

编写代码

package com.mybatis_plus;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;

// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {
    public static void main(String[] args) {
        // 需要构建一个 代码自动生成器 对象
        AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath+"/src/main/java");//配置输出路径
        gc.setAuthor("Pymjl");//配置作者
        gc.setOpen(false);
        gc.setFileOverride(false); // 是否覆盖
        gc.setServiceName("%sService"); // 去Service的I前缀
        gc.setIdType(IdType.AUTO);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
//2、设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("Url");//配置数据库url
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");//用户
        dsc.setPassword("password");//密码
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);
//3、包的配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("blog");
        pc.setParent("com.Pymjl");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);
//4、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("user");//映射表名,这里也可以添加多个表
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true); // 自动lombok;
        strategy.setLogicDeleteFieldName("deleted");//配置逻辑删除
// 自动填充配置
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategy.setTableFillList(tableFills);
// 乐观锁
        strategy.setVersionFieldName("version");
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true); //   localhost:8080/hello_id_2
        mpg.setStrategy(strategy);
        mpg.execute(); //执行
    }
}

执行这个方法就会得到生成的代码了!

注意配置自己的数据库,另外,映射表名时注意对应自己表里面的字段。

本人也是第一次开始写博客,如果哪里有错,请联系我及时改正,谢谢大家的支持

上一篇:2021-05-28


下一篇:mybatis plus