Mybatis-plus学习笔记
文章目录
- Mybatis-plus学习笔记
- 前言
- 一、MP简介
- 二、SpringBoot集成Mybatis plus使用步骤
前言
一、MP简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
官网: https://mp.baomidou.com/
特性
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持数据库
mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver 、 presto
达梦数据库 、 虚谷数据库 、 人大金仓数据库
是在mybatis的基础上加了一些辅助功能大大简化了我们的开发
二、SpringBoot集成Mybatis plus使用步骤
1.引入库
引入下mp依赖,注意不要引错了,会和我一样找不到映射的
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
再引入下连接池druid和单元测试框架junit
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
2.配置文件
application,yml文件配置
关于数据库字段风格虽然实体类可以设置成和数据库字段不同 但是这样加大内存的消耗,建议还是和mp默认一样
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_mp?serverTimezone=GMT
username: root
password: xxxxx
mybatis-plus:
global-config:
db-config:
id-type: auto
# table-prefix: t_ 设置表前缀
# table-underline: false #不设置驼峰 如 t_studentInfo 变成 t_student_info
#configuration:
# map-underscore-to-camel-case: false #设置列不驼峰
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #显示mysql语句
Application类记得加mapper扫描
@MapperScan("com.luyi.mapper")
3.数据库结构和实体类配置
数据库结构
实体类代码:
/**
* 部门实体
* @author 卢意
* @create 2020-10-14 19:31
*/
@TableName("t_department") //实体映射t_department表 同名不用映射
@Data //自动生成get set
public class Department {
@TableId(value = "id",type = IdType.AUTO) //设置主键生成策略
private Integer id; //编号
@TableField(value = "depart_name") //字段名和属性名称不一样时 设置映射
private String name;//名称
private String remark; //备注
@TableField(exist = false) //数据库中不存在的属性 设置不存在
public String state; //
}
4.mapper接口
继承BaseMapper
package com.luyi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.luyi.entity.Department;
/**
* 部门mapper接口
* @author 卢意
* @create 2020-10-14 19:34
*/
public interface DepartmentMapper extends BaseMapper<Department> {
}
4.使用
这样就继承了很多方法
5.queryWrapper的使用
1.queryWrapper的声明
建议使用第一种声明方式比较直观
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
//第二种声明方式 QueryWrapper<Employee> queryWrapper2= Wrappers.<Employee>query();
2.queryWrapper的实例
(1).查找薪水大于3500 名字里有“小”的 员工
sql语句
select * from t_employee where salary>3500 and name like '%小%'
queryWrapper使用
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
//第二种声明方式 QueryWrapper<Employee> queryWrapper2= Wrappers.<Employee>query();
queryWrapper.gt("salary", 3500).like("name", "小"); // gt 大于
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (salary BETWEEN ? AND ? AND name LIKE ? AND email IS NOT NULL)
==> Parameters: 3500(Integer), 4800(Integer), %小%(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 3, 李小丽, 1993-02-09, 女, 12722556578, 2, 3800
<== Row: 4, 王小萌, 1994-02-09, 女, 12622556578, 2, 4000
<== Total: 2
(2).查找薪水范围【3500,4800】,名字里有“小”以及email不为空 的员工
sql语句
select * from t_employee where between 3500 and 4800 and name like '%小%' and email is not null
queryWrapper使用
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.between("salary", 3500, 4800).like("name", "小").isNotNull("email");
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (salary > ? AND name LIKE ?)
==> Parameters: 3500(Integer), %小%(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 3, 李小丽, 1993-02-09, 女, 12722556578, 2, 3800
<== Row: 4, 王小萌, 1994-02-09, 女, 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 女, 12622556578, 3, 4400
<== Row: 6, 钱小小, 1994-06-09, 女, 16642556578, 4, 4900
<== Total: 4
(3).查询姓李的,并且出生日期范围是1993-02-09到1994-04-09的员工
sql语句
SELECT * FROM t_employee WHERE DATE_FORMAT(birthday,'%Y-%m-%d')>='1993-02-09' AND DATE_FORMAT(birthday,'%Y-%m-%d')<='1994-04-09' AND NAME LIKE '李%'
queryWrapper使用
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.apply("DATE_FORMAT(birthday,'%Y-%m-%d')>={0} AND DATE_FORMAT(birthday,'%Y-%m-%d')<={1} ","1993-02-09","1994-04-09").likeRight("name", "李");
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@40298285] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (DATE_FORMAT(birthday,'%Y-%m-%d')>=? AND DATE_FORMAT(birthday,'%Y-%m-%d')<=? AND name LIKE ?)
==> Parameters: 1993-02-09(String), 1994-04-09(String), 李%(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 2, 李四, 1993-02-09, 男, 13622556578, 1, 3500
<== Row: 3, 李小丽, 1993-02-09, 女, 12722556578, 2, 3800
<== Total: 2
(4).查询姓李的或者邮箱不为空并且是女性的员工
sql语句
sql:SELECT * FROM t_employee WHERE NAME LIKE '李%' OR (email IS NOT NULL AND gender ='女')
queryWrapper使用
这里运用了lambda表达式,处理or方法更方便一点
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.likeRight("name", "李").or(wq->wq.isNotNull("email").eq("gender","女"));
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JJDBC Connection [com.mysql.jdbc.JDBC4Connection@af9a89f] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (name LIKE ? OR (email IS NOT NULL AND gender = ?))
==> Parameters: 李%(String), 女(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 2, 李四, 1993-02-09, 男, 13622556578, 1, 3500
<== Row: 3, 李小丽, 1993-02-09, 女, 12722556578, 2, 3800
<== Row: 4, 王小萌, 1994-02-09, 女, 12622556578, 2, 4000
<== Row: 6, 钱小小, 1994-06-09, 女, 16642556578, 4, 4900
<== Total: 4
(5).查询姓李的并且邮箱不为空或者是女性的员工
sql语句
sql:SELECT * FROM t_employee WHERE NAME LIKE '李%' AND (email IS NOT NULL OR gender ='女')
queryWrapper使用
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.likeRight("name", "李").and(wq->wq.isNotNull("email").or().eq("gender","女"));
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@7c2312fa] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (name LIKE ? AND (email IS NOT NULL OR gender = ?))
==> Parameters: 李%(String), 女(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 2, 李四, 1993-02-09, 男, 13622556578, 1, 3500
<== Row: 3, 李小丽, 1993-02-09, 女, 12722556578, 2, 3800
<== Total: 2
(6).查询属于编号1,2,3部门的并且薪水小于等于3500的员工 根据年龄从大到小排序显示
sql语句
sql:SELECT * FROM t_employee WHERE salary<=3500 AND department_id IN (1,2,3) ORDER BY birthday ASC
queryWrapper使用
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.le("salary",3500).in("department_id","1,2,3").orderByAsc("birthday");//le 小于等于
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@11e33bac] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,phone_number,department_id,salary FROM t_employee WHERE (salary <= ? AND department_id IN (?)) ORDER BY birthday ASC
==> Parameters: 3500(Integer), 1,2,3(String)
<== Columns: Id, name, birthday, gender, phone_number, department_id, salary
<== Row: 2, 李四, 1993-02-09, 男, 13622556578, 1, 3500
<== Row: 1, 张三, 2000-01-09, 男, 13654556578, 1, 3000
<== Total: 2
6.updateWrapper的使用
1.queryWrapper的声明
建议使用第一种声明方式比较直观
UpdateWrapper<Employee> updateWrapper=new UpdateWrapper<>();
//第二种声明方式UpdateWrapper<Employee> updateWrapper= Wrappers.<Employee>update();
2.queryWrapper的实例
(1).更新指定员工的邮箱和联系电话
sql语句
UPDATE t_employee SET email="[email protected]", phoneNumber="12345678" WHERE id=6
queryWrapper使用
UpdateWrapper<Employee> updateWrapper=new UpdateWrapper<>();
//第二种声明方式UpdateWrapper<Employee> updateWrapper= Wrappers.<Employee>update();
Employee employee=new Employee();
employee.setEmail("12345qq.com");
employee.setPhone_number("18359348349");
updateWrapper.eq("id", 5);
Integer resultNum= employeeMapper.update(employee, updateWrapper);
if(resultNum>0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@301aa982] will not be managed by Spring
==> Preparing: UPDATE t_employee SET email=?, phone_number=? WHERE (id = ?)
==> Parameters: 12345qq.com(String), 18359348349(String), 5(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7965a51c]
修改成功
(2).删除市场部老员工
sql语句
DELETE FROM t_employee WHERE DATE_FORMAT(birthday,'%Y-%m-%d')<="1990-01-01" AND department_id=2
queryWrapper使用
apply 实现MySql函数
UpdateWrapper<Employee> updateWrapper=new UpdateWrapper<>();
//第二种声明方式UpdateWrapper<Employee> updateWrapper= Wrappers.<Employee>update();
updateWrapper.apply("DATE_FORMAT(birthday,'%Y-%m-%d')<={0}","1994-01-01").eq("department_id", 2);
Integer resultNum= employeeMapper.delete(updateWrapper);
if(resultNum>0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@359ff4d9] will not be managed by Spring
==> Preparing: DELETE FROM t_employee WHERE (DATE_FORMAT(birthday,'%Y-%m-%d')<=? AND department_id = ?)
==> Parameters: 1994-01-01(String), 2(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@59532566]
修改成功
7.条件构造器select方法
根据业务需求,有时候只需要返回特定几个数据表字段,通过条件构造器的select方法指定
1.实例
(1)查找薪水大于3500 名字里有“小”的 员工(只显示编号和姓名)
继上面queryWrapper的实例扩展
apply 实现MySql函数
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.select("id","name").gt("salary", 3500).like("name", "小"); // gt 大于
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@4ce14f05] will not be managed by Spring
==> Preparing: SELECT id,name FROM t_employee WHERE (salary > ? AND name LIKE ?)
==> Parameters: 3500(Integer), %小%(String)
<== Columns: id, name
<== Row: 4, 王小萌
<== Row: 5, 曹小梅
<== Row: 6, 钱小小
<== Total: 3
(2)查找薪水大于3500 名字里有“小”的 员工 (排除出生日期和性别)
queryWrapper使用
这里运用了lambda表达式
QueryWrapper<Employee> queryWrapper=new QueryWrapper<>();
queryWrapper.select(Employee.class,fieldInfo->!fieldInfo.getColumn().equals("birthDay")&&!fieldInfo.getColumn().equals("gender"))
.gt("salary", 3500).like("name", "小"); // gt 大于
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@af9a89f] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,email,phone_number,department_id,salary FROM t_employee WHERE (salary > ? AND name LIKE ?)
==> Parameters: 3500(Integer), %小%(String)
<== Columns: Id, name, birthday, email, phone_number, department_id, salary
<== Row: 4, 王小萌, 1994-02-09, [email protected], 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 12345qq.com, 18359348349, 3, 4400
<== Row: 6, 钱小小, 1994-06-09, [email protected], 16642556578, 4, 4900
<== Total: 3
(3)查询每个部门的平均薪资
sql:
SELECT department_id,AVG(salary) AS avg_salary FROM t_employee GROUP BY department_id;
queryWrapper使用
注意在使用是在实体字段添加平均工资属性
@TableField(exist = false) //不映射到数据库
private Integer avg_salary;
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.
select("department_id","AVG(salary) AS avg_salary")
.groupBy("department_id");
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@29528a22] will not be managed by Spring
==> Preparing: SELECT department_id,AVG(salary) AS avg_salary FROM t_employee GROUP BY department_id
==> Parameters:
<== Columns: department_id, avg_salary
<== Row: 1, 3250.0000
<== Row: 2, 4000.0000
<== Row: 3, 4400.0000
<== Row: 4, 4900.0000
<== Total: 4
8.condition动态判断条件
mp框架,在条件构造方法里,都会重载一个condition参数;
这个参数的作用是动态判断条件,假如condition是true,则拼接加条件,false的话,则不拼接加条件;
我们前台传来的动态条件,以前是通过代码判断拼接,现在我们可以直接条件构造方法里写,大大简化代码量;
1.实例
(1)动态判断条件 根据性别和名字查询
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
String s_gender="女";
String s_name="小";
/*老方法
if(StringUtil.isNotEmpty(s_gender)){
queryWrapper.eq("gender", s_gender);
}
if(StringUtil.isNotEmpty(s_name)){
queryWrapper.like("name", s_name);
}*/
queryWrapper.eq(StringUtil.isNotEmpty(s_gender), "gender",s_gender)
.like(StringUtil.isNotEmpty(s_name), "name",s_name);
List<Employee> employeeList = employeeMapper.selectList(queryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@7495699f] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,email,phone_number,department_id,salary FROM t_employee WHERE (gender = ? AND name LIKE ?)
==> Parameters: 女(String), %小%(String)
<== Columns: Id, name, birthday, gender, email, phone_number, department_id, salary
<== Row: 4, 王小萌, 1994-02-09, 女, [email protected], 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 女, 12345qq.com, 18359348349, 3, 4400
<== Total: 2
9返回Map类型数据
我们前面的案例都是返回的集合List;
集合List的弊端是会把所有的列属性都封装返回,但是我们有时候,只需要返回几个字段,然后再返回到用户端;
所以mp框架给我们提供了List<Map<String, Object>>返回类型,String是列名,Object是值,只返回select的字段;
1.实例
(1) 查询每个部门的平均薪资(Map)
QueryWrapper<Employee> queryWrapper=new QueryWrapper<> ();
queryWrapper.
select("department_id","AVG(salary) AS avg_salary")
.groupBy("department_id");
List<Map<String,Object>> maps = employeeMapper.selectMaps(queryWrapper);
System.out.println(maps);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@29528a22] will not be managed by Spring
==> Preparing: SELECT department_id,AVG(salary) AS avg_salary FROM t_employee GROUP BY department_id
==> Parameters:
<== Columns: department_id, avg_salary
<== Row: 1, 3250.0000
<== Row: 2, 4000.0000
<== Row: 3, 4400.0000
<== Row: 4, 4900.0000
<== Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4f63e3c7]
[{department_id=1, avg_salary=3250.0000}, {department_id=2, avg_salary=4000.0000}, {department_id=3, avg_salary=4400.0000}, {department_id=4, avg_salary=4900.0000}]
10.lambda条件构造器
mp框架提供了lambda表达式条件构造器支持;
1.实例
(1) 查找薪水大于3500 名字里有“小”的 员工 (使用Lambda表达式 )
LambdaQueryWrapper<Employee> lambdaQueryWrapper=new QueryWrapper<Employee>().lambda();
/*
第二种方式
LambdaQueryWrapper<Employee> lambdaQueryWrapper2=new LambdaQueryWrapper<>();
第三种方式
LambdaQueryWrapper<Employee> lambdaQueryWrapper3= Wrappers.lambdaQuery();*/
lambdaQueryWrapper.gt(Employee::getSalary,3500)
.like(Employee::getName,"小");
List<Employee>employeeList=employeeMapper.selectList(lambdaQueryWrapper);
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@12b5454f] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,email,phone_number,department_id,salary FROM t_employee WHERE (salary > ? AND name LIKE ?)
==> Parameters: 3500(Integer), %小%(String)
<== Columns: Id, name, birthday, gender, email, phone_number, department_id, salary
<== Row: 4, 王小萌, 1994-02-09, 女, [email protected], 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 女, 12345qq.com, 18359348349, 3, 4400
<== Row: 6, 钱小小, 1994-06-09, 男, [email protected], 16642556578, 4, 4900
<== Total: 3
(2) 查找薪水大于3500 名字里有“小”的 员工 (使用Lambda表达式 chain (链式) )
List<Employee>employeeList=new LambdaQueryChainWrapper<Employee>(employeeMapper)
.gt(Employee::getSalary,3500)
.like(Employee::getName,"小")
.list();
System.out.println(employeeList);
结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@12b5454f] will not be managed by Spring
==> Preparing: SELECT Id,name,birthday,gender,email,phone_number,department_id,salary FROM t_employee WHERE (salary > ? AND name LIKE ?)
==> Parameters: 3500(Integer), %小%(String)
<== Columns: Id, name, birthday, gender, email, phone_number, department_id, salary
<== Row: 4, 王小萌, 1994-02-09, 女, [email protected], 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 女, 12345qq.com, 18359348349, 3, 4400
<== Row: 6, 钱小小, 1994-06-09, 男, [email protected], 16642556578, 4, 4900
<== Total: 3
10.Mybatis-plus物理分页插件
1.配置一个PaginationInterceptor的bean;
在3.3.0以下的版本
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
注意PaginationInterceptor 导入的类是
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
但是在3.4.0版本时 改包下的类被废弃,统一把插件变成一个集合
内置插件(since 3.4.0)
主体插件: MybatisPlusInterceptor该插件内部插件集:
● 分页插件: PaginationInnerInterceptor
● 多租户插件: TenantL ineInnerInterceptor
● 动态表名插件: DynamicTableNameInnerInterceptor乐观锁插件: OptimisticL ockerInnerInterceptor
● sq|性 能规范插件: llegalsQLInnerInterceptor
● 防止全表更新与删除插件: BlockAttackInnerInterceptor
3.4.0的配置如下
package com.luyi.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MybatisPlus配置类
* @author 卢意
* @create 2020-10-15 17:05
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
}
2.实例
(1) 找薪水大于3500 名字里有“小”的 员工 带分页
QueryWrapper<Employee> queryWrapper=new QueryWrapper<>();
// QueryWrapper<Employee> queryWrapper2= Wrappers.<Employee>query();
queryWrapper.gt("salary",3500).like("name","小");
Page<Employee> page = new Page<>(1,2);
IPage<Employee> employeePage = employeeMapper.selectPage(page, queryWrapper);
System.out.println("总记录数:"+employeePage.getTotal());
System.out.println("总页数:"+employeePage.getPages());
System.out.println("当前页数据:"+employeePage.getRecords());
结果
==> Preparing: SELECT Id,name,birthday,gender,email,phone_number,department_id,salary FROM t_employee WHERE (salary > ? AND name LIKE ?) LIMIT ?
==> Parameters: 3500(Integer), %小%(String), 2(Long)
<== Columns: Id, name, birthday, gender, email, phone_number, department_id, salary
<== Row: 4, 王小萌, 1994-02-09, 女, [email protected], 12622556578, 2, 4000
<== Row: 5, 曹小梅, 1994-04-09, 女, 12345qq.com, 18359348349, 3, 4400
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@51d143a1]
总记录数:3
总页数:2
当前页数据:[Employee(Id=4, name=王小萌, birthday=Wed Feb 09 00:00:00 CST 1994, gender=女, [email protected], phone_number=null, department_id=null, salary=4000, avg_salary=null), Employee(Id=5, name=曹小梅, birthday=Sat Apr 09 00:00:00 CST 1994, gender=女, email=12345qq.com, phone_number=null, department_id=null, salary=4400, avg_salary=null)]
(2)不返回记录数节约内存消耗
11.Mybatis-plus ActiveRecord模式(AR模式)
在Mybatis-Plus中提供了ActiveRecord的模式,支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作,简单来说就是一个实体类继承Model类,并通过注解与数据库的表名进行关联,这样就可以通过实体类直接进行表的简单增删改查操作,这样也确实极大的方便了开发人员。
1.设置
实体类继承Model类 注意记得加上注解否则报错
@EqualsAndHashCode(callSuper = false)
public class Department extends Model<Department> {
2.实例
都是简单CRUD 就不多说了 就是insertOrUpdate比较特别一点
(1)insert
Department department=new Department();
department.setName("xx部门");
department.setRemark("xx部门测试");
boolean insert = department.insert();
System.out.println(insert);
(2)updateById
Department department=new Department();
department.setName("xx部门");
department.setRemark("xx部门测试");
boolean insert = department.insert();
System.out.println(insert);
(3)insertorupdate 比较特别
添加或者修改 根据Id是否存在来判断
Department department=new Department();
department.setId(7);
department.setName("xx部门1");
department.setRemark("xx部门测试1");
boolean update = department.insertOrUpdate();
System.out.println(update);
(4)deleteById
Department department=new Department();
boolean deleteById = department.deleteById(7);
System.out.println(deleteById);
(5)selectById
blic void selectById(){
Department department=new Department();
Department department1 = department.selectById(1);
System.out.println(department1);
(5)selectByAll
Department department=new Department();
List<Department> departmentList = department.selectAll();
System.out.println(departmentList);
(5)selectByQueryWrapper
Department department=new Department();
QueryWrapper<Department> queryWrapper=new QueryWrapper<>();
queryWrapper.like("depart_name", "研");
List<Department> departmentList = department.selectList(queryWrapper);
System.out.println(departmentList);
11.Mybatis-plus 通用Service
mp框架同样提供了service层的封装支持,让我们能够简化service层的开发;
1,使用前配置
service接口继承IIService,service实现类继承ServiceImpl
/**
* @author 卢意
* @create 2020-10-15 19:14
*/
public interface DepartmentService extends IService<Department> {
}
/**
* @author 卢意
* @create 2020-10-15 19:15
*/
@Service("departmentService")
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
}
IService提供了所有通用常用的方法,包括批处理添加更新支持,以及lambda支持;
2.实例
大部分都是CRUD 就写两个
(1)updateById
Department department=new Department();
department.setId(8);
department.setName("牛逼2");
department.setRemark("12");
boolean save = departmentService.updateById(department);
System.out.println(save);
(2)saveBatch 批处理
默认1000条
Department department1=new Department();
department1.setName("牛逼1");
department1.setRemark("XX");
Department department2=new Department();
department2.setName("牛逼2");
department2.setRemark("XX2");
Department department3=new Department();
department3.setName("牛逼3");
department3.setRemark("XX3");
boolean b = departmentService.saveBatch(Arrays.asList(department1, department2, department3));
System.out.println(b);
11.Mybatis-plus 代码生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
1.使用方法
(1).添加 代码生成器 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
(2).添加 模板引擎 依赖
MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。
Velocity(默认):
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</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.2.2.RELEASE</version>
</dependency>
注意!如果选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。
AutoGenerator generator = new AutoGenerator();
// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());
// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());
// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());
// other config
...
(3).代码生成器代码
加了一点注解 但是还是官方文档介绍的的更好一点
https://mybatis.plus/guide/generator.html](https://mybatis.plus/guide/generator.html)
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("卢意");
gc.setOpen(false);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/db_mp?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent("com.luyi");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
/* // 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
*//*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
checkDir("调用默认方法创建的目录,自定义目录用");
if (fileType == FileType.MAPPER) {
// 已经生成 mapper 文件判断存在,不想重新生成返回 false
return !new File(filePath).exists();
}
// 允许生成模板文件
return true;
}
});
*//*
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
*/
/*// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);*/
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
//strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
//strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
// 写于父类中的公共字段
//strategy.setSuperEntityColumns("id");
strategy.setInclude("t_department");
//驼峰 strategy.setControllerMappingHyphenStyle(true);
// 表名前缀
strategy.setTablePrefix( "t_");
mpg.setStrategy(strategy);
//用默认引擎
// mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
效果图