一、CRUD 扩展 (2)
1.1 Select
- 查询所有:
/*
* 查询
* */
@Test //查询全部
public void selectUser(){
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
- 根据id查询:
@Test //通过id查询单个用户
public void selectUser1(){
User user = userMapper.selectById(3);
System.out.println(user);
}
- 通过id查询多个用户
@Test //批量查询
public void selectUser2(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
users.forEach(System.out::println);
}
- 条件查询 通过map封装
@Test // 条件查询 通过map封装
public void selectUser3(){
Map<String,Object> map = new HashMap<>();
map.put("name","xieMax");
map.put("age",22);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
1.2 分页查询
分页在网站的使用十分之多!
- 1、原始的limit分页
- 2、pageHelper第三方插件
- 3、MybatisPlus其实也内置了分页插件!
如何使用:参考官网 分页插件
- 1、配置拦截器组件(在config下面的
MybatisPlusConfig
)
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
return new MybatisPlusInterceptor();
}
- 2、增加测试方法直接使用page对象即可
/*
* 分页
* */
@Test //测试分页查询
public void pageTest(){
//参数一 current:当前页 参数二size:页面大小
//使用了分页插件之后,所有的分页操作都变得简单了
Page<User> page = new Page<>(2,5);
Page<User> userPage = userMapper.selectPage(page, null);
userPage.getRecords().forEach(System.out::println);
System.out.println("总页数==>"+page.getTotal());
}
运行结果查看:
1.3 Delete
1.3.1 物理删除
- ① 通过id删除
@Test //通过id删除
public void deleteUserById(){
userMapper.deleteById(1819427560255004676L);
}
运行删除后:
- ② 批量删除
运行后:
- ③ 通过map删除
@Test//批量删除 通过map删除
public void deleteByMap(){
Map<String,Object> map = new HashMap<>();
map.put("name","xieMax");
userMapper.deleteByMap(map);
}
运行后
1.3.2 逻辑删除
官网逻辑删除 逻辑删除支持
我们在工作中会遇到一些问题:逻辑删除!
物理删除
:从数据库中直接删除逻辑删除
:在数据库中没有被删除,而是通过一个变量来使他失效!deleted=0 ==> deleted=1
管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!
上手测试一下:
- 1、在数据表中增加一个
deleted
字段
- 2、实体类中添加对应属性
@TableLogic//逻辑删除注解
private Integer deleted;
- 3、在 application.yml 中配置 MyBatis-Plus 的全局逻辑删除属性
mybatis-plus:
#配置逻辑删除 没删除的为0 删除的为1
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除字段名
logic-delete-value: 1 # 逻辑已删除值
logic-not-delete-value: 0 # 逻辑未删除值
- 4、测试一下删除
运行删除:
刷新数据库查看:
再次运行查询:
发现:
记录还在,deleted变为1
,再次测试查询被删除的用户,发现查询为空
以上所有的CRUD及其扩展操作,我们都必须精通掌握!会大大提高工作写项目的效率!
二、性能分析插件
我们在平时的开发中,会遇到一些满Sql。测试、druid···
MybatisPlus也提供了性能分析插件,如果超过这个时间就停止运行!
性能分析拦截器作用:用于输出每条sql语句及其执行时间
- 1、导入插件遇见下面问题
解决(降低依赖版本):
//性能分析插件
@Bean
@Profile({"dev","test"})//设置dev开发、test测试 环境开启 保证我们的效率
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//设置sql最大执行时间*ms,如果超过了则不执行
performanceInterceptor.setFormat(true);//开启sql格式化
return performanceInterceptor;
}
注意: 要在application.yml
中配置环境为dev
或test
环境!
#设置开发环境
spring:
profiles:
active: dev
- 2、测试使用
① 测试查询全部所用的时间:
@Test //查询全部
public void selectUser(){
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
显示结果如下:
② 测试查询全部所用的时间将来最大时间改为1ms运行则如下抛出异常
使用性能分析插件,可以帮助我们提高效率!
三、条件构造器
官网 条件构造器
十分重要:Wrapper 记住查看输出的SQL进行分析
表数据
- 测试一:
增加方法:
@Test
public void test1(){
//参数是一个wrapper ,条件构造器,和刚才的map对比学习!
//查询name不为空,email不为空,age大于18的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age",18);
userMapper.selectList(wrapper);
}
查询结果:
- 测试二
增加方法:
@Test
public void test2(){
//查询name=Sandy
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","Sandy");
//查询一个数据selectOne,若查询出多个会报错
//Expected one result (or null) to be returned by selectOne(), but found: *
//若出现多个结果使用list或map
userMapper.selectOne(wrapper);//查询一个数据,若出现多个结果使用list或map
}
查询结果:
- 测试三
增加方法
@Test
public void test3(){
//查询age在10-20之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30);//区间
System.out.println(userMapper.selectCount(wrapper));//输出查询的数量selectCount
}
查询结果:
- 测试四
增加方法:
@Test
public void test4(){
//模糊查询 查询表中名字包含 a,不包含 c ,且test%的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","a")
.notLike("name","c")
.likeRight("email","test"); //qq% 左和右?
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
查询结果:
- 测试五
增加查询方法:
@Test
public void test5(){
//模糊查询
//SELECT id,name,age,email,version,deleted,create_time,update_time
// FROM user WHERE id IN (select id from user where id < 3)
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id","select id from user where id < 3");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
查询结果显示:
- 测试六
增加方法:
@Test
public void test6(){
//通过id进行降序排序
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
查询结果显示:
条件构造器所有查询代码:
package com.gansu;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gansu.mapper.UserMapper;
import com.gansu.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class WrapperTests {
@Autowired
private UserMapper userMapper;
@Test
public void test1(){
//参数是一个wrapper ,条件构造器,和刚才的map对比学习!
//查询name不为空,email不为空,age大于18的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age",18);
userMapper.selectList(wrapper);
}
@Test
public void test2(){
//查询name=Sandy
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","Sandy");
//查询一个数据selectOne,若查询出多个会报错
//Expected one result (or null) to be returned by selectOne(), but found: *
//若出现多个结果使用list或map
userMapper.selectOne(wrapper);//查询一个数据,若出现多个结果使用list或map
}
@Test
public void test3(){
//查询age在10-20之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30);//区间
System.out.println(userMapper.selectCount(wrapper));//输出查询的数量selectCount
}
@Test
public void test4(){
//模糊查询 查询表中名字包含 a,不包含 c ,且test%的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","a")
.notLike("name","c")
.likeRight("email","test"); //qq% 左和右?
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
@Test
public void test5(){
//模糊查询
//SELECT id,name,age,email,version,deleted,create_time,update_time
// FROM user WHERE id IN (select id from user where id < 3)
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id","select id from user where id < 3");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
@Test
public void test6(){
//通过id进行降序排序
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
}
Mysql
=>JDBC
=>Mybatis
=>MybatisPlus
四、代码自动生成器
AutoGenerator
是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成Entity、Mapper、Mapper XML、Service、Controller
等各个模块的代码,极大的提升了开发效率。
官网👉👉代码生成器
生成前提要有表:
- ① 创建一个springboot maven项目
- ② 修改版本号,删除不需要的目录
- ③ 导入依赖
<!--1.数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!--2.lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--3.mybatis-plus 版本很重要3.0.5-->
<!--mybatis-plus自己开发的,并非官方的-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version><!--3.4.2 3.0.5-->
</dependency>
<!--4.h2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--5.junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--模板引擎 依赖:mybatis-plus代码生成的时候报异常-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!--配置ApiModel在实体类中不生效-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>spring-boot-starter-swagger</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!--beetl-->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.3.2.RELEASE</version>
</dependency>
整个pom.xml文件:
<?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.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gansu</groupId>
<artifactId>CodeGenerator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CodeGenerator</name>
<description>CodeGenerator</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--1.数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!--2.lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--3.mybatis-plus 版本很重要3.0.5-->
<!--mybatis-plus自己开发的,并非官方的-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version><!--3.4.2 3.0.5-->
</dependency>
<!--4.h2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--5.junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--模板引擎 依赖:mybatis-plus代码生成的时候报异常-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!--配置ApiModel在实体类中不生效-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>spring-boot-starter-swagger</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!--beetl-->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.3.2.RELEASE</version>
</dependency>
</dependencies>
</project>
- ④ 编写生成器
AutoGenerator
package com.gansu;
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.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.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
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("Daniel");
gc.setOpen(false);
gc.setFileOverride(false);//是否覆盖
gc.setServiceName("%sService");//去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("study");
pc.setParent("com.gansu");
pc.setEntity("pojo");
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 gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtUpdate = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtUpdate);
strategy.setTableFillList(tableFills);
//乐观锁配置
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);//开启驼峰命名
strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute();//执行
}
}
- ⑤ 运行上面代码,生成后显示:
- ⑥ 拷贝到自己的项目中就可以使用了。
至此,
MyBatis-Plus总结完毕
,还需要进一步学习可以到官网继续探索