目录
3.4 添加配置文件application.yml,配置数据库信息
1. MyBatis-Plus概述
MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。
2. MyBatis-Plus框架结构
序号 | 模块 | 功能 |
---|---|---|
1 |
| 核心模块,提供了对MyBatis的增强和扩展,包括分页、动态SQL、对象映射等功能。 |
2 |
| JDBC模块,提供了一些实用的方法,如获取数据库连接、执行SQL语句等。 |
3 |
| 元数据模块,用于解析数据库的元数据信息,包括数据库表结构、字段信息等。 |
4 |
| 分页模块,提供分页查询的功能 |
5 |
| 代码生成模块,用于自动生成MyBatis的Mapper接口、XML文件和Java实体类。 |
6 |
| 注解模块,提供了一些自定义的注解,用于简化代码编写。 |
7 |
| 扩展模块,提供了一些实用的扩展功能,如缓存、事务管理等。 |
3. MyBatis-Plus快速入门
3.1 创建表
创建数据库mybatis_db
创建表user
CREATE TABLE user (
id bigint(20) NOT NULL COMMENT '主键ID',
name varchar(30) DEFAULT NULL COMMENT '姓名',
age int(11) DEFAULT NULL COMMENT '年龄',
email varchar(50) DEFAULT NULL COMMENT '邮箱',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time datetime DEFAULT NULL COMMENT '修改时间',
version int(11) DEFAULT NULL COMMENT '版本',
deleted int(11) DEFAULT NULL COMMENT '删除标记',
PRIMARY KEY (`id`)
);
添加测试数据
INSERT INTO `user` VALUES
(1, '张三', 18, '[email protected]', '2024-01-17 10:31:30', '2024-01-17 10:31:30', 1, 0),
(2, '李四', 20, '[email protected]', '2024-01-17 10:31:30', '2024-01-17 10:31:30', 1, 0),
(3, '王五', 28, '[email protected]', '2024-01-17 10:31:30', '2024-01-17 10:31:30', 1, 0),
(4, '赵六', 21, '[email protected]', '2024-01-17 10:31:30', '2024-01-17 10:31:30', 1, 0),
(5, '周七', 24, '[email protected]', '2024-01-17 10:31:30', '2024-01-17 10:31:30', 1, 0);
3.2 创建工程
设置 Maven
设置自动导入包 Auto Import
设置启动注解 Annotation Processors
3.3 导入依赖
<!--引入springboot依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<dependencies>
<!--引入spring-boot启动器依赖, 添加启动器后web工程常用的依赖会自动帮你引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>
<!--打包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.4 添加配置文件application.yml,配置数据库信息
# 配置日志输出格式
logging:
pattern:
console: "%clr(%5p) %clr(-){faint} %clr(%-80.80logger{79}){cyan} %clr(:) %m%n"
spring:
# 数据源配置
datasource:
username: root #数据库用户名
password: 163.com #密码
url: jdbc:mysql://localhost:3306/mybatis_db?serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
# sql输出日志配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.5 创建实体类(包括自动填充)
package com.miaxis.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
@TableName("user")
public class User {
@TableId(type = IdType.ID_WORKER) //主键生成策略
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime; //自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //自动填充
@TableField(fill = FieldFill.INSERT)
@Version
private Integer version; //自动填充 当做更新时, version字段会自动加1
@TableLogic //逻辑删除
@TableField(fill = FieldFill.INSERT) //自动填充
private Integer deleted;
}
3.6 创建配置类(包括配置乐观锁、分页、逻辑删除等插件)
package com.miaxis.config;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class Config {
/*配置乐观锁插件*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
/*配置分页插件*/
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
/*逻辑删除配置*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
}
乐观锁:一个人操作时,允许多人可以同时操作,但是同一时刻只能有一个操作。使用一个额外的字段Version,取出记录时,获取当前version,更新时,带上这个version,把version值+1。
逻辑删除(假删除),将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录 。逻辑删除添加后,使用查询, 查询的内容只有标记为0的被查出来
3.7 编写自动填充handler类
添加注解 来去指明 哪些字段需要自动填充
package com.miaxis.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/* 1.编写handler 指定 填充的内容
* 2.在实体类当中 添加注解 来去指明 哪些字段需要自动填充
* */
@Component
public class UserMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
this.setFieldValByName("version",1,metaObject);
this.setFieldValByName("deleted",0,metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
3.8 编写mapper接口类
package com.miaxis.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.miaxis.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
3.9 编写启动类,添加MapperScan
package com.miaxis;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.miaxis.mapper")
public class Application {
public static void main(String[] args ) {
SpringApplication.run(Application.class, args );
}
}
3.10 编写测试类,CRUD操作
package com.miaxis;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.miaxis.entity.User;
import com.miaxis.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@SpringBootTest
public class ApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
//查询所有内容
public void getAll() { /*如果添加了逻辑删除 默认查询只会查询出标记为0的选项*/
/**查询所有内容*/
List<User> users = userMapper.selectList(null);
/** 打印集合中元素*/
users.forEach(System.out::println);
}
@Test
//create添加数据
public void testInsert(){
User user = new User();
user.setName("fmjava");
user.setAge(1);
user.setEmail("[email protected]");
int result = userMapper.insert(user);
System.out.println(result); //影响的行数
System.out.println(user.getId()); //id自动回填
}
@Test
//read读取数据
public void testSelect(){
//根据单个id查询
User user = userMapper.selectById(2);
System.out.println(user);
}
@Test
//read读取数据
public void testSelect2(){
//多id批量查询
List<User> users = userMapper.selectBatchIds(Arrays.asList(2, 3, 4));
users.forEach(System.out::println);
}
@Test
//read读取数据
public void testSelect3(){
//把需要查询的条件添加到map当中
HashMap<String,Object> map = new HashMap<>();
map.put("name","王五");
map.put("age","28");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
@Test
//分页查询
public void selectByPage(){
/*当前页, 一页查询多少条记录*/
Page<User> page = new Page<>(2, 3);
userMapper.selectPage(page,null);
/*把查询出所有结果给封装到page对象当中*/
System.out.println("当前页 : "+page.getCurrent());
System.out.println("每页数据 : "+page.getRecords());
System.out.println("每页显示多少条记录 :"+page.getSize());
System.out.println("总记录数 : "+page.getTotal());
System.out.println("总页数 : "+page.getPages());
System.out.println("是否有下一页 : "+page.hasNext());
System.out.println("是否有上一页 : "+page.hasPrevious());
}
@Test
//update修改数据
public void update(){
//先查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("zs1");
//执行更新
int nRet = userMapper.updateById(user);
if(nRet <= 0) {
System.out.println("更新失败");
}else {
System.out.println("更新成功");
}
}
@Test
//update修改数据
public void update2(){
//先查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("zs2");
//模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
//把版本给变小,发现代码能执行成功,但是没有修改成功
user.setVersion(user.getVersion() -1);
//执行更新
int nRet = userMapper.updateById(user);
if(nRet <= 0) {
System.out.println("更新失败");
}else {
System.out.println("更新成功");
}
}
@Test
//delete删除数据
public void deleteTest(){ /*逻辑删除*/
int i = userMapper.deleteById(1L);
System.out.println(i);
}
@Test
//delete删除数据
public void deleteTest2(){
int i = userMapper.deleteBatchIds(Arrays.asList(2,3,4));
System.out.println(i);
}
@Test
//delete删除数据
public void deleteTest3(){
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("name","fmjava2");
userMapper.deleteByMap(hashMap);
}
}
3.11 编写多条件查询测试类
package com.miaxis;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.miaxis.entity.User;
import com.miaxis.mapper.UserMapper;
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
public class ApplicationTests2 {
@Autowired
private UserMapper userMapper;
@Test
public void test1(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","李四")
.ne("age",10);
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
@Test
public void test2(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","李四")
.ge("age",24)
.isNotNull("email");
userMapper.delete(queryWrapper);
}
@Test
public void testSelectCount() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.between("age", 20, 30);
Integer count = userMapper.selectCount(queryWrapper);
System.out.println(count);
}
@Test
public void testSelectList() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("id", 3L);
map.put("name", "王五");
map.put("age", 28);
queryWrapper.allEq(map);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
@Test
public void testSelectMaps() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.notLike("name", "fm")
.likeRight("email", "l");
List<User> maps = userMapper.selectList(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
}
@Test
public void testSelectObjs() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//queryWrapper.in("id", 1, 2, 3);
queryWrapper.inSql("id", "select id from user where id < 3");
List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表
objects.forEach(System.out::println);
}
@Test
public void testUpdate1() {
//修改值
User user = new User();
user.setAge(99);
user.setName("gxq");
//修改条件
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "fm")
.or()
.between("age", 20, 30);
int result = userMapper.update(user, userUpdateWrapper);
System.out.println(result);
}
@Test
public void testUpdate2() {
//修改值
User user = new User();
user.setAge(10);
user.setName("myxq");
//修改条件
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "A")
.or(i -> i.eq("name", "gxq").ne("age", 20));
int result = userMapper.update(user, userUpdateWrapper);
System.out.println(result);
}
@Test
public void testSelectListOrderBy() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
@Test
public void testSelectListLast() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/**只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用*/
queryWrapper.last("limit 1");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
@Test
public void testSelectListColumn() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id", "name", "age");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
@Test
public void testUpdateSet() {
//修改值
User user = new User();
user.setAge(10);
//修改条件
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "A")
.set("name", "fmjava")//除了可以查询还可以使用set设置修改的字段
.setSql(" email = '[email protected]'");//可以有子查询
int result = userMapper.update(user, userUpdateWrapper);
}
}
3.12 性能分析
概述:性能分析拦截器,用于输出每条 SQL 语句及其执行时间。SQL 性能执行分析,开发环境使用,超过指定时间,停止运行,有助于发现问题。
3.12.1 配置文件中添加配置
#环境设置:dev、test、prod
spring:
profiles:
active: test
3.12.2 配置类中添加插件
/**
* SQL 执行性能分析插件
* 开发环境使用,线上不推荐。
* 参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
* 参数:format: SQL是否格式化,默认false。
*/
@Bean
@Profile({"test"}) // 设置 test 环境开启(可以设置多个 {"test","dev","prod"})
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1000);//超过此处设置的ms sql不会执行
performanceInterceptor.setFormat(true);//格式化sql
return performanceInterceptor;
}
4. Demo下载地址
标签:queryWrapper,SpringBoot,Demo,Plus,user,new,import,com,public From: https://blog.csdn.net/mickey2007/article/details/137095873编译器版本:IntelliJ IDEA 2020.3.2 x64
JDK版本:java 1.8.0_111