文章目录
目录
一、mybatisPlus的介绍
1:mybatisPlus是mybatis的增强工具,所以在原本的mybatis中可以使用的语法在mybatisPlus基本上也是可以使用的。
2:在mybatisPlus中引入了 条件构造器:Wrapper 使得更加方便的进行开发
mybatisPlus官网:https://baomidou.com/
二、mybatisPlus的基础使用
配置
导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.9</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
配置文件(application.properties/yml)
这里以yml进行演示
spring:
datasource:
# 配置连接数据库的信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yourdatabase?characterEncoding=UTF-8
username: yourusername
password: yourpassword
# 配置mybatisPlus
mybatis-plus:
configuration:
# 输出sql语句的日志,效果就是在每次进行执行sql语句时会输出在控制板中
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
实体类的创建:
@TableName(value ="t_user")
@Data
public class User implements Serializable {
@TableId(value = "id",type = IdType.AUTO)
private Long id;
@TableField(value = "last_name")
private String lastName;
private String email;
private String gender;
private Integer age;
private Integer isDelete;
private Integer sex;
}
这里的两个注解的分别的意思是:
@TableName(value = “”):设置此实体类所绑定的库名
@TableId(value = “id”,type = IdType.AUTO):作用是将属性与数据库主键进行绑定
value:是指此主键的名、 type:设置默认填充的策略
这里只介绍两个:
AUTO:当设置此值时,并且在数据库中进行设置了主键自增的属性之后,则也数据库的自增为主,若是数据库没有设置则会报错
ASSIGN_ID(默认值):经过雪花算法所得的唯一id,注意此算法的出来的值因为过大所以一般都会将此id属性类型设置为Long类型
其他的策略在IDType枚举类中,如图:
Mapper配置
@Mapper
public interface UserMapper extends BaseMapper<User> {}
注意:这里的User是指你要绑定的表,不要设置错了,否则就会找不到数据源
BaseMapper的基本CURD(增删改查)
在mybatisPlus中提供了一些简单的API来进行实现基本的CURD(增删改查),具体的使用方法在下面的测试类代码中进行演示:
@SpringBootTest
public class demoTest {
@Autowired
private UserMapper userMapper;
// 添加数据:insert
@Test
public void testInsert(){
// 方法一:通过创建一个User对象进行添加
// 执行的sql语句为:INSERT INTO t_user ( last_name, gender, age ) VALUES ( ?, ?, ? )
User user = new User();
user.setAge(123);
user.setLastName("张三");
user.setGender("男");
user.setId(1L);
/*row为响应的行数*/
// int rows = userMapper.insert(user);
// 方法二:insertOrUpdate()此方法是更具主键id进行增加或修改,若是设置了重复的id值则会执行两条sql语句:一条查询一条update
System.out.println(userMapper.insertOrUpdate(user));
}
// 删除
@Test
public void testDelete(){
// 方式一:通过id进行删除数据
// sql语句:DELETE FROM t_user WHERE id=?
System.out.println(userMapper.deleteById(1877327132242313222L));
// 方式二:通过map进行删除:map中的key值就是字段名,value值就是你想要删除的某个字段的值
// sql语句: DELETE FROM t_user WHERE (last_name = ?)
HashMap<String, Object> map = new HashMap<>();
map.put("last_name","张三");
System.out.println(map);
System.out.println(userMapper.deleteByMap(map));
}
// 改
@Test
public void testUpdate(){
// 方式一:通过id进行修改,注意传的参数是实体类,此实体类中id是判断的id,其余的值为修改后的值
// sql语句: UPDATE t_user SET last_name=?, gender=?, age=? WHERE id=?
User user = new User();
user.setAge(123);
user.setLastName("张三");
user.setGender("男");
user.setId(2L);
System.out.println(userMapper.updateById(user));
}
// 查
@Test
public void testSelect(){
// 方式一:通过id进行查询
// sql语句: SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE id=?
System.out.println(userMapper.selectById(3));
// 方式二:通过map进行查询,返回的值为:list<T>
// sql语句: SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (gender = ?)
HashMap<String, Object> map = new HashMap<>();
map.put("gender","男");
System.out.println(userMapper.selectByMap(map));
}
}
三、wrapper(条件构造器)
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。
Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件的核心工具。
以下是主要的 Wrapper 类及其功能:
- wrapper: 是所有条件构造器的顶级父类,其主要实现类如下
- AbsractChainWrapper: 这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。
- QueryWrapper: 专门用于构造 查询(Query) 条件
- UpdateWrapper: 用于构造**更新(Update)**条件,可以在更新数据时指定条件。
- AbstractLambdaWrapper: 使用Lambda 语法
- LambdaUpdateWrapper: Lambda 更新封装Wrapper
- LambdaQueryWrapper: 用于Lambda语法使用的查询Wrapper
- AbsractChainWrapper: 这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。
继承关系示意图:
条件构造器(wrapper)通用API
使用范围为:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper
这里为了方便展示wrapper的API就拿QueryWrapper进行演示了
基础条件判断:
在mysql中的基础条件判断例如(>、<、=…),都被mybatisPlus中的条件构造器进行封装成了对应的API方法如下:
.gt():大于
.ge():大于等于
.gt():小于
.le():小于等于
.eq():等于
.ne():不相等
使用范围为:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper
具体用法如下:
/**
* 基础的条件判断(支持:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper)
*/
@Test
public void testWrapper(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句:SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (age > ? AND age >= ? AND age < ? AND age <= ? AND gender = ? AND last_name <> ?)
*/
queryWrapper.gt("age",17) //gt:大于
.ge("age",18) //ge:大于等于
.lt("age",99) //gt:小于
.le("age",100) //le:小于等于
.eq("gender","男")//查询gender是否等于男
.ne("last_name",null);//判断单个字段不相等的条件
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
进阶条件判断(in、like、between):
在mysql中有三个关键字(in、like、between),分别对应着条件构造器API中的:
between(boolean condition, R column, Object val1, Object val2)
: 范围匹配
between方法形参:val1:左边界值、val2:左边界值
like(boolean condition, R column, Object val)
:模糊匹配
like方法形参:val: 模糊匹配的值。
in(boolean condition, R column, Object... values)
: 取值匹配
in方法形参:values: 判断字段具体相等的值
共有形参:
boolean condition: 在这里是进行判断此方法是否执行,若为true则正常执行,若为false不执行,下面的也会有许多的方法会有此形参这里就一笔带过了。
R column: 表示需要进行条件判断的字段名
伴生API:
notBetween、notLike、notIn:这些API就是与对应的API进行逆向取值的意思
likeRight(右模糊匹配)、likeLeft(左模糊匹配),
具体用法如下:
/**
* 进阶条件判断(支持:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper)
* (相当于mysql中:between、like)
*/
@Test
public void testWrapper2(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为: SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (age BETWEEN ? AND ? AND last_name LIKE ? AND email LIKE ? AND last_name LIKE ?)
*/
queryWrapper.between(true,"age",0,18)//查询age在0到18【包括边界值】,最前面的boolean值是用来进行判断是否执行此between条件
.notBetween(false,"age",19,100)//与between相反,
.like(true,"last_name","小")//查询last_name字段包含"小"的所有字段
.notLike(false,"last_name","c")//与like相反
.likeLeft(true,"email","@qq.com")//满足左模糊匹配的字段对应的sql语句为: SELECT * FROM user WHERE emil LIKE '%@qq.com'
.likeRight(true,"last_name","李");//满座右模糊匹配的字段所对应sql为: SELECT * FROM user WHERE last_name LIKE '李%'
// /*同时也有:notLikeLeft、notLikeRight*/
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(queryWrapper);
}
/**
* 进阶2条件判断(支持:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper)
* (相当于mysql中:in)
*/
@Test
public void testWrapper3(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为:SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (age BETWEEN ? AND ? AND last_name LIKE ? AND email LIKE ? AND last_name LIKE ?)
*/
queryWrapper.isNull(true, "last_name")//判断是否为空
.in(true, "gender", "男", "女")//判断gender的值是否等于男或者女
.notIn(true, "age", Arrays.asList(1, 2));//与in方法相反,其中values值也可以使用arrays.asList进行赋值也就相当于使用数组进行赋值
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
高级条件判断一:(子查询(嵌套查询)groupBy having、order by)
在sql中的 子查询、group by having、order by 对应的API为:
一、子查询:~sql
~sql(boolean condition, R column, String ~Value)
:子查询,在sql中的子查询的意思在条件判断中嵌套一个查询sql,并且将此sql返回的值作为参数进行判断,而有因为此判断可以是基础条件判断等一系列的判断,就在条件构造器中派生了对应的API如:inSql、geSql、leSql…,其对应的sql语句为:SELECT * FROM yourBase WHERE column ~ ( ~Value )
形参:~value 的意思是需要进行嵌套的 子SQL语句
二、group by having:.groupBy()、.having()
方法.groupBy():groupBy(boolean condition, R column)
方法:.having():having(boolean condition, String sqlHaving, Object... params)
这两个方法所对应的就是mysql中的分组条件查询,
having的形参:
sqlHaving: 用来进行过滤分组的条件sql语句,还可以可以使用占位符进行标记,列如:age>{0}
params: 占位符所对应的参数。
**占位符使用注意:**占位符 要与 参数一一对应否则会直接报错
三、order by:
orderBy(boolean condition, boolean isAsc, R column)
:此方法对应值mysql中的order by关键字;
形参:isAsc 是判断是否需要ASC(升序)排序
(这里又伴生出来了两个方法:orderByAsc:默认升序、orderBYDesc:默认降序)
具体使用方法如下:
/**
* 高级条件判断(支持:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper)
* (相当于mysql中:子查询(嵌套查询),group by having,order by,)
*/
@Test
public void testWrapper4(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为:SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (id IN (select id from t_user where age>18)) ORDER BY age ASC
*/
queryWrapper
.inSql(true, "id", "select id from t_user where age>18")//子查询:将右边的sql语句进行执行,执行完返回的所有值,左与id进in条件判断
.notInSql(false, "id", "select id from t_user where age<=18")//与上面相反,执行的sql语句为:SELECT * FROM user WHERE id NOT IN (select id from t_user where age<=18)
/*
这里还有:eqSql:等于嵌套子查询、gtSql:大于~、lt:小于~、geSql:大于等于~、leSql:小于等于~。执行逻辑都和上面的inSql相似
*/
.orderBy(true, true, "age");//根据age进行升序排序:第一个参数是判断是否执行,第二个参数是判断是否进行升序,第三个参数是字段
/*
这里还有:orderByAsc:默认升序、orderBYDesc:默认降序
*/
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
@Test
public void testWrapper5(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为:SELECT count(*) FROM t_user GROUP BY age HAVING sum(age) >= ?
*/
queryWrapper
.groupBy(true, "age")//更具性别进行分组,总共分两组:男、女。 (注意:这里可以不止更具一个字段进行分组,可以设置多个但不常用) sql语句为:SELECT gender FROM t_user GROUP BY gender;
.having(true, "sum(age) >= {0}", 18)//更具分组后的数据进行过滤,sum(age)>=1;这里的{0},代表的是占位符其中的0就是后面的参数的第一位(注意占位符和参数必须保持一致),sql语句为:SELECT * FROM t_user GROUP BY ... HAVING sum(age) > 10
.select("age");//查询的某个单独的字段,这里因为用到了groupBy having,所以尽量将分组的字段和查询的字段保持一致,或者查询其他的逻辑运运算值(如:count),否则可能会报错:SQL 查询与 MySQL 的 only_full_group_by SQL 模式不兼容。
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
高级条件判断二:(func(函数)、and、or)
func(函数)、and、or这三个是条件构造器中的API有了这些方法可以更加的灵活的执行sql语句
一、func(函数)
概念: 它提供了一种在链式调用中根据条件执行不同查询操作的机制。通过传入一个 Consumer 函数式接口,func 方法允许你在不中断链式调用的情况下,根据条件执行不同的查询构建逻辑。
方法签名:func(boolean condition, Consumer<Children> consumer)
二、or、and
**概念:**看到这里并且敲代码尝试的话,会发现,不管使用ge\lt等方法默认的连接条件就是and,所以这里条件构造器就派生出了两个API就是:or、and。
**方法签名:and\or(boolean condition, Consumer<Children> consumer)
共有形参consumer:一个 Consumer 函数式接口,它接受一个 Children 类型的参数,并可以调用 Children 对象上的方法来构建查询条件。
(这里看着可能并不理解,可以直接看下面的代码以及注释,会明了一些)
/**
* 高级条件判断 3(支持:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper)
* (是mybatisPlus中创建的方法:func、and、or。有了这些方法可以更加的灵活的执行sql语句)
*/
@Test
public void testFunc(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为:SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (last_name = ?)
*/
queryWrapper.func(true,i -> {
if (true){
i.eq("last_name","小红");//这里因为条件一直恒等于true所以会执行此方法
}else {
i.ne("last_name","小红");
}}//此方法结合lambda[此时的参数i也就是queryWrapper对象,可以执行里面的方法]进行从而可以在执行sql语句前,执行一些其他的操作列如:判断、循环(不推荐),
);
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
@Test
public void testAnd(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
/*
sql语句为:SELECT id,last_name,email,gender,age,is_delete,sex FROM t_user WHERE (age >= ? AND (last_name LIKE ?) OR (email LIKE ?))
*/
queryWrapper.ge("age",100)
.and(true,i ->{//进行and的条件运算,对应的sql语句为:SELECT * FROM t_user WHERE (age>=100 AND (last_name like '%1%'));
i.like("last_name","1");
})
.or(true,j -> {//进行or条件运算,对应的sql语句为:SELECT * FROM t_user WHERE (......) OR (email like '%@qq.com')
j.likeLeft(true,"email","@qq.com");
});//此时的or是和前面的ge和and方法做or运算:(... where (age>=100 and (last_name like '%1%')) or (email like '%@qq.com') ),所以or里面的条件满足而上面的条件不满足也是可以查询出来的,
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
条件构造器(Wrapper)特殊API
使用范围并不是通用的。
只适用于lambdaQueryWrapper和QueryWrapper的Api有:select
只适用于lambdaUpdateWrapper和UpdateWrapper的Api:set、setSql
在mybatisPlus3.5.9:所更新的API:
只适用于lambdaUpdateWrapper和UpdateWrapper:setDecrBy、setIncrBy
如以下代码所示:
// 只适用于lambdaQueryWrapper和QueryWrapper的Api
@Test
public void testQuery(){
// sql语句为: SELECT id,age,email FROM t_user
// 一、select:用于查询单独某一个字段的api
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id","age","email");
System.out.println(userMapper.selectList(queryWrapper));
}
// 只适用于lambdaUpdateWrapper和UpdateWrapper的Api
@Test
public void testUpdate(){
// sql语句为:UPDATE t_user SET sex=? WHERE (age > ?)
// 一、set,用于修改某个字段的值
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper.gt("age",18)//修改条件
.set(true,"sex",1);
System.out.println(userMapper.update(userUpdateWrapper));
// sql语句为:UPDATE t_user SET last_name=? WHERE (age < ?)
// 二、setSql,若是修改的字段过于繁琐复杂,可以直接写入sql语句,将写好的sql语句进行拼接到set关键字之后
UpdateWrapper<User> userUpdateWrapper2 = new UpdateWrapper<>();
userUpdateWrapper2.lt("age", 18)//修该条件
.setSql(true, "last_name={0}", "张三");//进行拼接的sql
System.out.println(userMapper.update(userUpdateWrapper2));
}
// 只适用于lambdaUpdateWrapper和UpdateWrapper的Api(注意这些API的适用的mybatisPlus的版本为:3.5.9)
@Test
public void testLambdaUpdate(){
// sql语句为:UPDATE t_user SET age=age - 2 WHERE (age > ?)
// 一、setDecrBy方法是在指定的字段的基础上进行递减:val
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.gt(User::getAge, 35)//更新条件
.setDecrBy(true, User::getAge, 2);
// System.out.println(userMapper.update(lambdaUpdateWrapper));
// sql语句为:UPDATE t_user SET age=age + 2 WHERE (age > ?)
// 二、setIncrBy方法是在指定的字段的基础上进行累加:val
LambdaUpdateWrapper<User> lambdaUpdateWrapper2 = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper2.gt(User::getAge, 35)//更新条件
.setIncrBy(true, User::getAge, 2);
System.out.println(userMapper.update(lambdaUpdateWrapper2));
}
这里是条件构造器中的大部分API,其中还有一些api并没有列举出来,要是找不到的话可以去官网mybatisPlus:https://baomidou.com/guides/wrapper/ 中进行查询