一、MybatisPlus简介
MybatisPlus是一款基于mybatis框架基础上开发的增强型工具,旨在简化开发、提高效率,是一款国人开发的数据库操作工具,通过继承api的方式,大大的提高了效率
- 在使用MybatisPlus之前,我们需要导入MybatisPlus的起步依赖
<!-- MyBatis-Plus 核心依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
因为我们是在spring boot项目中使用MybatisPlus,所以只需导入这一个核心依赖即可。
-
定义数据接口Mapper类,并且继承BaseMapper<>接口
package com.example.Dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.domain.Emp; import com.example.domain.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserDao extends BaseMapper<User> { }
二、标准数据层开发
标准的数据层开发有基本的crud功能以及分页、条件查询,下面看MybatisPlus是如何具体的实现这些功能的。
crud代码如下:
package com.example;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.Dao.UserDao;
import com.example.domain.Emp;
import com.example.domain.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;
@SpringBootTest
class MybatisApplicationTests {
@Autowired
UserDao userDao;
@Test
void select() {
//查询
User user = userDao.selectById(1);
System.out.println(user);
}
@Test
void add(){
//添加
User user = new User();
user.setName("王五");
user.setId(2);
user.setGender("男");
userDao.insert(user);
}
@Test
void update(){
//修改
//根据id修改属性需要提供具有id属性的对象,这个对象中没有赋值的属性,修改的这条记录会保持原来的值,有新的值的属性将会代替原来记录中的值
User user = new User();
user.setName("李四11");
user.setId(1);
userDao.updateById(user);
}
@Test
void delete(){
//删除
userDao.deleteById(2);
}
}
需要注意的是,根据id修改属性需要提供具有id属性的对象,这个对象中没有赋值的属性,修改的这条记录会保持原来的值,有新的值的属性将会代替原来记录中的值 ,这不同于Mybatis,当其他属性为null时会将表中的数据修改为null,需要通过xml中的where标签来进行if判断。
分页查询:
MybatisPlus底层对于分页查询是采用了拦截器的方式,拦截的是方法以及方法中的参数,会判断是否是查询操作。如果是查询操作,才会进入分页的逻辑处理。我们使用分页擦好像时需要先写一个配置类用来设置拦截器。
package com.example.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//添加具体的拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
代码如下:
@Test
void Page(){
//IPage iPage = new Page(1,1);
//创建一个Page对象用于设置分页的参数
Page<User> page = new Page<>(1,2);
//将设置好参数的Page对象翻入查询的方法中
Page<User> page1 = userDao.selectPage(page, null);
System.out.println(page1.getRecords());
System.out.println(page1);
}
这里需要注意一点,我们也可以使用IPage对象来接收Page对象的地址,IPage是Page的父类,导包的时候要注意不要导错包
条件查询:
条件查询有两种形式,一种是普通的使用QueryWrapper类定义查询的条件,第二种是使用LambdaQueryWrapper类采用lambda格式进行定义查询条件。推荐使用lambda格式
//条件查询
@Test
void selectWrapper(){
/*QueryWrapper<User> qw = new QueryWrapper<>();
//添加条件
qw.ge("age",18);//age大于18,
qw.lt("age",30);//age小于30
//也可以采用链式编程
qw.ge("age",18).lt("age",30);//直接点代表and
qw.ge("age",18).or().lt("age",30);//加个or()代表or*/
//lambda格式 推荐使用
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.ge(User::getAge,18).lt(User::getAge,30);
List<User> users = userDao.selectList(lambdaQueryWrapper);
}
范围查询,模糊查询,模糊查询中的like中的left和right代表占位符%的位置
@Test
void test3(){
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//等于=
lqw.eq(User::getAge,18);
//范围查询 lt(<) le(<=) gt(>) ge(>=) eq(=) betwen
lqw.between(User::getAge,18,30);//查询条件为age在18到30之间的数据
//模糊查询 like
//模糊查询中的like中的left和right代表占位符%的位置
lqw.like(User::getName,"张三");
lqw.likeLeft(User::getName,"张");
}
条件查询null判定
@Test
void test(){
//条件查询null判定
User user = new User(3,"小明",19,"男");
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//不管age的值是否为null,都拼接到条件判断中
//lambdaQueryWrapper.lt(User::getAge,18).ge(User::getAge,30);
//只有当前面的参数为true才将后面的条件拼接到判断中
lambdaQueryWrapper.lt(null != user.getAge(),User::getAge,18);
List<User> users = userDao.selectList(lambdaQueryWrapper);
System.out.println(users);
}
查询投影
@Test
void test2(){
//查询投影
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//查询实体类中的部分属性
//添加需要查询的字段
lambdaQueryWrapper.select(User::getAge,User::getName);
List<User> users = userDao.selectList(lambdaQueryWrapper);
System.out.println(users);
//查询实体类中没有的属性
QueryWrapper<User> qw = new QueryWrapper<>();
qw.select("count(*) as nums");
qw.groupBy("gender");
List<Map<String, Object>> maps = userDao.selectMaps(qw);
System.out.println(maps);
}
字段映射与表名映射
@TableName:用于设置实体类名与表名对应
@TableField:用于设置属性的相关属性
- value:表示该属性在表中对应的字段
- exist:表示该属性在表中不存在,查询返回结果使不会映射这个属性,不能与value属性同时使用
- select:表示该属性是否参与查询,默认是true
代码:
package com.example.domain;
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
//指定该类对应名为user的表
@TableName("user")
public class User {
long id;
String name;
Integer age;
//设置sex属性在表中对应gender字段,并且不参与查询操作
@TableField(value = "gender",select = false)
String sex;
//设置该属性在表中不存在
@TableField(exist = false)
String online;
}
三、id生成策略
在了解id生成策略之前,我们需要先了解一个注解
@TableId:设置该属性为主键,并且配置主键的相关配置
- value:设置数据库主键字段名称
- type:设置主键id的生成策略
常用的id生成策略有以下几种:
package com.example.domain;
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
//指定该类对应名为user的表
@TableName("user")
public class User {
//设置该属性为主键,并且设置其为自增策略
@TableId(value = "id",type = IdType.AUTO)
long id;
String name;
Integer age;
//设置sex属性在表中对应gender字段,并且不参与查询操作
@TableField(value = "gender",select = false)
String sex;
//设置该属性在表中不存在
@TableField(exist = false)
String online;
}