MybatisPlus(用于简化Mybatis开发)
通过MybatisPlus的引入简化Dao层的代码书写
导入mybatis-plus的依赖
java
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.10.1</version>
</dependency>
使用方式:对应的Dao接口继承BaseMapper<对应的实体对象>
java
@Mapper
public interface UserDao extends BaseMapper<User> {
}
@Mapper
也可以不写
说明:Dao接口要想被容器扫描到,有两种解决方案:
-
方案一:在Dao接口上添加
@Mapper
注解,并且确保Dao处在引导类所在包或其子包中该方案的缺点是需要在每一Dao接口中添加注解
-
方案二:在引导类上添加
@MapperScan
注解,其属性为所要扫描的Dao所在包该方案的好处是只需要写一次,则指定包下的所有Dao接口都能被扫描到,@Mapper就可以不写。
java
@SpringBootApplication
@MapperScan("com.example.dao")
public class Mybatisplus01Application {
public static void main(String[] args) {
SpringApplication.run(Mybatisplus01Application.class, args);
}
}
使用MybatisPlus实现数据层操作

新增
java
@Test
void testSave(){
User user = new User();
user.setName("张三");
user.setPassword("123456");
user.setAge(23);
user.setTel("12345678910");
userDao.insert(user);
}
删除(通过id删除,但是id有可能是long类型即需要在长整型数后面加上一个L
)
java
@Test
void testDelete(){
userDao.deleteById(1909511862680911873L);
}
修改
java
@Test
void testUpdate(){
User user = new User();
user.setId(1L);
user.setName("张三");
user.setPassword("123456");
user.setAge(23);
user.setTel("12345678910");
userDao.updateById(user);
}
查询通过id,查询全部
java
@Test
void testGetById() {
User user = userDao.selectById(1L);
System.out.println(user);
}
java
@Test
void testGetAll() {
List<User> userList = userDao.selectList(null);
userList.forEach(System.out::println);
}
条件查询:通过设定一个条件对象
QueryWrapper
java
@Test
void testGetAll() {
System.out.println("模糊查询");
//创建一个查询条件对象
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
// 查询条件:模糊查询
userQueryWrapper.like("name","张");
List<User> userList = userDao.selectList(userQueryWrapper);
userList.forEach(System.out::println);
System.out.println("======================");
//使用lambda格式进行条件查询
QueryWrapper<User> qw1= new QueryWrapper<>();
// 查询条件:小于20岁
//User::getAge表示获取User对象的age属性---》表示lambda的方法引用
qw1.lambda().lt(User::getAge,20);
List<User> userList1 = userDao.selectList(qw1);
userList1.forEach(System.out::println);
System.out.println("======================");
QueryWrapper<User> qw2= new QueryWrapper<>();
// 查询条件:大于20岁小于30岁
qw2.lambda().gt(User::getAge,20).lt(User::getAge,30);
List<User> userList2 = userDao.selectList(qw2);
userList2.forEach(System.out::println);
System.out.println("======================");
QueryWrapper<User> qw3= new QueryWrapper<>();
//查询条件:大于20岁或者小于10岁---》通过or()方法进行连接
qw3.lambda().gt(User::getAge,20).or().lt(User::getAge,10);
List<User> userList3 = userDao.selectList(qw3);
userList3.forEach(System.out::println);
}
条件查询中的null参数值查询(在条件上就做一个判断如果不为空才进行拼接 查询的条件)
处理查询条件中的 null 值
在构建查询条件时,可以通过判断条件参数是否为 null 来决定是否添加该条件。例如:
java
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(null != uq.getAge2(), User::getAge, uq.getAge2());
lqw.gt(null != uq.getAge(), User::getAge, uq.getAge());
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
查询投影
可以选择查询结果中包含的属性。例如:
LambdaQueryWrapper lqw = new LambdaQueryWrapper(); lqw.select(User::getId, User::getName, User::getAge); List userList = userDao.selectList(lqw); System.out.println(userList);
范围查询
java
LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<>();
//等同于 name=="张三",password=="123456"
lqw.eq(User::getName,"张三").eq(User::getPassword,"123456");
User user = userDao.selectOne(lqw);
System.out.println(user);
System.out.println("======================");
LambdaQueryWrapper<User> lqw1=new LambdaQueryWrapper<>();
//范围查询 between---表示在20到30岁之间前面的是下限后面的是上限
lqw1.between(User::getAge,20,30);
List<User> userList = userDao.selectList(lqw1);
userList.forEach(System.out::println);
字段映射与表映射不同
问题1:数据库表字段与实际开发中的字段不同步(@TableField(value = "pwd")
)
问题2:实际开发中添加了数据库表中未定义的属性(@TableField(exist = false)
)
问题3:采用默认查询开放了更多的字段查看权限
(比如开发中不显示出密码给用户看:@TableField(select = false)
)
问题4:数据库表名与在实际开发中使用的表名不同(@TableName("tbl_user")
)
java
@TableName("tbl_user")
public class User {
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private Integer online;
}
Insert操作增加一条数据的ID生成策略
通过@TableId(type="ID的生成策略")
生成策略有:
AUTO():使用数据库id自增策略控制id生成
NONE():不设置id生成策略
INPUT():用户手工输入id
ASSIGN_ID():雪花算法生成id
(可兼容数值型与字符串型)+---保证唯一性,不重复---+
ASSIGN_UUID():以UUID生成算法作为id生成策略
java
@TableId(type=IdType.ASSIGN_ID)
private Long id;
多记录操作
删除多条记录
java
@Test
void testDelete(){
//删除指定多条数据
List list = new ArrayList<>();
list.add(1402551342481838081L);
list.add(1402553134049501186L);
list.add(1402553619611430913L);
userDao.deleteBatchIds(list);
}
查询多条记录
java
@Test
void testGetByIds(){
//查询指定多条数据
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(3L);
list.add(4L);
userDao.selectBatchIds(list);
}
逻辑删除(用于设置状态字段为不可用状态,实际上字段仍然在数据表中)
物理删除:业务数据在数据库中丢失,执行的是delete操作
逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中,执行的update操作
1、修改数据表添加deleted列
字段名可以任意,内容可以自定义,比如0表示正常,1表示删除,可以在添加列的同时设置其默认值为0正常
2、实体类添加属性
java
@Data
//@TableName("tbl_user") 可以不写是因为配置了全局配置
public class User {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String name;
@TableField(value="pwd",select=false)
private String password;
private Integer age;
private String tel;
@TableField(exist=false)
private Integer online;
@TableLogic(value="0",delval="1")
//value为正常数据的值,delval为删除数据的值
private Integer deleted;
}
3、运行删除方法
AI检测代码解析
java
@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testDelete(){
userDao.deleteById(1L);
}
}
逻辑删除走的是update操作,会将指定的字段修改成删除状态对应的值。
说明:
1、逻辑删除MP会将所有的查询都添加一个为删除的条件,也就是已经别删除的数据是不应该被查询出来的。如果还想把已经删除的数据都查询出来,就需要如下操作:
java
@Mapper
public interface UserDao extends BaseMapper {
//查询所有数据包含已经被删除的数据
@Select("select * from tbl_user")
public List selectAll(); }
2、如果每个表都有逻辑删除,不需要再每个模型类的属性上添加@TableLogic注解,可以在配置文件中添加全局配置,如下:
mybatis-plus:
global-config:
db-config:
# 逻辑删除字段名
logic-delete-field: deleted
# 逻辑删除字面值:未删除为0
logic-not-delete-value: 0
# 逻辑删除字面值:删除为1
logic-delete-value: 1
逻辑删除的本质是:修改操作,如果加了逻辑删除字段,查询数据时也会自动带上逻辑删除字段。
就是说在设定了相关逻辑删除字段了之后,mybatisplus执行的delete为update操作
执行的SQL语句为:
UPDATE tbl_user SET deleted=1 where id = ? AND deleted=0