0
点赞
收藏
分享

微信扫一扫

Mybatis-Plus--分页/多表联合查询--方法/使用/教程/实例


简介

        本文用实例介绍MybatisPlus的分页以及多表联合查询的方法。

公共代码

分页插件新写法(3.4.0及之后)

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

@Configuration
public class MybatisPlusConfig {

// 分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

分页插件老写法(3.4.0之前)

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}

entity

@Data
@TableName("t_question")
public class Question implements Serializable {

private static final long serialVersionUID = 1L;

// 问答主键id
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

// 学生外键id
@TableField("student_id")
private Integer studentId;

// 问题内容
private String content;

// 问题悬赏的积分
private Integer value;
}
@Data
@TableName("t_student")
public class Student implements Serializable {

private static final long serialVersionUID = 1L;

// 学生主键id
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

// 学生名称
private String name;

// 学生积分数
private Integer points;
}

VO

@Data
public class QuestionStudentVO implements Serializable {
// 问题主键id
private Integer id;

// 问题内容
private String content;

// 问题悬赏的积分
private Integer value;

// 学生外键id
private Integer studentId;

// 学生名字
private List<String> name;

// 学生积分
private Integer points;
}

启动类

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class MpPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MpPlusApplication.class, args);
}
}

sql

USE mp;
DROP TABLE IF EXISTS `t_question`;
CREATE TABLE `t_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT NULL,
`content` varchar(64) DEFAULT NULL,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8;


BEGIN;
INSERT INTO `t_question` VALUES ('1001', '1', 'this is question content', '10');
INSERT INTO `t_question` VALUES ('1002', '2', 'this is question content', '30');
COMMIT;

DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`id` int(11) NOT NULL,
`name` varchar(64) DEFAULT NULL,
`points` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

BEGIN;
INSERT INTO `t_student` VALUES ('1', 'Iron Man', '201');
INSERT INTO `t_student` VALUES ('2', 'Jarvis', '100');
INSERT INTO `t_student` VALUES ('3', 'Tony', '300');
COMMIT;

分页插件 

package com.example.conf;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {

// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}

多表查询

其他网址

​​mybatis Plus 多表联合查询​​

代码

mapper

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.Question;
import com.example.vo.QuestionStudentVO;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface QuestionMapper extends BaseMapper<Question> {
@Select("SELECT t_question.*,t_student.`name`,t_student.`points` " +
" FROM t_question,t_student " +
" WHERE t_question.student_id=t_student.id")
List<QuestionStudentVO> getQuestionStudent();

@Select("SELECT t_student.name " +
" FROM t_question,t_student " +
" WHERE t_question.student_id = #{id} " +
" AND t_question.student_id=t_student.id")
List<String> getStudentNameByQuestionId(@Param("id") Long id);

@Select("SELECT t_student.name " +
" FROM t_question,t_student " +
" ${ew.customSqlSegment} " +
" AND t_question.student_id=t_student.id")
List<String> getStudentNamesByQuestionIds(@Param("ew") Wrapper wrapper);
}

 ​controller

package com.example.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.Student;
import com.example.mapper.QuestionMapper;
import com.example.vo.QuestionStudentVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping("/common")
public class CommonController {
@Autowired
private QuestionMapper questionMapper;

@RequestMapping("/getAllQuestionWithStudent")
public List<QuestionStudentVO> getAllQuestionWithStudent() {
List<QuestionStudentVO> questionStudent = questionMapper.getQuestionStudent();
if (questionStudent == null) {
return Collections.emptyList();
}
return questionStudent;
}

@RequestMapping("/getStudentNameByQuestionId")
public List<String> getStudentNameById(Long id) {
return questionMapper.getStudentNameByQuestionId(id);
}

@RequestMapping("/getStudentNamesByQuestionIds")
public List<String> getStudentNamesByQuestionIds(Long[] ids) {
List<Long> questionIds = Arrays.asList(ids);
return questionMapper.getStudentNamesByQuestionIds(questionIds);
}
}

测试

postman访问:​​http://localhost:8080/common/getAllQuestionWithStudent​​

postman结果

[
{
"id": 1001,
"studentId": 1,
"name": null,
"points": 201,
"content": "this is question content",
"value": 10
},
{
"id": 1002,
"studentId": 2,
"name": null,
"points": 100,
"content": "this is question content",
"value": 30
}
]

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@597f87ec] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1471701683 wrapping com.mysql.cj.jdbc.ConnectionImpl@7b7782db] will not be managed by Spring
==> Preparing: SELECT t_question.*,t_student.`name`,t_student.points FROM t_question,t_student WHERE t_question.student_id=t_student.id
==> Parameters:
<== Columns: id, student_id, content, value, name, points
<== Row: 1001, 1, this is question content, 10, Iron Man, 201
<== Row: 1002, 2, this is question content, 30, Jarvis, 100
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@597f87ec]

 ​postman访问:​​http://localhost:8080/common/getStudentNameByQuestionId?id=1​​

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@427b93c6] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1287419385 wrapping com.mysql.cj.jdbc.ConnectionImpl@7b7782db] will not be managed by Spring
==> Preparing: SELECT t_student.name FROM t_question,t_student WHERE t_question.student_id = ? AND t_question.student_id=t_student.id
==> Parameters: 1(Long)
<== Columns: name
<== Row: Iron Man
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@427b93c6]

postman结果

[
"Iron Man"
]

 ​postman访问:​​http://localhost:8080/common/getStudentNamesByQuestionIds?ids=1,2​​

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@63dc1476] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1830549117 wrapping com.mysql.cj.jdbc.ConnectionImpl@7b7782db] will not be managed by Spring
==> Preparing: SELECT t_student.name FROM t_question,t_student WHERE (t_question.student_id IN (?,?)) AND t_question.student_id=t_student.id
==> Parameters: 1(Long), 2(Long)
<== Columns: name
<== Row: Iron Man
<== Row: Jarvis
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@63dc1476]

postman结果

[
"Iron Man",
"Jarvis"
]

单表分页

其他网址

​​Mybatis-Plus官网(分页)​​

​​Mybatis Plus 使用详解 - 六层楼 -​​

代码 

mapper

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.Question;
import com.example.vo.QuestionStudentVO;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface QuestionMapper extends BaseMapper<Question> {
}

Service

package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.Student;

public interface StudentService extends IService<Student> {
}
package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.Student;
import com.example.mapper.StudentMapper;
import com.example.service.StudentService;
import org.springframework.stereotype.Service;

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
}

Controller

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@RestController
@RequestMapping("/common")
public class CommonController {
@Autowired
private QuestionService questionService;

@Autowired
private StudentService studentService;

@RequestMapping("/getAllStudent")
public IPage<Student> getAllStudent(Page<Student> page) {
// 如果查出来为空,会返回入参page里边的数据,比如:current,size等。不需要自己判空。
return studentService.page(page,
new LambdaQueryWrapper<Student>().orderByDesc(Student::getName)
);
}

@RequestMapping("/getAllStudentByName")
public IPage<Student> getAllStudentByName(Page<Student> page) {
// 如果查出来为空,会返回入参page里边的数据,比如:current,size等。不需要自己判空。
return studentService.lambdaQuery().eq(Student::getName, "Jarvis").page(page);
}

@RequestMapping("/getAllStudentByNameNo")
public IPage<Student> getAllStudentByNameNo(Page<Student> page) {
// 如果查出来为空,会返回入参page里边的数据,比如:current,size等。不需要自己判空。
return studentService.lambdaQuery().eq(Student::getName, "NO NO").page(page);
}

}

测试

postman访问:​​http://localhost:8080/common/getAllStudent​​

使用第1条(无条件,会查出所有)

postman结果

{
"records": [
{
"id": 1,
"name": "Iron Man",
"points": 201
},
{
"id": 2,
"name": "Jarvis",
"points": 100
},
{
"id": 3,
"name": "Tony",
"points": 300
}
],
"total": 3,
"size": 10,
"current": 1,
"orders": [],
"optimizeCountSql": true,
"hitCount": false,
"searchCount": true,
"pages": 1
}

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5810d535] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1456943175 wrapping com.mysql.cj.jdbc.ConnectionImpl@61b976ac] will not be managed by Spring
JsqlParserCountOptimize sql=SELECT id,name,points FROM t_student
==> Preparing: SELECT COUNT(1) FROM t_student
==> Parameters:
<== Columns: COUNT(1)
<== Row: 3
==> Preparing: SELECT id,name,points FROM t_student LIMIT ?,?
==> Parameters: 0(Long), 10(Long)
<== Columns: id, name, points
<== Row: 1, Iron Man, 201
<== Row: 2, Jarvis, 100
<== Row: 3, Tony, 300
<== Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5810d535]

使用第2条(指定条件,有匹配到的):​​http://localhost:8080/common/getAllStudentByName?size=5&current=1​​

postman结果

{
"records": [
{
"id": 2,
"name": "Jarvis",
"points": 100
}
],
"total": 1,
"size": 5,
"current": 1,
"orders": [],
"optimizeCountSql": true,
"hitCount": false,
"searchCount": true,
"pages": 1
}

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b8778dc] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@594281656 wrapping com.mysql.cj.jdbc.ConnectionImpl@61b976ac] will not be managed by Spring
JsqlParserCountOptimize sql=SELECT id,name,points FROM t_student

WHERE (name = ?)
==> Preparing: SELECT COUNT(1) FROM t_student WHERE (name = ?)
==> Parameters: Jarvis(String)
<== Columns: COUNT(1)
<== Row: 1
==> Preparing: SELECT id,name,points FROM t_student WHERE (name = ?) LIMIT ?,?
==> Parameters: Jarvis(String), 0(Long), 5(Long)
<== Columns: id, name, points
<== Row: 2, Jarvis, 100
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b8778dc]

使用第3条(指定条件,没有匹配到的):​​http://localhost:8080/common/getAllStudentByNameNo​​

postman结果

{
"records": [],
"total": 0,
"size": 10,
"current": 1,
"orders": [],
"optimizeCountSql": true,
"hitCount": false,
"searchCount": true,
"pages": 0
}

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6418d8d0] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1158294948 wrapping com.mysql.cj.jdbc.ConnectionImpl@61b976ac] will not be managed by Spring
JsqlParserCountOptimize sql=SELECT id,name,points FROM t_student

WHERE (name = ?)
==> Preparing: SELECT COUNT(1) FROM t_student WHERE (name = ?)
==> Parameters: NO NO(String)
<== Columns: COUNT(1)
<== Row: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6418d8d0]

多表分页

其他网址

​​最简单的 MyBatis Plus 的多表联接、分页查询实现方法_IT小村-​​

代码

Mapper 

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.Question;
import com.example.vo.QuestionStudentVO;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface QuestionMapper extends BaseMapper<Question> {
@Select("SELECT t_question.*,t_student.* " +
" FROM t_question,t_student " +
" WHERE t_question.student_id=t_student.id")
List<QuestionStudentVO> getQuestionStudentPage (Page<QuestionStudentVO> page);
}

Service

package com.example.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.Question;
import com.example.vo.QuestionStudentVO;

import java.util.List;

public interface QuestionService extends IService<Question> {
IPage<QuestionStudentVO> getQuestionStudentPage (Page<QuestionStudentVO> page);
}
package com.example.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.Question;
import com.example.mapper.QuestionMapper;
import com.example.service.QuestionService;
import com.example.vo.QuestionStudentVO;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
//下边的this.baseMapper都可以用自动注入的QuestionMapper替换

@Override
public Page<QuestionStudentVO> getQuestionStudentPage (Page<QuestionStudentVO> page) {
return page.setRecords(this.baseMapper.getQuestionStudentPage(page));
}
}

Controller

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@RestController
@RequestMapping("/common")
public class CommonController {
@Autowired
private QuestionService questionService;

@Autowired
private StudentService studentService;

@RequestMapping("/getAllQuestionWithStudentByPage")
public IPage<QuestionStudentVO> getAllQuestionWithStudentByPage(Page<QuestionStudentVO> page) {
IPage<QuestionStudentVO> questionStudent = questionService.getQuestionStudentPage (page);
return questionStudent;
}
}

测试

postman访问:

​​http://localhost:8080/common/getAllQuestionWithStudentByPage?current=1&size=2​​

postman结果(可见数组或List无法直接赋值。)

{
"records": [
{
"id": 1001,
"studentId": 1,
"name": null,
"points": 201,
"content": "this is question content",
"value": 10
},
{
"id": 1002,
"studentId": 2,
"name": null,
"points": 100,
"content": "this is question content",
"value": 30
}
],
"total": 2,
"size": 2,
"current": 1,
"orders": [],
"optimizeCountSql": true,
"hitCount": false,
"searchCount": true,
"pages": 1
}

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@46bd5ef7] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1676586413 wrapping com.mysql.cj.jdbc.ConnectionImpl@61b976ac] will not be managed by Spring
JsqlParserCountOptimize sql=SELECT t_question.*,t_student.* FROM t_question,t_student WHERE t_question.student_id=t_student.id
==> Preparing: SELECT COUNT(1) FROM t_question, t_student WHERE t_question.student_id = t_student.id
==> Parameters:
<== Columns: COUNT(1)
<== Row: 2
==> Preparing: SELECT t_question.*,t_student.* FROM t_question,t_student WHERE t_question.student_id=t_student.id LIMIT ?,?
==> Parameters: 0(Long), 2(Long)
<== Columns: id, student_id, content, value, id, name, points
<== Row: 1001, 1, this is question content, 10, 1, Iron Man, 201
<== Row: 1002, 2, this is question content, 30, 2, Jarvis, 100
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@46bd5ef7]

手动包装Page

        Mybatis Plus分页查询的重点在于Page这个包装类。上边的多表分页查询用了page.setRecords其实就是手动包装的。再把代码拿过来看一下

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
@Override
public Page<QuestionStudentVO> getQuestionStudentPage (Page<QuestionStudentVO> page) {
return page.setRecords(this.baseMapper.getQuestionStudentPage(page));
}
}

this.baseMapper.getQuestionStudentPage(page)

这个执行完之后,会将page的total等进行赋值。然后外部的page.setRecords会将其返回值设置到page里边去。

排序

排序涉及到Page类的List<OrderItem> orders;成员,OrderItem定义如下:

public class OrderItem implements Serializable {
private static final long serialVersionUID = 1L;

//需要进行排序的字段
private String column;

// 是否正序排列,默认 true
private boolean asc = true;
...
}

前端指定排序

Controller

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@RestController
@RequestMapping("/common")
public class CommonController {
@Autowired
private StudentService studentService;

@RequestMapping("/getAllStudentInOrder")
public IPage<Student> getAllStudentInOrder(Page<Student> page) {
IPage<Student> students = studentService.page(page);
if (students == null) {
return page;
}
return students;
}
}

测试

postman访问:​​http://localhost:8080/common/getAllStudentInOrder?current=1&size=2​​

postman的body

orders[0].column

orders[0].asc

Mybatis-Plus--分页/多表联合查询--方法/使用/教程/实例_sql

postman的结果

{
"records": [
{
"id": 3,
"name": "Tony",
"points": 300
},
{
"id": 2,
"name": "Jarvis",
"points": 100
}
],
"total": 3,
"size": 2,
"current": 1,
"orders": [
{
"column": "name",
"asc": false
}
],
"optimizeCountSql": true,
"hitCount": false,
"searchCount": true,
"pages": 2
}

后端结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@551ee9d2] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@726462971 wrapping com.mysql.cj.jdbc.ConnectionImpl@61b976ac] will not be managed by Spring
JsqlParserCountOptimize sql=SELECT id,name,points FROM t_student
==> Preparing: SELECT COUNT(1) FROM t_student
==> Parameters:
<== Columns: COUNT(1)
<== Row: 3
==> Preparing: SELECT id, name, points FROM t_student ORDER BY name DESC LIMIT ?,?
==> Parameters: 0(Long), 2(Long)
<== Columns: id, name, points
<== Row: 3, Tony, 300
<== Row: 2, Jarvis, 100
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@551ee9d2]

后端OrderItems排序

@GetMapping("/page")
public IPage<User> getUserPage(Page<User> page) {
page.addOrder(OrderItem.desc("create_time"), OrderItem.asc("id"));
return UserService.page(page);
}

后端Wrapper排序

@GetMapping("/page")
public IPage<User> getUserPage(Page<User> page) {
LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>lambdaQuery();
queryWrapper.orderByDesc(User::getCreateTime);
queryWrapper.orderByAsc(User::getId);
return UserService.page(page, queryWrapper);
}

其他网址

​​​​

mybatis-plus的使用 ------ 进阶 -

举报

相关推荐

0 条评论