目录
介绍
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
功能特性
- 通用 CRUD 操作
- 分页插件
- 条件构造器
- 代码生成器
- SQL 注入器
- 元对象( meta-object ) 功能
- 多租户 SQL 解析器
- 动态表名 SQL 解析器
- 性能分析插件
Mybatis-Plus 提供了强大的CRUD操作,内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求。【基于SpringBoot 】
使用
1、导入依赖
<!--指定项目的父级依赖 方便快速搭建-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.13</version>
<relativePath/>
</parent>
<dependencies>
<!--Spring Boot Web模块的依赖,包括了Spring MVC和Tomcat等依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--MySQL数据库驱动的依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!--Spring Boot的核心依赖,包括了Spring和Spring Boot的各种依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--Spring Boot测试模块的依赖,包括了JUnit、Mockito等依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--MyBatis-Plus的Spring Boot Starter依赖,包括了MyBatis、MyBatis-Spring等依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<!--阿里巴巴数据库连接池的依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!--JUnit 5测试框架的API依赖-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
</dependencies>
2、在resources/application.yml中 配置数据源和 MyBatis-Plus 的相关配置
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: "0123"
url: jdbc:mysql://localhost:3306/sys?characterEncoding=utf8&allowMultiQueries=true
type: com.alibaba.druid.pool.DruidDataSource
druid:
one:
max-active: 100
min-idle: 20
max-wait: 2000
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-aliases-package: com.project.bean
mapper-locations: classpath:*/*Mapper.xml
注意:
缩进问题:在YAML文件中,缩进是非常重要的,因为它表示了层级关系。例如,server和spring都是顶级属性,因此它们的缩进为0。而port和datasource则是server和spring的子属性,因此它们的缩进为2。以此类推。同一层级的属性,其缩进的空格数必须相同
密码问题:密码作为字符串类型时会被解释为八进制数。因此,如果密码以0开头,可能会导致密码被错误地解释为八进制数,从而导致密码错误或其他问题。为了避免这种情况发生需要使用双引号将其括起来。
3、创建启动类
- 启动Spring Boot 应用程序并初始化必要的组件和依赖项
@SpringBootApplication
public class MainMyBatisPlus {
public static void main(String[] args) {
SpringApplication.run(MainMyBatisPlus.class);
}
}
4、编写实体类和业务接口
//实体类映射的数据库表名
@TableName("t_student")
public class StudentBean {
//定义主键列对应属性,value表示该属性映射的列名
//type = IdType.AUTO 表示主键生成策略
//IdType.AUTO 表示利用数据库表的自动增长列填充主键列的值
@TableId(value = "pk_stuID",type = IdType.AUTO)
private Integer id;
//定义当前属性 对应的列名
@TableField("s_name")
private String name;
@TableField("s_gender")
private String sex;
@TableField("s_birthday")
private LocalDate birthday;
@TableField("s_tel")
private String phone;
}
public interface IStudentService {
void add(StudentBean stuBean);
void del(Integer id);
void update(Integer id,String tel);
List<StudentBean> findAll();
StudentBeanfindById(Integer id);
List<StudentBean> findByName(String name);
List<StudentBean> findByBirthday(LocalDate start,LocalDate end);
}
5、创建mapper接口
- 必须继承BaseMapper 且需加@Mapper注解
@Mapper
public interface IStudentMapper extends BaseMapper<StudentBean> {
}
6、书写业务接口的实现类
- 使用 MyBatis-Plus 提供的 API 进行 CRUD 操作
@Service
@Transactional
public class StudentServiceImp implements IStudentService {
@Autowired
private IStudentMapper mapper;
@Override
public void add(StudentBean studentBean) {
mapper.insert(studentBean);
}
@Override
public void del(Integer id) {
mapper.deleteById(id);
}
@Override
public void update(Integer id, String tel) {
ManBean man = mapper.selectById(id);
man.setPhone(tel);
mapper.updateById(man);
}
@Override
public List<StudentBean> findAll() {
return mapper.selectList(null);
}
@Override
public StudentBean findById(Integer id) {
return mapper.selectById(id);
}
@Override
public List<StudentBean > findByName(String name) {
QueryWrapper<StudentBean > qw = new QueryWrapper<>();
//模糊查询 列名,值
qw.like("s_name",name);
return mapper.selectList(qw);
}
@Override
public List<StudentBean > findByBirthday(LocalDate start, LocalDate end) {
QueryWrapper<StudentBean > qw = new QueryWrapper<>();
//大于
qw.ge("s_birthday",start);
//小于
qw.le("s_birthday",end);
return mapper.selectList(qw);
}
}
7、创建测试类
@SpringBootTest(classes = MainMyBatisPlus.class)
public class ManTest {
@Autowired
private IStudentService service;
@Test
public void test(){
}
}
联表查询
maybatis-plus实体类中添加的注解,仅对单表有效。如果需要联表操作,必须重定义resultMap映射 。
查询所有员工,并查询每个员工所在的部门名称
实体Bean
@TableName("t_dept")
public class DeptBean {
@TableId(value = "pk_deptId",type = IdType.AUTO)
private Integer id;
@TableField("d_name")
private String name;
@TableField("d_master")
private String master;
/** 该部门的员工人数 */
@TableField(exist = false)//标识该属性不是数据库表的列
private Integer emNum;
/** 员工集合*/
@TableField(exist = false)
private List<EmployeeBean> emList;
}
@TableName("t_employee")
public class EmployeeBean {
@TableId(value = "pk_emId",type = IdType.AUTO)
private Integer id;
@TableField("e_name")
private String name;
@TableField("e_birthday")
private LocalDate birthday;
//添加时,可以避免书写sql语句
@TableField("fk_deptId")
private Integer deptId;
@TableField(exist = false)
private DeptBean dept;
}
业务接口
public interface IEmployeeService {
List<EmployeeBean> findAll();
}
Mapper
@Mapper
public interface IEmployeeMapper extends BaseMapper<EmployeeBean> {
@Select("SELECT e.*,d.`d_name`FROM t_employee e, t_dept d \n" +
"WHERE e.`fk_deptId` = d.`pk_deptId`;")
@ResultMap("emMap")
List<EmployeeBean> findAll();
}
实现类
@Service
@Transactional
public class EmployeeImp implements IEmployeeService {
@Autowired
private IEmployeeMapper emMapper;
@Autowired
private IDeptMapper deptMapper;
@Override
public List<EmployeeBean> findAll() {
return emMapper.findAll();
}
}
按id查询员工,同时查询员工所在部门的信息
业务接口
public interface IEmployeeService {
EmployeeBean findById(Integer emId);
}
实现类
@Service
@Transactional
public class EmployeeImp implements IEmployeeService {
@Override
public EmployeeBean findById(Integer emId) {
EmployeeBean employeeBean = emMapper.selectById(emId);
employeeBean.setDept(deptMapper.selectById(employeeBean.getDeptId()));
return employeeBean;
}
}
-
按员工id查询员工信息,并将查询结果封装到员工对象
-
按部门id查询部门信息,并将查询结果set设置到员工对象的部门属性中
按ID查询部门,同时查询该部门的员工信息
业务接口
public interface IEmployeeService {
DeptBean findById(Integer id);
}
实现类
@Service
@Transactional
public class EmployeeImp implements IEmployeeService {
@Override
public DeptBean findById(Integer id) {
//根据id查询部门信息
DeptBean deptBean = deptMapper.selectById(id);
//用QueryWrapper类创建一个查询条件
QueryWrapper<EmployeeBean> qw = new QueryWrapper<>();
//查询条件为fk_deptId字段等于id
qw.eq("fk_deptId",id);
//根据查询条件查询员工列表,并将查询结果设置到部门对象中
deptBean.setEmList(employeeMapper.selectList(qw));
return deptBean;
}
}
动态条件分页查询
多表
1、创建配置类,注册分页插件
@Configuration//标识 配置类
public class MybatisPlusConfig {
@Bean//将该方法返回的对象添加到Spring容器中,并交由Spring进行管理。
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
- MybatisPlusInterceptor是Mybatis-Plus提供的一个拦截器,用于拦截执行的SQL语句,可以在执行前后进行一些自定义的操作。
- 给MybatisPlusInterceptor对象,添加一个内部拦截器PaginationInnerInterceptor,并指定数据库类型为MYSQL。`PaginationInnerInterceptor`是Mybatis-Plus提供的一个分页插件,用于拦截执行的SQL语句,并自动进行分页操作,避免手动编写分页SQL语句。
2、业务接口
public interface IEmployeeService {
IPage<EmployeeBean> cutFindByItem(Integer pageNum,
String name, LocalDate startTime,LocalDate endTime);
}
3、Mapper
@Mapper
public interface IEmployeeMapper extends BaseMapper<EmployeeBean> {
IPage<EmployeeBean> cutFindByItem(Page pg, @Param("name") String name,
@Param("startTime") LocalDate startTime,
@Param("endTime") LocalDate endTime);
}
4、sql
<resultMap id="emMap" type="EmployeeBean">
<id column="pk_emId" property="id"></id>
<result column="e_name" property="name"></result>
<result column="e_birthday" property="birthday"></result>
<result column="fk_deptId" property="deptId"></result>
<result column="d_name" property="dept.name"></result>
</resultMap>
<select id="cutFindByItem" resultMap="emMap">
select e.*,d.d_name from t_employee e,t_dept d where e.fk_deptId = d.pk_deptId
<if test="name!=null and name !=''">
and e.e_name like "%"#{name}"%"
</if>
<if test="startTime!=null">
and e_birthday >= #{startTime}
</if>
<if test="endTime!=null">
and #{endTime} >= e_birthday
</if>
</select>
5、实现类
@Service
@Transactional
public class EmployeeImp implements IEmployeeService {
@Autowired
private IEmployeeMapper emMapper;
@Autowired
private IDeptMapper deptMapper;
@Override
public IPage<EmployeeBean> cutFindByItem(Integer pageNum,
String name, LocalDate startTime, LocalDate endTime) {
return emMapper.cutFindByItem(new Page(pageNum,3),name,startTime,endTime);
}
}
注意:用IPage接口封装了分页信息和查询结果<员工类>,创建分页对象Page设置(当前页码,每页显示记录数)
6、测试
IPage ip = service.cutFindByItem(2,"小",null,null);
System.out.println(ip.getRecords()+" "+ip.getPages()+" "+ip.getTotal());
单表
单表用自带的API方法就可以了,比如动态条件查询学生:
@Override
public IPage<StudentBean> findByItem(Integer pageNO, String name, LocalDate startTime, LocalDate endTime) {
QueryWrapper qw = new QueryWrapper<>();
if(name!=null&&name.length()!=0){
qw.like("s_name",name);
}
if(startTime!=null){
qw.ge("s_birthday",startTime);
}
if(startTime!=null){
qw.le("s_birthday",endTime);
}
return mapper.selectPage(new Page(pageNO,3),qw);
}
级联删除
删除部门之前,删除部门所在的员工
void delCaseCade(Integer id);
@Override
public void delCaseCade(Integer id) {
//按部门id删除员工
QueryWrapper<EmployeeBean> qw = new QueryWrapper<>();
qw.eq("fk_deptId",id);
employeeMapper.delete(qw);
//按部门id删除部门
deptMapper.deleteById(id);
}
外键置空
void delSetNull(Integer id);
@Delete("update t_employee set fk_deptId=null where fk_deptId=#{id};" +
"delete from t_dept where pk_deptId=#{id};")
void delSetNull(Integer id);
@Override
public void delSetNull(Integer id) {
deptMapper.delSetNull(id);
}
主从表同时插入
添加部门,同时添加部门员工
//业务接口
public interface IDeptService {
void add(DeptBean deptBean, List<EmployeeBean> emList);
}
@Mapper
public interface IDeptMapper extends BaseMapper<DeptBean> {
void addEmployeeList(@Param("id") Integer id,
@Param("emList") List<EmployeeBean> emList);
}
批量添加部门员工
<mapper namespace="com.project.mapper.IDeptMapper">
<insert id="addEmployeeList">
insert into t_employee(e_name,e_birthday,fk_deptId) values
<foreach collection="emList" item="em" separator=",">
(#{em.name},#{em.birthday},#{id})
</foreach>
</insert>
</mapper>
增加部门对象,调用mapper方法,按部门id,添加员工集合
@Service
@Transactional
public class DeptServiceImp implements IDeptService {
@Autowired
private IDeptMapper deptMapper;
@Autowired
private IEmployeeMapper employeeMapper;
@Override
public void add(DeptBean deptBean, List<EmployeeBean> emList) {
deptMapper.insert(deptBean);
deptMapper.addEmployeeList(deptBean.getId(),emList);
}
}