1 前言
我们知道MybatisPlus
对单表操作很方便,特别是其条件构造器和分页插件,避免我们书写简单重复的SQL,提高我们的效率。其实在自定义SQL中也可以使用MybatisPlus
提供的条件构造器和分页插件,下面就来介绍如何自定义SQL中如何使用。
2 环境准备
- 数据库新建
student
和teacher
两张表
student
表结构如下
id | name | teacher_id |
---|---|---|
1 | 小明 | 1 |
2 | 小红 | 1 |
3 | 小白 | 2 |
teacher
表结构如下
id | name |
---|---|
1 | 老师1 |
2 | 老师2 |
- 项目的创建此处就省略了。导入如下依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- MybatisPlus依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
- yml配置
yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///test
username: root
password: root
mybatis-plus:
# 开启MybatisPlus的日志打印
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 如果mapper文件所在位置为resources/mapper下,此项可不配置
mapper-locations: classpath:mapper/*.xml
- 实体类
Student
实体类
java
package com.example.entity;
@Data
@TableName("student")
public class Student {
//自动递增的主键
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private Integer teacherId;
}
Teacher
实体类
java
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("teacher")
public class Teacher {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
}
- vo
java
package com.example.vo;
/**
* 用于接收查询出的数据
*/
@Data
public class StudentVo {
private Integer id;
private String name;
private Teacher teacher;
}
- 注意:在启动类上添加
MapperScan
注解扫描mapper
接口所在包
3 实现
我们以查询出学生信息为例,如下图
3.1 使用条件构造器
mapper
接口如下
注意:Wrapper形参的格式与下面要相同
java
package com.example.mapper;
@Repository
public interface StudentMapper extends BaseMapper<Student> {
StudentVo mySelectOne(@Param(Constants.WRAPPER) Wrapper<StudentVo> queryWrapper);
}
xml
配置文件如下
${ew.customSqlSegment}
:就是条件构造器中的条件了,不需要写WHERE
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper">
<resultMap id="studentVoMap" type="com.example.vo.StudentVo">
<result property="id" column="id" />
<result property="name" column="name" />
<association property="teacher" javaType="com.example.entity.Teacher">
<result property="id" column="tid" />
<result property="name" column="tname" />
</association>
</resultMap>
<select id="mySelectOne" resultMap="studentVoMap">
SELECT s.id, s.name, t.id tid, t.name tname
FROM student s join teacher t on s.teacher_id = t.id
${ew.customSqlSegment}
</select>
</mapper>
- 测试
java
@Test
void contextLoads() {
QueryWrapper<StudentVo> wrapper = Wrappers.<StudentVo>query()
.eq("s.id", 1);
StudentVo studentVo = studentMapper.mySelectOne(wrapper);
System.out.println(studentVo);
}
执行SQL如下
这样我们就能在自定义SQL中使用条件构造器了。
3.2 使用分页
MybatisPlus
使用分页需要配置分页插件,配置如下
java
package com.example.config;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
mapper
接口如下
less
package com.example.mapper;
@Repository
public interface StudentMapper extends BaseMapper<Student> {
Page<StudentVo> mySelectPage(Page<StudentVo> iPage, @Param(Constants.WRAPPER) Wrapper<StudentVo> queryWrapper);
}
xml
文件如下
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper">
<resultMap id="studentVoMap" type="com.example.vo.StudentVo">
<result property="id" column="id" />
<result property="name" column="name" />
<association property="teacher" javaType="com.example.entity.Teacher">
<result property="id" column="tid" />
<result property="name" column="tname" />
</association>
</resultMap>
<select id="mySelectPage" resultMap="studentVoMap">
SELECT s.id, s.name, t.id tid, t.name tname
FROM student s join teacher t on s.teacher_id = t.id
${ew.customSqlSegment}
</select>
</mapper>
- 测试
java
@Test
void contextLoads() {
QueryWrapper<StudentVo> wrapper = Wrappers.<StudentVo>query()
.eq("s.id", 1);
Page<StudentVo> page = studentMapper.mySelectPage(Page.of(1, 10), wrapper);
System.out.println(page.getRecords());
}
执行的SQL如下
我们发现分页也起效果了。
4 总结
虽然我们能够在自定义SQL中使用MybatisPlus
提供的条件构造器共和分页插件,但是还是有局限性的。
- 不能使用
LambdaWrapper
- 自定义SQL使用条件构造器,只会将条件原封不动的加在SQL后。例子如下
我们要查询创建时间create_date
等于2023年的
java
// 我们只能书写为create_date,而不能书写为createDate
QueryWrapper<StudentVo> wrapper = Wrappers.<StudentVo>query()
.eq("s.id", 1)
.eq("create_date", 2023)
5 写在最后
上述观点只是小白在学习过程中对接触的新东西的总结和分享,若存在不足之处,还请大佬指出。