Mybatis-plus的长篇大论,–入门级
介绍
MyBatis-Plus(简称 MP)是基于 MyBatis 的一个便捷增强工具,在 MyBatis 的基础上,简化了开发流程,提高了开发效率。MP 提供了常见的增删改查功能,还有分页、逻辑删除、乐观锁、自动填充、性能分析等实用功能,避免了开发人员需要写重复的 SQL 代码,从而减少代码量、节省开发时间、提高代码可维护性。MP 的目标是成为 MyBatis 的最佳搭档。
官网
简介 | MyBatis-Plus (baomidou.com)
[个人仓库](city-mybatis-plus: 学习mybatis (gitee.com))
别的不多,直接上上~~~项目
搭建SpringBoot 2.5.5 搭建的时候注意版本,太高的话容易出问题且不好解决,
第一步搭建一个数据库
你可以有一个用户表,也可以自己建一个,有几个列就可以了,最好再加点数据。
/*
Navicat Premium Data Transfer
Source Server : MySQL
Source Server Type : MySQL
Source Server Version : 80024
Source Host : localhost:3306
Source Schema : mycity
Target Server Type : MySQL
Target Server Version : 80024
File Encoding : 65001
Date: 16/06/2023 11:19:25
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for mybatis
-- ----------------------------
DROP TABLE IF EXISTS `mybatis`;
CREATE TABLE `mybatis` (
`id` bigint NOT NULL COMMENT '主键ID',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',
`age` int NULL DEFAULT NULL COMMENT '年龄',
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of mybatis
-- ----------------------------
INSERT INTO `mybatis` VALUES (1, 'Jone', 18, 'test1@baomidou.com');
INSERT INTO `mybatis` VALUES (2, 'Jack', 20, 'test2@baomidou.com');
INSERT INTO `mybatis` VALUES (3, 'Tom', 28, 'test3@baomidou.com');
INSERT INTO `mybatis` VALUES (4, 'Sandy', 21, 'test4@baomidou.com');
INSERT INTO `mybatis` VALUES (5, 'Billie', 24, 'test5@baomidou.com');
INSERT INTO `mybatis` VALUES (1669524881004863490, 'Alice', 22, '2222@qq.com');
SET FOREIGN_KEY_CHECKS = 1;
搭建idea项目
这个图片太麻烦
简单说一下,
- boot 2.5.5
- 数据库驱动
- lombok
就这几个
maven依赖:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.city</groupId>
<artifactId>city-mybatis-plus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>city-mybatis-plus</name>
<description>city-mybatis-plus</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
</dependencies>
</project>
不要全部复制粘贴,容易出问题,看看要啥
项目初始化
- 先跑,确定没问题
- 创建实体类,在plus里包名叫domain,没啥区别
- 创建接口dao或者Mapper
看代码
package com.city.citymybatisplus.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
*
* @TableName mybatis
*/
@TableName(value ="mybatis")
@Data
public class Mybatis implements Serializable {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 邮箱
*/
private String email;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
package com.city.citymybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.city.citymybatisplus.domain.Mybatis;
public interface MybatisMapper extends BaseMapper<Mybatis> {
}
最明显的区别就是不用大量的代码去写接口方法
只需继承基础类 BaseMapper<>
其实现在就完成了一个简单的项目入门,已经可以对数据库进行操作了。
对数据进行操作
- 记住添加扫描包 很重要,要不然没有 Bean @MapperScan(“com/city/citymybatisplus/mapper”) 添加在启动类
- 编写测试类
package com.city.citymybatisplus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//添加测试类
@MapperScan("com/city/citymybatisplus/mapper")
public class CityMybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(CityMybatisPlusApplication.class, args);
}
}
package com.city.citymybatisplus;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.city.citymybatisplus.domain.Mybatis;
import com.city.citymybatisplus.mapper.MybatisMapper;
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
public class MybatisTest {
@Autowired
MybatisMapper mybatisMapper;
void testGetAll() {
List<Mybatis> mybatisList = mybatisMapper.selectList(null);
System.out.println(mybatisList);
}
@Test
void testInsert(){
Mybatis mybatis = new Mybatis();
mybatis.setAge(22);
mybatis.setName("Alice");
mybatis.setEmail("2222@qq.com");
mybatisMapper.insert(mybatis);
}
@Test
void testgetPage(){
IPage page = new Page(1,2);
mybatisMapper.selectPage(page,null);
System.out.println("当前页码:"+page.getCurrent());
System.out.println("每页数据总量:"+page.getSize());
System.out.println("总页数:"+page.getPages());
System.out.println("数据总量:"+page.getTotal());
System.out.println("当前页数据:"+page.getRecords());
}
}
对于测试类可以先运行selectall,测试是否成功,可以根据提示查看每个方法,进行测试。
分页查询
void testgetPage(){
IPage page = new Page(1,2);
mybatisMapper.selectPage(page,null);
System.out.println("当前页码:"+page.getCurrent());
System.out.println("每页数据总量:"+page.getSize());
System.out.println("总页数:"+page.getPages());
System.out.println("数据总量:"+page.getTotal());
System.out.println("当前页数据:"+page.getRecords());
}
这是测试的方法,但是现在还不行,还要编写mybatis-plus的配置类,才可以。 注意:注解
package com.city.citymybatisplus.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义拦截器
MybatisPlusInterceptor mysqlPlusInterceptor = new MybatisPlusInterceptor();
//添加具体的拦截器
mysqlPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mysqlPlusInterceptor;
}
}
配置文件添加日志,查看sql命令
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
使用代码生成器 mybatisX
这是IDEA的插件,安装即可,很不错
这个插件会生成domain、Mapper、server、impl、resouce的代码,多试几次就顺手了。
条件查询
日志优化
关闭banner
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mycity
username: root
password: 123456
main:
banner-mode: off
server:
port: 8080
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: false
创建日志文件logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
</configuration>
三种方式
/* //条件查询.方式一 设置条件
QueryWrapper qw = new QueryWrapper();
qw.lt("age",22);
List<Mybatis> mybatisList = mybatisMapper.selectList(qw);
System.out.println(mybatisList);
*/
// 方式二
/* QueryWrapper qw1 = new QueryWrapper();
qw1.lambda().lt(Mybatis:: getAge,
24);
List<Mybatis> mybatisList1 = mybatisMapper.selectList(qw1);
System.out.println(mybatisList);*/
LambdaQueryWrapper<Mybatis> lqw = new LambdaQueryWrapper();
lqw.lt(Mybatis::getAge,24);
List<Mybatis> mybatisList2 = mybatisMapper.selectList(lqw);
System.out.println(mybatisList2);
null值处理
做空值判定
@Test
void testNullSelect(){
//模拟页面传递的查询数据
MybatisQuery mq = new MybatisQuery();
// mq.setAge2(24);
mq.setAge(18);
// LambdaQueryWrapper<Mybatis> lqw = new LambdaQueryWrapper<>();
// lqw.lt(Mybatis::getAge,24);
// lqw.gt(Mybatis::getAge,18);
// List<Mybatis> mybatisList = mybatisMapper.selectList(lqw);
// System.out.println(mybatisList);
LambdaQueryWrapper<Mybatis> lqw = new LambdaQueryWrapper<>();
lqw.ge(null!= mq.getAge(),Mybatis::getAge,mq.getAge());
lqw.lt(null!= mq.getAge2(),Mybatis::getAge,mq.getAge2());
// lqw.lt(Mybatis::getAge,24);
// lqw.gt(Mybatis::getAge,18);
List<Mybatis> mybatisList = mybatisMapper.selectList(lqw);
System.out.println(mybatisList);
}
查询投影
@Test
void testChoose() {
LambdaQueryWrapper<Mybatis> lqw = new LambdaQueryWrapper();
lqw.select(Mybatis::getId,Mybatis::getName);
List<Mybatis> mybatisList = mybatisMapper.selectList(lqw);
System.out.println(mybatisList);
//查询投影
QueryWrapper<Mybatis> qw = new QueryWrapper<>();
qw.select("count(*) as nums , age");
qw.groupBy("age");
List<Map<String,Object>> my = mybatisMapper.selectMaps(qw);
System.out.println(my);
}
删除锁
由配置文件配置
乐观锁
业务并发带来的问题:秒杀
@Version
private Integer version;
@Test
void testupdate() {
Mybatis mybatis = new Mybatis();
mybatis.setId(2L);
mybatis.setName("Tom");
mybatis.setVersion(2);
QueryWrapper<Mybatis> qw = new QueryWrapper<>();
mybatisMapper.updateById(mybatis);
}