一、Mybatis-Plus简介
(一)什么是Mybatis-Plus
Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发。 (最常见的简单SQL不用编写,只需要让自己的Mapper接口继承BaseMapper接口即可)
(二)Mybatis-Plus的优势
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响。
- 损耗小:启动即会自动注入基本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 操作智能分析阻断,也可自定义拦截规则,预防误操作。
(三)Mybatis-Plus框架结构:
右边框框里的为mybatis-plus的结构:annotation(注解)、extension(扩展)、core(核心)、generator(代码生成器)、mybatis-plus-boot-starter(springboot启动器)。左边为mybatis-plus的原理。
二、lombok的简介与使用
mybatis-plus可以开启使用Lombok,关于Lombok的简介和使用,我以前的博客有写到。这是链接:Lombok的简介与使用以及总结_lombok插件是免费的吗-CSDN博客文章浏览阅读213次。本章目录前言一、Lombok简介二、Lombok使用1、加入maven依赖2、常用注解介绍@Date@Getter/@Setter@NonNull@EqualsAndHashCode@NoArgsConstructor, @RequiredArgsConstructor 和 @AllArgsConstructor@Slf4j三、总结前言 我们在开发中经常需要花很多时间给JavaBean的属性写getter/se_lombok插件是免费的吗https://blog.csdn.net/xzys430/article/details/108864096
三、swagger的简介与使用
mybatis-plus还可以开启swagger,关于swagger的简介与使用,我以前的博客也写了。这里是链接:swagger的简介和使用(SpringBoot整合)_swagger的作用是什么以及他和springboot怎么整合-CSDN博客文章浏览阅读266次,点赞4次,收藏2次。SpringBoot整合swagger)swagger简介swagger整合swagger1、添加依赖2、编写swagger配置类swagger注解一般我在开发的时候写接口文档感觉比较麻烦,所以就想到使用swagger来统一管理,而且swagger还可以用来构建和测试接口。swagger简介Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。它可以在线生成接口文档以及在线测试,就不需要自己去浏览器输请求或者用postman测试接口了。sw_swagger的作用是什么以及他和springboot怎么整合https://blog.csdn.net/xzys430/article/details/108727362
四、CRUD接口:
1、BaseMapper CRUD 接口
说明:
- 通用 CRUD 封装BaseMapper接口,为Mybatis-Plus启动时自动解析实体表关系映射转换为Mybatis内部对象注入容器
- 泛型 T 为任意实体对象
- 参数Serializable 为任意类型主键Mybatis−Plus不推荐使用复合主键, 约定每一张表都有自己的唯一 id 主键
- 对象 Wrapper为 条件构造器
BaseMapper-CRUD官方文档:
https://mybatis.plus/guide/crud-interface.html#mapper-crud-%E6%8E%A5%E5%8F%A3
五、测试案例:
5.1..引入依赖:
<!--mybatis-plus(springboot版)-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.2.0</version>
</dependency>
<!--引入Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>
<!-- springBoot框架的其他依赖如下: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>${spring-boot.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
<version>${spring-boot.version}</version>
</dependency>
<!--工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
5.2.建表:
create database test char set utf8;
use test;
CREATE TABLE IF NOT EXISTS user(
id INT UNSIGNED AUTO_INCREMENT COMMENT '主键id',
name VARCHAR(8) NOT NULL COMMENT '姓名',
age int(3) NOT NULL COMMENT '年龄',
address VARCHAR(40) COMMENT '住址',
create_date DATE COMMENT '创建时间',
PRIMARY KEY ( id )
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO test.user (id, name, age, address, create_date)
VALUES (1, 'zs', 19, 'xian', '2024-05-10');
INSERT INTO test.user (id, name, age, address, create_date)
VALUES (2, 'ls', 20, 'yanan', '2024-05-10');
INSERT INTO test.user (id, name, age, address, create_date)
VALUES (3, 'wangwu', 21, 'baoji', '2024-05-10');
5.3.实体类:
package com.zyq.mybatisPlusDemo.pojo.entity;
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("users")//当表名跟实体类类名不一致时,要使用@TableName注解进行映射
public class User {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
//Mybatis-Plus默认采用雪花算法生成唯一值。
//在MyBatis-Plus中,要启用自增主键,你需要在你的实体类中的主键字段上使用@TableId注解,并将其type属性设置为IdType.AUTO。
//这会告诉MyBatis-Plus使用数据库的自增机制来处理主键。
//VO(View/Value Object)—— 视图对象
//DTO(Data Transfer Object)—— 数据传输对象
//BO(Business Object)—— 业务对象
//PO(Persistent Object)—— 持久对象
//DO(Data/Domain Object)—— 数据/领域对象
//POJO(Plain Old/Ordinary Java Object)—— 以上模型的统称
5.4.application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
#spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
# 解决循环依赖的问题
spring.main.allow-circular-references=true
spring.datasource.name=test
## 配置连接池信息
## 初始化大小,最小,最大
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=30
## 配置获取连接等待超时的时间
spring.datasource.druid.max-wait=60000
## 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
# spring.datasource.druid.time-between-eviction-runs-millis=60000
## 配置一个连接在池中最小生存的时间,单位是毫秒
# spring.datasource.druid.min-evictable-idle-time-millis=300000
# spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
# spring.datasource.druid.test-while-idle=true
#spring.datasource.druid.test-on-borrow=false
#spring.datasource.druid.test-on-return=false
#spring.datasource.druid.pool-prepared-statements=true
#spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
## 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
#spring.datasource.druid.filters=stat,wall
## 通过connectProperties属性来打开mergeSql功能;慢SQL记录
#spring.datasource.druid.connection-properties=druid.stat.mergeSql=true
#spring.datasource.druid.filter.stat.slow-sql-millis=5000
## 超过时间限制是否回收
#spring.datasource.druid.remove-abandoned=true
## 超时时间;单位为秒。180秒=3分钟
#spring.datasource.druid.remove-abandoned-timeout-millis=180
## 关闭abanded连接时输出错误日志
#spring.datasource.druid.log-abandoned=true
# mybatis-plus 默认扫描mapper.xml的目录
mybatis-plus.mapper-locations=classpath*:/mappers/*.xml
#配置sql打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 全局的slf4j配置 (slf4j是lombok框架提供的log4j工具)
logging.level.root=WARN
## 局部的slf4j配置
#logging.level.com.zyq.mybatisPlusDemo=DEBUG
logging.level.com.zyq.mybatisPlusDemo=INFO
#slf4j的日志级别 ERROR>WARN>INFO>DEBUG>TRACE
5.5.主启动类:
package com.zyq.mybatisPlusDemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zyq.mybatisPlusDemo.mapper")
public class MainClass {
public static void main(String[] args) {
SpringApplication.run(MainClass.class, args);
}
}
5.6.UserMapper接口:
package com.zyq.mybatisPlusDemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zyq.mybatisPlusDemo.pojo.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
5.7.测试类:
package com.zyq.mybatisPlusDemo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zyq.mybatisPlusDemo.mapper.UserMapper;
import com.zyq.mybatisPlusDemo.pojo.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
public class MainClassTest {
@Autowired(required = false)
UserMapper userMapper;
//一、查询
@Test
public void test1_getAll() {
List<User> userList=userMapper.selectList(null);
System.out.println(userList);
}
@Test
public void test2_selectById() {
User u=userMapper.selectById(4);
System.out.println("selectById" + u );
}
@Test
public void test3_selectBatchIds() {//selectBatchIds: 批量查询指多个id的记录集合
List ids= Arrays.asList( 1,2,3);
List<User> users=userMapper.selectBatchIds(ids);
System.out.println("selectBatchIdsIds" + users );
}
@Test
public void test4_selectByMap() {//selectByMap方法: 根据Map集合中传入的条件进行查询,每个条件都是and关系
Map<String, Object> map=new HashMap<>();
map.put("age",22);
map.put("name","赵六6");
List<User> users=userMapper.selectByMap(map);
System.out.println("selectByMap" + users );
}
@Test
public void test4_selectCount() {//selectByMap方法: 根据Map集合中传入的条件进行查询,每个条件都是and关系
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//年龄20-30之间的
wrapper.between("age",20,30);
//wrapper.eq("del_flag",0);//删除标志为0
//创建时间降序
//wrapper.orderByDesc("create_time");
Integer rs=userMapper.selectCount(wrapper);
System.out.println("selectCount::" + rs );
}
//二、添加
@Test
public void test5_addOne() {
/*User u=new User(4, "赵六", 29);
userMapper.insert(u);
System.out.println("添加User对象 " + u +"成功");*/
//在User类中的主键字段上使用@TableId注解,并将其type属性设置为IdType.AUTO。可以启动mysql的主键自增效果,
//并且可以在User对象没有主键的情况下插入成功,同时还可以获取此user对象生成的主键值
User u=new User("赵六6", 22);
userMapper.insert(u);
System.out.println("添加User对象 " + u +"成功,id为:"+ u.getId());
}
//三、删除:
@Test
public void test6_deleteById() {
int rows=userMapper.deleteById(5);
System.out.println("删除的行数:"+ rows);
}
@Test
public void test7_deleteByMap() {//deleteByMap方法: 根据Map中的条件进行删除,map中的条件在sql语句中是and关系
Map<String, Object> map=new HashMap<>();
map.put("age",22);
map.put("name","赵六6");
int rows=userMapper.deleteByMap(map);
System.out.println("test7_deleteByMap删除的行数:"+ rows);
}
//deletebatchIds方法: 根据传入List集合中的id进行批量删除
@Test
public void test3_deleteBatchIds() {//selectBatchIds: 批量查询指多个id的记录集合
List ids= Arrays.asList( 5,6);
int rows=userMapper.deleteBatchIds(ids);
System.out.println("test3_deleteBatchIds删除的行数:"+ rows);
}
//四、修改
@Test
public void test3_updateOne() {
User u=new User(4, "赵六zhaoL", 24);
userMapper.updateById(u);
System.out.println("更新" + u +"对象成功");
}
//更新操作中可以用MyBatisPlus框架提供的UpdateWrapper提供的方法作为更新条件,并将UpdateWrapper对象传入到update方法中使用
@Test
public void test3_updateWrapper() {
User u=new User(4, "赵六zhaoL", 240);
userMapper.update(u, new UpdateWrapper<User>().eq("name","赵六zhaoL") );
u=userMapper.selectById(4);
System.out.println("更新" + u +"对象成功");
}
}
//Mybatis-Plus默认采用雪花算法生成唯一值。
//在MyBatis-Plus中,要启用自增主键,你需要在你的实体类中的主键字段上使用@TableId注解,并将其type属性设置为IdType.AUTO。
//这会告诉MyBatis-Plus使用数据库的自增机制来处理主键。
注意: 如果项目测试类运行时报异常Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference?
可以尝试给配置文件application.properties中添加如下配置,看是否能解决问题
spring.main.allow-circular-references=true
六、BaseMapper的CRUD方法:
6.1.BaseMapper的方法
BaseMapper中提供了CRUD方法,具体方法如下:
// 插入一条记录
int insert(T entity);
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page,
@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
6.2.Wrapper接口的方法
Wrapper接口的常用 方法
案例一:根据name模糊查看未删除的用户列表信息
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//name不为空时,组装模糊查询条件
wrapper.like(StringUtils.isNotBlank(name),"name",name);
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例二:查看姓李的并且邮箱不为空的用户列表
sql实现:
select * from t_user
where del_flag = 0
and name like concat('李','%')
and email is not null
order by create_time desc
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//姓张的
wrapper.likeRight("name","张");
//邮箱不为空
wrapper.isNotNull("email");
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例三:年龄范围查询(20-30之间的)
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//年龄20-30之间的
wrapper.between("age",20,30);
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例四:根据createTime查看当日的用户列表
sql实现:
select * from t_user
where del_flag=0
and DATE(create_time) = STR_TO_DATE('2021-08-13','%Y-%m-%d')
order by create_time desc
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//查询条件为创建时间
wrapper.apply(StringUtils.isNotBlank(createTime),"DATE(create_time) = STR_TO_DATE('"+createTime+"','%Y-%m-%d')");
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例五:查看某个时间段内的用户列表
select * from t_user
where del_flag=0
and DATE(create_time) >= STR_TO_DATE('2021-08-01','%Y-%m-%d')
AND DATE(create_time) <= STR_TO_DATE('2021-08-13','%Y-%m-%d')
order by create_time desc
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//查询条件为创建时间
wrapper.apply(StringUtils.isNotBlank(startTime),"DATE(create_time) >= STR_TO_DATE('"+startTime+"','%Y-%m-%d')");
wrapper.apply(StringUtils.isNotBlank(endTime),"DATE(create_time) <= STR_TO_DATE('"+endTime+"','%Y-%m-%d')");
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例六:查询姓李的并且邮箱不为空或者是年龄大于16的用户
sql实现:
select * from t_user
where del_flag=0
and name like concat('李','%')
and (email is not null or age>16)
order by create_time desc
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//and方法嵌套
wrapper.likeRight("name","李").and(
userQueryWrapper -> userQueryWrapper.isNotNull("email")
.or().lt("age",16)
);
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
案例七:查询id为1,2,3的用户列表信息
sql实现:
select * from t_user
where del_flag=0
and id in(1,2,3)
order by create_time desc
//构建一个查询的wrapper
QueryWrapper<User> wrapper = new QueryWrapper<User>();
if(StringUtils.isNotBlank(ids)){
//字符串转数组再转List
Collection<String> collection = Arrays.asList(ids.split(","));
//in方法
wrapper.in(collection.size()>0,"id",collection);
}
//未删除
wrapper.eq("del_flag",0);
//创建时间降序
wrapper.orderByDesc("create_time");
List<User> list = userMapper.selectList(wrapper);
来自于gitcode上作者的案例代码:
Wrap条件构造器演示案例:
(一)条件构造器介绍:
在mybatis-plus中提了构造条件的类Wrapper,它可以根据自己的意图定义我们需要的条件。Wrapper是一个抽象类,一般情况下我们用它的子类QueryWrapper来实现自定义条件查询。
1.1.普通查询方法测试:
package com.zyq.mybatisPlusDemo.test;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyq.mybatisPlusDemo.mapper.UserMapper;
import com.zyq.mybatisPlusDemo.pojo.entity.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;
import java.util.function.Consumer;
@SpringBootTest
public class Test2 {
@Autowired(required = false)
UserMapper userMapper;
//一、查询
@Test
public void test1_selectOne() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name","zs");
queryWrapper.eq("age",19);
User u=userMapper.selectOne(queryWrapper);
System.out.println("selectOneWrapper:"+u);
}
@Test
public void test2_selectList() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.like("name","z").lt("age",20);
List<User> userList=userMapper.selectList(queryWrapper);
System.out.println("selectListWrap:"+userList);
}
@Test
public void test3_selectList2() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
//左边随意右边为s
queryWrapper.likeLeft("name","s").or().eq("age",19).orderByDesc("age");
List<User> userList=userMapper.selectList(queryWrapper);
System.out.println("selectList2Wrap:"+userList);
}
@Test
public void test3_selectList3() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
//右边随意左边为z
queryWrapper.likeRight("name","z").and(wq->wq.lt("age",35).or().isNotNull("address") );
/*Consumer<QueryWrapper<User>> consumer=new Consumer<QueryWrapper<User>>(){
public void accept(QueryWrapper<User> wq) {
wq.lt("age",35).or().isNotNull("address");
}
};
queryWrapper.likeRight("name","z").and(consumer);*/
//上边的内部类可以简化为下边的lambda的形式
queryWrapper.likeRight("name","z").and(wq->wq.lt("age",35).or().isNotNull("address") );
List<User> userList=userMapper.selectList(queryWrapper);
System.out.println("selectList3Wrap:"+userList);
}
}
1.2.SelectPage方法:
SelectPage用于分页,在Mybatis-Plus中分页有两种:一种是逻辑分页或叫内存分页,另一个是物理分页。内存分页就是把数据全部查询出来放到内容中,返回你想要的一部分数据,当数据量非常庞大时,这种方法就行不通了,因为太耗内容,所以一般采用物理分页,需要SpringMVC中加入物理分页配置:
A.配置类:
package com.zyq.mybatisPlusDemo.config;
import com.baomidou.mybatisplus.annotation.DbType;
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 interceptor=new MybatisPlusInterceptor();
interceptor.addInnerInterceptor( new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
B.测试 代码:
在com.zyq.mybatisPlusDemo.test.Test2类中写如下测试方法:
@Test
public void test4_selectPage() {
//1.创建查询条件QueryWrapper
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.lt("age",35);
//2.创建分页对象
Page<User> page=new Page<>(1,2);//从第2页开始,每页2条数据
//3.调用userMapper的selectPage查询方法
Page<User> selectPage=userMapper.selectPage(page,queryWrapper);
System.out.println("当前页码:"+selectPage.getCurrent());
System.out.println("每页记录数:"+selectPage.getSize());
System.out.println("总记录数:"+selectPage.getTotal());
System.out.println("总页数:"+selectPage.getPages());
List<User> userList=selectPage.getRecords();
System.out.println("记录数据:"+ userList);
/*Consumer<User> consumer=new Consumer<User>(){
public void accept(User user) {
System.out.println(user);
}
};
userList.forEach(consumer);*/
//匿名内部类可以简写为lambda格式: 方法参数名保留,后边写 -> 匿名 内部类中的方法写成代码块形式
//userList.forEach( user -> { System.out.println(user); } );
//可以简写为下边格式 ( 匿名内部类方法中只有一个参数可以省略参数不写,匿名内部类方法中只有一句代码则大括号也可以省略 )
//知识打印匿名内部类方法中参数的值,则可以将打印语句省略为System.out::println格式。
userList.forEach(System.out::println);
}
1.3.删除和修改:
//二、删除操作
@Test
public void test5_delete() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name","赵六6").eq("age",22);
int rows=userMapper.delete(queryWrapper);
System.out.println("delete删除的记录个数:"+rows);
}
//三、修改操作
@Test
public void test5_update() {
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name","zhaoliu6").lt("age",300);
User u=new User();
u.setId(5).setName("赵六6").setAge(22);
int rows=userMapper.update(u, queryWrapper);
System.out.println("修改的记录个数:"+rows);
}
七、常用注解说明:
7.1. @TableName注解:
描述:表名注解。 当表名跟实体类类名不一致时,要使用@TableName注解进行映射
7.2.@TableId注解
描述:主键注解。 经常用于数据库自增策略 ( 默认使用雪花算法生成id的数字值 )
@TableId(type=IdType.AUTO)
type的值用IdType枚举类的常量来赋值,常量值如下:
IdType枚举类的常量值:
7.3.@TableField注解:
描述:字段注解(非主键)。 通常用于表的列名和类名属性不一致时,进行映射的。
八、MyBatisplus自动生成Service代码:
用法较少,一般都要自己Service层代码并添加一些业务逻辑(下边方法没有业务逻辑,只是调用BaseMapper的CRUD方法, 而且不能添加wrapper条件对象, 可以选择性的使用MyBatisPlus中简单的方法,如果需要更复杂的方法时就自己编写<这样简单的方法就不用编写了,业务逻辑复杂的自己编写>)
8.1.通用service简介
Mybatis-Plus除了通用的Mapper还有通用的Servcie层,这也减少了相对应的代码工作量,把通用 的接口提取到公共类。其实按照MP的这种思想,可以自己也实现一些通用的Controller。
8.2.通用service常用方法介绍
/**
* 插入一条记录(选择字段,策略插入)
*
* @param entity 实体对象
*/
default boolean save(T entity) {
return SqlHelper.retBool(getBaseMapper().insert(entity));
}
/**
* 根据 ID 选择修改
*
* @param entity 实体对象
*/
default boolean updateById(T entity) {
return SqlHelper.retBool(getBaseMapper().updateById(entity));
}
/**
* TableId 注解存在更新记录,否插入一条记录
*
* @param entity 实体对象
*/
boolean saveOrUpdate(T entity);
/**
* 根据 Wrapper,查询一条记录 <br/>
* <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT
1")</p>
*
* @param queryWrapper 实体对象封装操作类 {@link
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default T getOne(Wrapper<T> queryWrapper) {
return getOne(queryWrapper, true);
}
/**
* 根据 Wrapper,查询一条记录
*
* @param queryWrapper 实体对象封装操作类 {@link
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param throwEx 有多个 result 是否抛出异常
*/
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
8.4.案例:
A.Service接口:
package com.zyq.mybatisPlusDemo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zyq.mybatisPlusDemo.pojo.entity.User;
public interface UserService extends IService<User> {
}
B.Service实现类:
package com.zyq.mybatisPlusDemo.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyq.mybatisPlusDemo.mapper.UserMapper;
import com.zyq.mybatisPlusDemo.pojo.entity.User;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
}
C.测试类:
package com.zyq.mybatisPlusDemo.testService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyq.mybatisPlusDemo.pojo.entity.User;
import com.zyq.mybatisPlusDemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class TestService {
@Autowired(required = false)
UserService userService;
@Test
public void test1_Save(){
User u=new User();
u.setName("孙来宝").setAge(30);
userService.save(u);
}
@Test
public void test2_SaveOrUpdate(){
User u=new User();
u.setName("孙来宝").setAge(40);
userService.saveOrUpdate(u);
}
@Test
public void test3_GetOne(){
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.lt("id",2);
User u = userService.getOne(queryWrapper,false);
System.out.println(u);
}
}
九、MybatisPlus代码生成器:
(一)代码生成器介绍:
代码生成器顾名思义就是为我们生成一些代码,省去了我们一些时间。AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率,MyBatis-Plus从3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖,才能实现代码生成器功能。
(二)构建maven工程,引入依赖
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>${spring-boot.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
<version>${spring-boot.version}</version>
</dependency>
<!--工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<!-- <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>-->
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<!--mybatis-plus(springboot版)-->
<!--mybatis-plus(springboot版)-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>
<!--<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.2.0</version>
</dependency>-->
<!-- 添加MySQL JDBC依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<!--依赖版本要与你创建的springboot项目的版本对应-->
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
(三)编写生成器代码类:
package com.zyq.plus;
import com.baomidou.mybatisplus.annotation.DbType;
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.rules.NamingStrategy;
public class PlusGenerateClass {
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("zyq");//设置作者
gc.setOpen(false);//生成是后是否打开资源管理器
gc.setFileOverride(false);//重新生成文件时是否覆盖
gc.setServiceName("%sService");
// gc.setSwagger2(true); 实体属性 Swagger2 注解
//2.配置gc给mpg
mpg.setGlobalConfig(gc);
//二、数据源配置(将dsc设置给mpg):
//1.创建数据源配置对象
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("test");//设置数据库名
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL);
//将创建数据源配置对象dsc设置给mpg
mpg.setDataSource(dsc);
//三、包配置对象封装包的信息(将包配置对象pc设置给mpg)
PackageConfig pc = new PackageConfig();
pc.setModuleName(null);
pc.setParent("com.zyq.plus");
pc.setController("controller");
pc.setEntity("entity");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
//四、策略配置对象, 策略配置对象封装XX信息(将策略配置对象strategy设置给mpg)
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("users");//对那一张表生成代码
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作
strategy.setRestControllerStyle(true); //restful api风格控制器
strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
mpg.setStrategy(strategy);
mpg.execute();
}
}
(四)、编写主启动类:
在主启动类上用@MapperScan扫描mapper接口
@MapperScan("com.zyq.plus.mapper")
package com.zyq.plus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zyq.plus.mapper")
public class PlusDemoMain {
public static void main(String[] args) {
SpringApplication.run(PlusDemoMain.class, args);
}
}
(五)配置application.yml配置文件:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
logging:
level:
com:
zyq:
plus: debug
(六).UserController中添加方法
package com.zyq.plus.controller;
import com.zyq.plus.entity.User;
import com.zyq.plus.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**前端控制器*/
@RestController
@RequestMapping("/users")
public class UserController {
// localhost:8080/users/userList
@Autowired
private UsersService usersService;
@RequestMapping("/userList")
@ResponseBody
public List<User> userList() {
return usersService.list();
}
}
(七)启动并访问:
7.1.去掉pom.xml中代码生成器的依赖:
<!--mybatis-plus代码生成器-->
<!--<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>-->
<!--velocity模板-->
<!-- 解释一下为什么要引两个模板依赖:
因为plus代码生成器需要一个模板引擎,velocity和freemarker任选一个,velocity是生成器中默认使用的,根据你的选择引依赖。 -->
<!--freemarker模板-->
<!--<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>-->
<!--<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>-->
7.2.启动项目主类PlusDemoMain:
7.3.用下边地址在浏览器中访问项目:
(十).新版mybatisplus代码生成器
官方文档: 代码生成器(新) | MyBatis-Plus (baomidou.com)https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8
1.降低mysql依赖版本:
mysql的驱动依赖需要修改为低版本,否则可能会报异常:Unable to load authentication plugin 'auth_gssapi_client'.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
2.mybatis-plus的新版本依赖:
修改如下两个依赖的版本
<!--mybatis-plus(springboot版)-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.6</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.6</version>
</dependency>
此问题还可能时因为mysql的密码加密方式的问题(需要在mysql命令行中修改mysql的密码加密方式)
MySQL 8.0之后默认采用了更加安全的用户密码验证方式
MySQL 驱动无法使用 'auth_gssapi_client' 认证插件连接到 MySQL 服务器,需要将 MySQL 服务器的认证插件更改为 'mysql_native_password'。
操作如下:
进入mysql用下边命令查询:
use mysql;
select user,host,plugin,authentication_string from user;
alter user 'root' @'localhost' identified with mysql_native_password by 'mysql数据库的密码';
用上边命令将红色plugin的值修改为 mysql_native_password
注意: 如果select user,host,plugin,authentication_string from user;查询root用户的plugin的值如果是
mysql_native_password, 就不需要用这几条命令修改mysql。
注: 尽量修改项目配置或项目的mysql依赖,而不要修改mysql。
3.生成代码的类:
package com.zyq.plus;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GenerateMain {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?&useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai","root","root")
// 全局配置
.globalConfig((scanner, builder) -> builder.author(scanner.apply("请输入作者名称?"))
/*.fileOverride()*///fileOverride表示覆盖已生成文件,已经被新版的mybatisplus弃用了
//.outputDir("D:\\idea-workspace\\_09_mybatisplus_generate_new\\src\\main\\java"))
.outputDir(System.getProperty("user.dir")+"\\src\\main\\java"))
//System.getProperty("user.dir")用于获取项目路径: D:\idea-workspace\_09_mybatisplus_generate_new
// 包配置
.packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")).pathInfo(Collections.singletonMap(OutputFile.xml,System.getProperty("user.dir")+"/src/main/resources/mapper")))
// 策略配置
.strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
.entityBuilder()
.enableLombok()
.addTableFills(
new Column("create_time", FieldFill.INSERT)
)
.enableChainModel()
.naming(NamingStrategy.underline_to_camel)//数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
.columnNaming(NamingStrategy.underline_to_camel)//表字段映射实体属性命名规则:默认null,不指定按照naming执行
.idType(IdType.AUTO)//添加全局主键类型
.formatFileName("%s")//格式化实体名称,%s取消首字母I,
.mapperBuilder()
.enableMapperAnnotation()//开启mapper注解
.enableBaseResultMap()//启用xml文件中的BaseResultMap 生成
.enableBaseColumnList()//启用xml文件中的BaseColumnList
.formatMapperFileName("%sMapper")//格式化Dao类名称
.formatXmlFileName("%sMapper")//格式化xml文件名称
.serviceBuilder()
.formatServiceFileName("%sService")//格式化 service 接口文件名称
.formatServiceImplFileName("%sServiceImpl")//格式化 service 接口文件名称
.build())
/*
模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
.templateEngine(new BeetlTemplateEngine())
.templateEngine(new FreemarkerTemplateEngine())
*/
.execute();
}
// 处理 all 情况
protected static List<String> getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
}
4.主启动类:
package com.zyq.plus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zyq.plus.mapper")
public class PlusDemoMain {
public static void main(String[] args) {
SpringApplication.run(PlusDemoMain.class, args);
}
}
5.配置application.yml配置文件:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
logging:
level:
com:
zyq:
plus: debug
6.UsersController中添加方法:
package com.zyq.plus.controller;
import java.util.List;
import com.zyq.plus.entity.Users;
import com.zyq.plus.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**前端控制器*/
// localhost:8080/users/userList
@RestController
@RequestMapping("/users")
public class UsersController {
@Autowired(required = false)
private UsersService usersService;
@RequestMapping("/userList")//@ResponseBody
public List<Users> userList() {
return usersService.list();
}
}
7.运行项目主启动类:
8.浏览器访问:
访问地址: localhost:8080/users/userList
原文链接:https://blog.csdn.net/m0_67296957/article/details/131723536