目录
src/main
├── java/com/atguigu
│ ├── Main.java # 启动类
│ ├── config/
│ │ └── MyBatisPlusConfig.java # 配置类,配置分页
│ ├── common/
│ │ └── Result.java # 全局统一返回
│ │ └── PageVO.java # 自定义通用分页对象(只保留核心字段)
│ ├── pojo/ # 数据库实体
│ │ ├── Employees.java
│ │ └── Departments.java
│ ├── dto/ # 查询参数封装
│ │ └── EmpQueryDTO.java
│ ├── vo/ # 视图对象(连表/返回前端)
│ │ └── EmpDepartmentsVO.java
│ ├── mapper/ # Mapper接口
│ │ └── EmpMapper.java
│ ├── service/
│ │ ├── EmployeesService.java # 业务接口
│ │ └── impl/
│ │ └── EmployeesServiceImpl.java # 业务实现
│ └── controller/
│ └── EmpController.java # 接口层
└── resources/ # 资源目录(核心!)
├── mapper/
│ └── xml/
│ └── EmpMapper.xml # XML SQL文件(放这里!)
└── application.yml # 配置文件
pom.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
</parent>
<groupId>com.atguigu</groupId>
<artifactId>mp-project-testa</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 测试环境 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 数据库相关配置启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- druid启动器的依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
<!-- 驱动类-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
yml
# 连接池配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql:///atguigudb
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台输出sql语句
map-underscore-to-camel-case: true
mapper-locations: classpath*:/mapper/*.xml
type-aliases-package: com.atguigu
配置类
java
package com.atguigu.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// mysql分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
通用类
统一返回格式
java
package com.atguigu.common;
import lombok.Data;
/*
* 全局统一返回结果
* */
@Data
public class Result<T> {
private int code;
private String msg;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<T>();
result.setData(data);
result.setCode(200);
result.setMsg("success");
return result;
}
public static <T> Result<T> fail(String msg) {
Result<T> result = new Result<T>();
result.setCode(500);
result.setMsg(msg);
return result;
}
}
自定义通用分页对象
java
package com.atguigu.common;
import lombok.Data;
import java.util.List;
/**
* 自定义通用分页对象(只保留核心字段)
*/
@Data
public class PageVO<T> {
// 数据列表
private List<T> records;
// 总条数
private Long total;
// 每页条数
private Long size;
// 当前页码
private Long current;
// 总页数
private Long pages;
/*
首先,类上的<T>是 public class PageVO<T>,这个是属于实例的泛型,
而,静态方法是属于类的,不属于实例,
所以,静态方法用不了类上的<T>,必须自己声明一个<T>。
说白了:
作用:告诉编译器,这个静态方法是泛型方法,里面的 T 是方法自己的泛型类型,
和传入的 IPage<T>、返回的 PageVO<T>的 T 是同一个类型。
当你调用:PageVO.restPage(IPage<Employees>) 时候
编译器就会自动把 <T> 推断为 Employees,保证类型安全。
*/
// 返回值类型:PageVO<T>,方法名:restPage
public static <T> PageVO<T> restPage(com.baomidou.mybatisplus.core.metadata.IPage<T> page) {
PageVO<T> pageVO = new PageVO<T>();
pageVO.setRecords(page.getRecords());
pageVO.setTotal(page.getTotal());
pageVO.setSize(page.getSize());
pageVO.setCurrent(page.getCurrent());
pageVO.setPages(page.getPages());
return pageVO;
}
}
实体类
Employees.java
java
package com.atguigu.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("employees")
public class Employees {
@TableId(value = "employee_id", type = IdType.AUTO)
private Long employeeId;
private String firstName;
private String lastName;
private String email;
private Long departmentId;
}
Departments.java
java
package com.atguigu.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("departments")
public class Departments {
@TableId(value = "department_id", type = IdType.AUTO)
private Long departmentId;
private String departmentName;
private Integer managerId;
}
Mapper + XML
EmpMapper 接口
继承 MP 的 BaseMapper,自定义业务方法*
java
package com.atguigu.mapper;
import com.atguigu.dto.EmpQueryDTO;
import com.atguigu.pojo.Employees;
import com.atguigu.vo.EmpDepartmentsVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface EmpMapper extends BaseMapper<Employees> {
// 分页查询 - 单表
IPage<Employees> selectEmpList(Page<Employees> page, @Param("query")EmpQueryDTO empQueryDTO);
// 分页查询 - 多表
IPage<EmpDepartmentsVO> selectEmpDepartmentList(Page<EmpDepartmentsVO> page, @Param("query")EmpQueryDTO empQueryDTO);
}
EmpMapper.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTO Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mapper.EmpMapper">
<!-- 单表查询:数据库列名用下划线 -->
<select id="selectEmpList" resultType="com.atguigu.pojo.Employees">
select employee_id, first_name, last_name, email, department_id
from employees
<where>
<if test="query.lastName != null and query.lastName != ''">
and last_name like concat("%", #{query.lastName}, "%")
</if>
<if test="query.email != null and query.email != ''">
and email like concat('%', #{query.email}, '%')
</if>
</where>
</select>
<!-- 多表查询:必须加表别名d.,列名用下划线 -->
<select id="selectEmpDepartmentList" resultType="com.atguigu.vo.EmpDepartmentsVO">
select
e.employee_id, e.first_name, e.last_name, e.email,
d.department_id, d.department_name
from employees e
left join departments d
on e.department_id = d.department_id
<where>
<if test="query.lastName != null and query.lastName != ''">
and e.last_name like concat("%", #{query.lastName}, "%")
</if>
<if test="query.email != null and query.email != ''">
and e.email like concat('%', #{query.email}, '%')
</if>
<if test="query.departmentName != null and query.departmentName != ''">
and d.department_name like concat('%', #{query.departmentName}, '%')
</if>
</where>
</select>
</mapper>
查询DTO
java
package com.atguigu.dto;
import lombok.Data;
@Data
public class EmpQueryDTO {
private String firstName;
private String lastName;
private String email;
private String departmentName;
private Integer pageNum = 1; // 默认第1页
private Integer pageSize = 10; // 默认每页10条
}
连表查询结果VO
java
package com.atguigu.vo;
import lombok.Data;
@Data
public class EmpDepartmentsVO {
// employees表
private Long employeeId;
private String firstName;
private String lastName;
private String email;
// departments表
private Long departmentId;
private String departmentName;
}
service
EmployeesService接口
java
package com.atguigu.service;
import com.atguigu.dto.EmpQueryDTO;
import com.atguigu.pojo.Employees;
import com.atguigu.vo.EmpDepartmentsVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface EmployeesService extends IService<Employees> {
IPage<Employees> getEmpList(EmpQueryDTO empQueryDTO);
IPage<EmpDepartmentsVO> getEmpDepartmentList(EmpQueryDTO empQueryDTO);
}
EmployeesServiceImpl.java
java
package com.atguigu.service.impl;
import com.atguigu.dto.EmpQueryDTO;
import com.atguigu.mapper.EmpMapper;
import com.atguigu.pojo.Employees;
import com.atguigu.service.EmployeesService;
import com.atguigu.vo.EmpDepartmentsVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmployeesServiceImpl extends ServiceImpl<EmpMapper, Employees> implements EmployeesService {
@Autowired
private EmpMapper empMapper;
@Override
public IPage<Employees> getEmpList(EmpQueryDTO empQueryDTO) {
Page<Employees> page = new Page<>(empQueryDTO.getPageNum(), empQueryDTO.getPageSize());
return empMapper.selectEmpList(page, empQueryDTO);
}
@Override
public IPage<EmpDepartmentsVO> getEmpDepartmentList(EmpQueryDTO empQueryDTO) {
Page<EmpDepartmentsVO> page = new Page<>(empQueryDTO.getPageNum(), empQueryDTO.getPageSize());
return empMapper.selectEmpDepartmentList(page, empQueryDTO);
}
}
controller
java
package com.atguigu.controller;
import com.atguigu.common.PageVO;
import com.atguigu.common.Result;
import com.atguigu.dto.EmpQueryDTO;
import com.atguigu.pojo.Employees;
import com.atguigu.service.EmployeesService;
import com.atguigu.vo.EmpDepartmentsVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/emp")
public class EmpController {
@Autowired
private EmployeesService empService;
@GetMapping("/list")
public Result<PageVO<Employees>> getEmployeeList(EmpQueryDTO empQueryDTO) {
IPage<Employees> page = empService.getEmpList(empQueryDTO);
return Result.success(PageVO.restPage(page));
}
@GetMapping("/empDepartment/list")
public Result<PageVO<EmpDepartmentsVO>> getEmpDepartmentList(EmpQueryDTO empQueryDTO) {
IPage<EmpDepartmentsVO> page = empService.getEmpDepartmentList(empQueryDTO);
return Result.success(PageVO.restPage(page));
}
}
启动类
java
package com.atguigu;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.atguigu.mapper")
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}