1792| 6
|
[学习记录] MybatisPlus |
发表于 2022-6-12 08:17
演示代码
3. 查询==3.1 分页查询==3.1.1 实现
3.1.2 常见问题
3.2 开启
|
方法 | 功能 | 备注 |
---|---|---|
eq | 指定列的值相同 | equals的简写 |
ne | 指定列的值不相同 | not equals的简写 |
lt | 指定列的值小于 | less then的简写 |
le | 指定列的值小于等于 | less then and equals的简写 |
gt | 指定列的值大于 | great then 的简写 |
ge | 指定列的值大于等于 | great then and equals的简写 |
between | 指定列的值在..和…之间 | |
notBetween | 指定列的值不在..和…之间 | |
like | 指定列的值等值模糊查询 | |
notLIke | 指定列的值不等值模糊查询 | |
orderByAsc | 按照指定的列升序排序 | |
orderByDesc | 按照指定的列降序排序 | |
groupBy | 按照指定的列分组 | |
having | 按照指定的列在分组后条件过滤 | |
in | 单条件多值查询 | |
isNull | 指定列的值为空 | |
isNOtNull | 指定列的值不为空 |
用户登录(eq匹配)
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//等同于=
lqw.eq(User::getName, "Jerry").eq(User::getPassword, "jerry");
User loginUser = userDao.selectOne(lqw);
System.out.println(loginUser);
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//范围查询 lt le gt ge eq between
lqw.between(User::getAge, 10, 30);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//模糊匹配 like
lqw.likeLeft(User::getName, "J");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
QueryWrapper<User> qw = new QueryWrapper<User>();
qw.select("gender","count(*) as nums");
qw.groupBy("gender");
List<Map<String, Object>> maps = userDao.selectMaps(qw);
System.out.println(maps);
官方API
文档
手动判空
Integer minAge=10; //将来有用户传递进来,此处简化成直接定义变量了
Integer maxAge=null; //将来有用户传递进来,此处简化成直接定义变量了
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
if(minAge!=null){
lqw.gt(User::getAge, minAge);
}
if(maxAge!=null){
lqw.lt(User::getAge, maxAge);
}
List<User> userList = userDao.selectList(lqw);
userList.forEach(System.out::println);
QueryWrapper
判空准备查询参数封装对象
@Data
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
private Integer online;
}
@Data
public class UserQuery extends User {
private Integer age2;
}
测试类中,使用QueryWrapper
判空
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//先判定第一个参数是否为true,如果为true连接当前条件
//lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2());
//lqw.gt(null != uq.getAge(),User::getAge, uq.getAge());
// 链式编程
lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2())
.gt(null != uq.getAge(),User::getAge, uq.getAge());
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
查询投影,就是要查询的列的问题。可能存在
复杂查询不推荐使用QueryWrapper
,使用Mybatis
原生方式,自己编写SQL。
/*LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.select(User::getId, User::getName, User::getAge);*/
//或者
QueryWrapper<User> lqw = new QueryWrapper<User>();
// 只指定部分类
lqw.select("id", "name", "age", "tel");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
QueryWrapper<User> lqw = new QueryWrapper<User>();
// count(*)不存在于表结构中国的字段
lqw.select("count(*) as count, tel");
lqw.groupBy("tel");
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
@TableField
属性注解,通过==value==属性,设置当前属性对应的数据库表中的字段关系。在模型类属性上方,使用@TableField
注解,通过==exist==属性,设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用。
查询和增删改的时候,都不会参与数据库的操作。
@TableField
注解,通过==select==属性:设置该属性是否参与默认查询(select *
)。此属性与select()映射配置不冲突。@Data
@TableName("tbl_user")
public class User {
/*
id为Long类型,因为数据库中id为bigint类型,
并且mybatis有自己的一套id生成方案,生成出来的id必须是Long类型
*/
private Long id;
private String name;
@TableField(value = "pwd",select = false) // 仅仅是不参与查询
private String password;
private Integer age;
private String tel;
@TableField(exist = false) //表示online字段不参与CRUD操作
private Boolean online;
}
DML
MybatisPlus
支持的生成策略MybatisPlus
支持8种生成策略五种可用,三种已过期。详情如下:
public enum IdType {
/**
* 数据库ID自增
* <p>该类型请确保数据库设置了 ID自增 否则无效</p>
*/
AUTO(0),
/**
* 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
*/
NONE(1),
/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/
INPUT(2),
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 分配ID (主键类型为number或string),
* 默认使用com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator(雪花算法)
*
* @since 3.3.0
*/
ASSIGN_ID(3),
/**
* 分配UUID (主键类型为 string)
* 默认使用 com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
*/
ASSIGN_UUID(4),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_ID}
*/
@Deprecated
ID_WORKER(3),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_ID}
*/
@Deprecated
ID_WORKER_STR(3),
/**
* @deprecated 3.3.0 please use {@link #ASSIGN_UUID}
*/
@Deprecated
UUID(4);
}
使用注解@TableId
名称:@TableId
类型:属性注解
位置:模型类中用于表示主键的属性定义上方
作用:设置当前类中主键属性的生成策略
相关属性
type:设置主键属性的生成策略,值参照IdType
枚举值
application.yaml
mybatis-plus:
global-config:
db-config:
id-type: assign_id # 全局使用雪花算法生成主键
table-prefix: tbl_ # 全局指定表名前缀,实体类上就不需要添加@TableName()注解了
//删除指定多条数据
List<Long> list = new ArrayList<>();
list.add(1402551342481838081L);
list.add(1402553134049501186L);
list.add(1402553619611430913L);
userDao.deleteBatchIds(list);
//查询指定多条数据
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(3L);
list.add(4L);
userDao.selectBatchIds(list);
在实际环境中,如果想删除一条数据,是否会真的从数据库中删除该条数据?
数据库表中添加逻辑删除标记字段
实体类中添加对应成员变量,并(逐个指定)标记对应属性
package com.cy.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
public class User {
private Long id;
//逻辑删除字段,标记当前记录是否被删除
// value表示未删除,delval表示已删除
@TableLogic(value="0", delval="1")
private Integer deleted;
}
实体类中添加成员变量后,也可以全局配置
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
# 逻辑删除字段名
logic-delete-field: deleted
# 逻辑删除字面值:未删除为0
logic-not-delete-value: 0
# 逻辑删除字面值:删除为1
logic-delete-value: 1
逻辑删除本质:逻辑删除的本质其实是修改操作。如果加了逻辑删除字段,查询数据时也会自动带上逻辑删除字段。
概念
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不用上锁。只在更新的时候会判断一下在此期间别人有没有去更新这个数据。
实现思路
使用数据版本(Version)记录:
version
字段来实现。version
字段的值一同读出,数据每更新一次,对此version
值加一。version
值相等,则予以更新,否则认为是过期数据。CAS:Compare And Swap
使用时间戳记录
数据库表中添加锁标记字段
实体类中添加对应字段,并设定当前字段为版本字段
package com.cy.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
@Data
public class User {
private Long id;
@Version
private Integer version;
}
配置乐观锁拦截器实现锁机制对应的动态SQL
语句拼装
package com.cy.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor() {
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpInterceptor;
}
}
使用乐观锁机制在修改前必须先获取到对应数据的verion
方可正常进行
@Test
public void testUpdate() {
/*User user = new User();
user.setId(3L);
user.setName("Jock666");
user.setVersion(1);
userDao.updateById(user);*/
//1.先通过要修改的数据id将当前数据查询出来
//User user = userDao.selectById(3L);
//2.将要修改的属性逐一设置进去
//user.setName("Jock888");
//userDao.updateById(user);
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L); //version=3
User user2 = userDao.selectById(3L); //version=3
user2.setName("Jock aaa");
userDao.updateById(user2); //version=>4
user.setName("Jock bbb");
userDao.updateById(user); //verion=3?条件还成立吗?
}
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。
发表于 2022-6-12 09:39
| ||
发表于 2022-6-12 13:05
| |
头像被屏蔽
|
发表于 2022-6-12 15:46
提示: 作者被禁止或删除 内容自动屏蔽
|
发表于 2022-6-12 19:35
| ||
RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )
GMT+8, 2024-11-25 10:39
Powered by Discuz!
Copyright © 2001-2020, Tencent Cloud.