1. MyBatisPlus枚举处理器深度解析
在SpringCloud微服务开发中,数据持久化是核心环节。MyBatisPlus作为增强版的ORM框架,提供了强大的枚举类型处理能力,这在实际业务场景中非常实用。比如用户状态、订单类型等字段,使用枚举比直接使用数字或字符串更符合面向对象的设计原则。
1.1 枚举类定义规范
一个完整的枚举类定义应该包含以下要素:
java复制@Getter
public enum UserStatus {
NORMAL(1,"正常"),
FROZEN(2,"冻结");
@EnumValue // 标记数据库存储的字段值
@JsonValue // 控制返回给前端的序列化值
private final int value;
private final String desc;
UserStatus(int value,String desc){
this.value=value;
this.desc=desc;
}
}
这里有几个关键点需要注意:
@EnumValue注解是MyBatisPlus特有的,用于标识哪个字段值应该存入数据库@JsonValue来自Jackson库,控制枚举序列化为JSON时的输出值- 实际开发中建议使用final修饰字段,避免状态被意外修改
1.2 枚举字段的实践应用
在实体类中使用枚举类型非常简单:
java复制// 修改前
private Integer status;
// 修改后
private UserStatus status;
业务逻辑中使用枚举比直接使用魔数(magic number)更安全:
java复制if(user == null || user.getStatus() == UserStatus.FROZEN) {
throw new BusinessException("用户已被冻结");
}
经验提示:在定义枚举时,建议实现一个静态方法通过value获取枚举实例,这样可以从数据库值快速转换为枚举对象:
java复制public static UserStatus of(Integer value) { return Arrays.stream(values()) .filter(item -> item.value == value) .findFirst() .orElse(null); }
2. MyBatisPlus分页插件实战
分页查询是业务系统中最常见的需求之一,MyBatisPlus的分页插件提供了非常便捷的实现方式。
2.1 分页插件配置详解
标准配置类应该包含以下内容:
java复制@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件配置
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
pageInterceptor.setMaxLimit(1000L); // 单页最大记录数限制
pageInterceptor.setOverflow(true); // 超出页码是否返回首页
interceptor.addInnerInterceptor(pageInterceptor);
return interceptor;
}
}
关键参数说明:
DbType.MYSQL:指定数据库类型,插件会根据不同类型生成不同的分页SQLsetMaxLimit(1000L):防止恶意请求超大分页导致内存溢出setOverflow(true):请求页码超过总页数时返回第一页数据
2.2 分页查询实践案例
完整的服务层分页查询示例:
java复制public Page<User> queryUserPage(int pageNo, int pageSize, String sortField, boolean isAsc) {
// 构建分页条件
Page<User> page = Page.of(pageNo, pageSize);
// 添加排序条件
if(StringUtils.isNotBlank(sortField)){
page.addOrder(new OrderItem(sortField, isAsc));
}
// 执行分页查询
return userService.page(page);
}
常见问题:当需要多字段排序时,可以添加多个OrderItem:
java复制page.addOrder(new OrderItem("create_time", false)) // 按创建时间降序 .addOrder(new OrderItem("id", true)); // 按ID升序
3. Docker核心概念与基础操作
Docker已经成为现代应用部署的标准工具,理解其核心概念对开发人员至关重要。
3.1 镜像与容器关系解析
镜像(Image)和容器(Container)是Docker最核心的两个概念:
- 镜像:类似于面向对象中的"类",是一个只读模板,包含运行应用所需的所有内容
- 容器:是镜像的运行实例,类似于"对象",每个容器都是独立隔离的环境
类比理解:
- 镜像就像是一个软件安装包(.exe/.dmg文件)
- 容器就是安装后正在运行的程序
3.2 Docker常用命令速查表
| 命令 | 说明 | 常用参数 |
|---|---|---|
docker run |
创建并运行容器 | -d(后台运行)、--name(命名)、-p(端口映射) |
docker ps |
查看运行中的容器 | -a(显示所有容器) |
docker stop |
停止容器 | 容器ID/名称 |
docker rm |
删除容器 | -f(强制删除运行中的) |
docker images |
查看镜像列表 | -q(只显示ID) |
docker rmi |
删除镜像 | 镜像ID/名称 |
docker logs |
查看容器日志 | -f(实时跟踪) |
3.3 端口映射与数据卷
端口映射让容器服务可以被外部访问:
bash复制docker run -p 8080:80 nginx
这表示将容器的80端口映射到主机的8080端口
数据卷(Volume)实现数据持久化:
bash复制docker run -v /宿主机路径:/容器内路径 mysql
注意事项:生产环境推荐使用命名卷而非直接挂载主机目录:
bash复制docker volume create mydata docker run -v mydata:/var/lib/mysql mysql
4. Dockerfile与镜像构建
4.1 Dockerfile核心指令详解
一个典型的Java应用Dockerfile示例:
dockerfile复制# 基础镜像
FROM openjdk:11-jre
# 设置工作目录
WORKDIR /app
# 复制应用jar包
COPY target/myapp.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java","-jar","app.jar"]
常用指令说明:
FROM:指定基础镜像,推荐使用官方镜像COPY:复制文件到镜像中,注意目标路径EXPOSE:声明运行时监听的端口(实际映射仍需-p参数)ENTRYPOINT:容器启动时执行的命令
4.2 多阶段构建优化
对于Java应用,可以使用多阶段构建减小镜像体积:
dockerfile复制# 构建阶段
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src/ ./src/
RUN mvn package
# 运行阶段
FROM openjdk:11-jre
WORKDIR /app
COPY --from=builder /build/target/myapp.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
这种构建方式可以去除构建工具等不必要的依赖,使最终镜像更精简。
5. Docker网络与多容器编排
5.1 Docker网络模式比较
Docker支持多种网络模式:
| 网络模式 | 特点 | 适用场景 |
|---|---|---|
| bridge | 默认模式,容器通过虚拟网桥连接 | 单机容器通信 |
| host | 容器直接使用主机网络 | 高性能网络需求 |
| none | 无网络配置 | 特殊安全需求 |
| overlay | 跨主机容器网络 | Swarm集群环境 |
5.2 Docker Compose实战
典型的docker-compose.yml文件示例:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- mynet
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
networks:
- mynet
volumes:
mysql_data:
networks:
mynet:
driver: bridge
关键配置说明:
depends_on:定义服务启动顺序volumes:声明数据卷,实现数据持久化networks:自定义网络,使服务可以通过服务名互访
部署技巧:使用
docker-compose up -d后台启动,docker-compose logs -f查看日志
6. SpringCloud与Docker集成实践
6.1 容器化SpringBoot应用
为SpringBoot应用添加Docker支持:
- 首先确保应用有健康检查端点:
properties复制management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=health,info
- 编写Dockerfile:
dockerfile复制FROM openjdk:11-jre
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- 构建并运行:
bash复制mvn package
docker build -t myapp .
docker run -p 8080:8080 myapp
6.2 容器间服务调用
在docker-compose中配置SpringCloud服务发现:
yaml复制services:
eureka:
image: springcloud/eureka-server
ports:
- "8761:8761"
user-service:
build: ./user-service
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka:8761/eureka
depends_on:
- eureka
在应用配置中指定服务发现:
properties复制eureka.client.serviceUrl.defaultZone=http://eureka:8761/eureka
这样服务之间就可以通过服务名进行调用,而不需要关心具体的IP地址。