Spring Boot 实战:从0到1搭建简单管理后台

Spring Boot 3.0新特性实战:从零搭建微服务架构 Jakarta EE 9迁移:包名从javax变更为jakarta。原生镜像支持:通过GraalVM支持生成原生可执行文件,提高启动速度和减少内存占用。AOT(Ahead-of-Time)处理:在构建时而不是运行时进行部分处理,提高性能。增强的Observability:改进了指标、健康检查和日志记录。Spring WebFlux和RSocket增强:提供了更好的响应式编程支持。Spring Boot 3.0带来了许多新特性和改进,使得构建微服务架构更加高效和便捷。 阅读详情

Spring Boot 实战:从0到1搭建简单管理后台

本文专为Spring Boot新手量身打造,全程剔除所有导包代码,聚焦核心实操步骤,用详实的文字描述补充每一步的细节的逻辑,让新手不仅能复制代码运行,还能理解每一步的意义,快速搭建出可落地、可扩展的简单管理后台。教程兼顾简洁性和实用性,不冗余、不堆砌,重点补充操作说明、逻辑讲解和避坑细节,确保即使是刚接触Spring Boot的开发者,也能跟着一步步完成搭建,最终实现完整的用户管理、角色菜单管理等核心功能。

本教程的核心优势的是“无导包、重实操、强落地”,所有代码均剔除package和import语句,直接复制即可使用,同时补充足够的文字描述,理清项目搭建的逻辑的脉络,避免新手走弯路,真正实现“从0到1”的完整落地。

一、核心目标与技术栈

1.1 核心需求(明确搭建方向)

本次搭建的简单管理后台,聚焦企业级后台的基础核心功能,无需复杂的权限细化和前端页面,重点实现后端核心接口,满足日常管理场景的基础需求,具体核心需求如下:

  • 用户管理模块:实现用户的新增、删除、修改、分页查询,搭配Excel导入导出功能,方便批量操作用户数据;同时集成Redis缓存,提升查询效率,避免重复查询数据库;密码采用加密存储,保障数据安全。

  • 角色/菜单管理模块:实现角色和菜单的基础CRUD操作,通过多对多关联表实现角色与用户、角色与菜单的关联,为后续权限控制打下基础,逻辑清晰且符合企业级开发规范。

  • 辅助功能模块:集成全局异常处理,统一接口响应格式,避免接口报错时返回杂乱信息,提升项目健壮性;添加定时任务,用于清理系统操作日志,减少数据库冗余;集成异步任务,演示邮件通知等异步场景,丰富项目功能。

1.2 技术栈选型(新手友好,稳定适配)

技术栈选型遵循“稳定、简洁、新手易上手”的原则,避免使用复杂且难上手的框架,所有技术均为企业级开发常用版本,适配性强,无需额外配置复杂环境,具体选型如下:

核心框架:Spring Boot 2.7.x(稳定版,兼容性强,新手易上手,避免使用最新版导致的依赖兼容问题)

数据访问:MyBatis-Plus 3.5.x(简化MyBatis操作,自带CRUD方法,无需手动编写基础SQL,提升开发效率)

数据库:MySQL 8.0(主流关系型数据库,稳定性高,适配大部分企业级场景,操作简单易上手)

缓存技术:Redis 6.x(轻量级缓存,用于缓存热点数据,减少数据库压力,提升接口响应速度)

工具类:Lombok(简化实体类编写,无需手动生成get/set方法,减少代码冗余)、EasyExcel 3.3.2(简单易用的Excel导入导出工具,适配各类Excel格式,避免复杂的POI操作)

其他:Spring Web(实现HTTP接口开发)、Spring Cache(整合Redis缓存)、Spring异步/定时注解(实现异步任务和定时任务)

避坑提示:技术栈版本需严格对应,Spring Boot 2.7.x需搭配MyBatis-Plus 3.5.x,避免版本不兼容导致项目启动失败;Redis需提前安装并启动,确保本地Redis服务正常运行,否则缓存功能无法生效;MySQL建议使用8.0版本,低版本可能存在语法兼容问题。

二、数据库设计(极简适配,直接执行)

数据库设计是后台项目的基础,本次设计遵循“简洁、实用、可扩展”的原则,设计5张核心数据表,覆盖用户、角色、菜单、关联关系和操作日志,所有表结构均经过简化,去除冗余字段,适配本次后台项目的核心需求,同时保证符合企业级开发规范,SQL语句可直接复制到MySQL中执行,无需修改。

设计思路:采用“用户-角色-菜单”的权限模型,通过多对多关联表实现三者之间的关联,确保权限逻辑清晰;用户表存储核心用户信息,密码加密存储;日志表用于存储用户操作记录,配合定时任务实现自动清理,减少数据库冗余。

CREATE DATABASE IF NOT EXISTS management_db CHARACTER SET utf8mb4;
USE management_db;

-- 用户表:存储用户核心信息,密码加密存储,状态控制启用/禁用
CREATE TABLE `sys_user` (
  `id` bigint(20) AUTO_INCREMENT,
  `username` varchar(50) NOT NULL UNIQUE,
  `password` varchar(100) NOT NULL,
  `status` tinyint(1) DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- 角色表:存储角色信息,用于关联用户和菜单
CREATE TABLE `sys_role` (`id` bigint(20) AUTO_INCREMENT, `role_name` varchar(50) NOT NULL UNIQUE, PRIMARY KEY (`id`)) ENGINE=InnoDB;

-- 菜单表:存储菜单信息,用于权限控制的基础
CREATE TABLE `sys_menu` (`id` bigint(20) AUTO_INCREMENT, `menu_name` varchar(50) NOT NULL, `parent_id` bigint(20) DEFAULT 0, PRIMARY KEY (`id`)) ENGINE=InnoDB;

-- 用户-角色关联表:实现用户与角色的多对多关联,避免重复关联
CREATE TABLE `sys_user_role` (
  `id` bigint(20) AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `role_id` bigint(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_user_role` (`user_id`,`role_id`)
) ENGINE=InnoDB;

-- 角色-菜单关联表:实现角色与菜单的多对多关联,控制菜单访问权限
CREATE TABLE `sys_role_menu` (
  `id` bigint(20) AUTO_INCREMENT,
  `role_id` bigint(20) NOT NULL,
  `menu_id` bigint(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_role_menu` (`role_id`,`menu_id`)
) ENGINE=InnoDB;

-- 操作日志表:存储用户操作记录,用于定时清理演示
CREATE TABLE `sys_log` (
  `id` bigint(20) AUTO_INCREMENT,
  `operation` varchar(100) NOT NULL,
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

实操提示:执行SQL前,务必确保MySQL服务正常启动;如果本地MySQL密码不是123456,后续配置文件中需对应修改;执行完成后,可通过Navicat、DBeaver等工具查看表结构,确认所有表创建成功后再继续后续操作;若执行过程中报错,检查MySQL版本是否为8.0,以及SQL语句是否完整复制。

三、项目初始化(3步搭建骨架,新手可直接跟着做)

项目初始化是搭建后台项目的基础,这一步的核心是搭建项目骨架、配置核心依赖和参数,确保后续功能能够正常开发和运行。本部分步骤清晰,每一步都补充详细的文字描述,明确操作目的和注意事项,新手无需具备复杂的开发经验,跟着步骤操作即可完成,避免走弯路。

3.1 新建Spring Boot项目(两种方式,任选其一)

为了适配不同新手的操作习惯,提供两种新建项目的方式,两种方式最终效果一致,可根据自己的实际情况选择,重点是配置正确的项目信息和依赖,确保项目骨架搭建成功。

方式1:通过Spring Initializr(在线创建,推荐新手,无需配置本地环境)

操作步骤详细说明:首先访问Spring Initializr官方网站(https://start.spring.io/),进入在线创建页面,该页面是Spring官方提供的项目快速创建工具,无需安装额外软件,操作简单。进入页面后,配置项目基本信息,Group可自定义(如com.example),Artifact为项目名称(建议命名为management-background,便于识别),Type选择Maven(新手友好,依赖管理更简单),Java版本选择8(主流版本,兼容性强),Spring Boot版本选择2.7.17(稳定版,避免使用最新版导致依赖兼容问题)。

配置完成后,勾选核心依赖,直接在搜索框中搜索对应的依赖并勾选,无需手动添加,勾选的依赖包括:Spring Web(用于开发HTTP接口)、MyBatis-Plus(简化数据库操作)、MySQL Driver(连接MySQL数据库)、Spring Data Redis(整合Redis缓存)、Spring Cache(启用缓存功能)、Lombok(简化实体类编写)。所有依赖勾选完成后,点击“Generate”按钮下载项目压缩包,解压后导入IDEA(或Eclipse),等待Maven依赖加载完成,加载时间根据网络情况而定,耐心等待即可,加载完成后无报错,说明项目骨架搭建成功。

方式2:IDEA本地创建(适合已安装IDEA的新手)

操作步骤:打开IDEA,点击“New Project”,在弹出的窗口中选择“Spring Initializr”,点击“Next”,后续的项目基本信息配置、依赖勾选,与方式1完全一致,配置完成后,选择项目保存路径,点击“Finish”,等待Maven依赖加载完成即可。

注意事项:依赖加载过程中,若出现依赖下载失败,可刷新Maven缓存(IDEA中点击右上角刷新按钮);若刷新后仍失败,检查网络连接,或更换Maven镜像源,确保依赖能够正常下载;Java版本建议选择8,避免使用更高版本导致部分依赖不兼容。

3.2 补充Maven依赖(完善功能,复制粘贴即可)

Spring Initializr勾选的依赖仅能满足基础功能需求,为了实现Excel导入导出、密码加密、文件操作等核心功能,需要补充部分依赖。打开项目的pom.xml文件,在标签内添加以下依赖,添加后点击IDEA右上角“刷新”按钮,加载新增依赖,无需修改任何内容,直接复制粘贴即可。

补充说明:新增的依赖各有作用,EasyExcel用于实现Excel导入导出功能,无需编写复杂的POI代码;Spring Security Crypto用于密码加密,保障用户密码安全;Commons-IO用于文件操作,适配Excel导入时的文件处理;Commons-Pool2用于Redis连接池配置,提升Redis缓存的性能和稳定性,所有依赖版本均经过适配,无需修改版本号,避免兼容性问题。

<!-- EasyExcel 导入导出依赖(核心) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>
<!-- 密码加密依赖(Spring Security Crypto) -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-crypto</artifactId>
</dependency>
<!-- 文件操作依赖(Commons-IO,适配Excel导入) -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- Redis连接池依赖(提升Redis性能) -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

3.3 核心配置(application.yml,关键一步)

配置文件是项目运行的核心,用于连接数据库、Redis,配置MyBatis-Plus、缓存、服务器等参数,直接决定项目能否正常启动和运行。操作步骤:删除项目默认的application.properties文件,新建application.yml文件(右键resources → New → File,文件名输入application.yml),复制以下配置内容,根据自己的本地环境修改对应参数,配置说明清晰,便于新手理解和修改。

配置说明:数据库配置部分,需修改password为自己的MySQL密码,url中的management_db是之前创建的数据库名称,无需修改;Redis配置部分,若本地Redis设置了密码,填写对应的密码,无密码则留空;MyBatis-Plus配置部分,mapper-locations指定Mapper XML文件的路径,type-aliases-package指定实体类包路径,需与自己的项目包名一致;服务器配置部分,端口8080若被占用,可修改为8081等未被占用的端口,context-path为项目访问前缀,后续访问接口需加上该前缀。

spring:
  # 数据库配置(核心,修改为自己的MySQL密码)
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/management_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root # 数据库用户名(默认root)
    password: 123456 # 替换为自己的MySQL密码(重要)

  # Redis配置(缓存用,默认本地Redis,无需修改)
  redis:
    host: localhost # Redis地址(本地为localhost)
    port: 6379 # Redis端口(默认6379)
    password: # 若Redis设置了密码,填写密码,无密码则留空
    database: 0 # Redis数据库索引(默认0)
    lettuce: # Redis连接池配置(提升性能)
      pool:
        max-active: 16 # 最大连接数
        max-idle: 8 # 最大空闲连接数
        min-idle: 4 # 最小空闲连接数
        max-wait: 1000 # 最大等待时间(毫秒)

  # 缓存配置(启用Redis缓存,替代默认本地缓存)
  cache:
    type: redis # 缓存类型:Redis
    redis:
      time-to-live: 3600000 # 缓存默认过期时间(1小时,单位:毫秒)
      cache-null-values: false # 不缓存null值,避免缓存穿透
      key-prefix: management:cache: # 缓存key前缀,避免与其他Redis数据冲突
      use-key-prefix: true # 启用key前缀

  # 定时任务与异步任务配置(无需修改)
  task:
    scheduling: # 定时任务线程池
      pool:
        size: 5 # 线程池大小
        thread-name-prefix: scheduled-task- # 线程名称前缀
    execution: # 异步任务线程池
      pool:
        core-size: 5 # 核心线程数
        max-size: 10 # 最大线程数
        queue-capacity: 20 # 队列容量

# MyBatis-Plus 配置(简化数据库操作,无需修改)
mybatis-plus:
  mapper-locations: classpath:mybatis/mapper/**/*.xml # Mapper XML文件路径
  type-aliases-package: com.example.management.entity # 实体类包路径(对应自己的包名)
  configuration:
    map-underscore-to-camel-case: true # 开启下划线转驼峰(如user_name → userName)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL语句,便于调试

# 服务器配置(无需修改,端口被占用可调整)
server:
  port: 8080 # 项目端口(默认8080)
  servlet:
    context-path: /management # 项目访问路径前缀(访问接口时需加上)

3.4 项目目录结构(规范简洁,便于维护)

为了让项目结构清晰,便于后续开发和维护,按照“分层架构”设计目录,明确区分各模块的功能,新手可直接按照以下目录结构创建包和文件,包名需与配置文件中“type-aliases-package”一致(如com.example.management),避免出现路径错误。

目录结构说明:config包用于存放自定义配置类(如Redis缓存序列化配置);entity包用于存放实体类,对应数据库中的数据表;dto包用于存放数据传输对象(如Excel导入导出DTO);mapper包用于存放MyBatis-Plus Mapper接口,实现数据库操作;service包用于存放业务逻辑,分为接口和实现类;controller包用于开发接口,对外提供访问入口;listener包用于存放Excel导入监听器;util包用于存放通用工具类;exception包用于存放全局异常处理相关类。

com.example.management
├── ManagementApplication.java  # 项目启动类(开启缓存、异步、定时任务)
├── config/                     # 配置类包(自定义配置)
├── entity/                     # 实体类包(对应数据库表)
├── dto/                        # 数据传输对象包(Excel导入导出、接口参数)
├── mapper/                     # MyBatis-Plus Mapper接口包
├── service/                    # Service层包(核心业务逻辑)
│   └── impl/                   # Service实现类包
├── controller/                 # Controller层包(接口开发)
├── listener/                   # EasyExcel监听器包(Excel导入用)
├── util/                       # 工具类包(通用工具,复用性强)
└── exception/                  # 全局异常处理包

3.5 启动类配置(开启核心功能,关键一步)

项目启动类是项目的入口,需要添加相关注解,开启缓存、异步任务、定时任务等核心功能,同时扫描Mapper接口,确保数据库操作能够正常生效。无需编写复杂代码,添加对应的注解即可,具体代码如下,直接复制到启动类中,确保类名与项目包名对应。

@SpringBootApplication
@MapperScan("com.example.management.mapper") // 扫描Mapper接口,确保数据库操作生效
@EnableCaching // 开启缓存功能(Redis缓存)
@EnableAsync // 开启异步任务(如异步邮件通知)
@EnableScheduling // 开启定时任务(如日志清理)
public class ManagementApplication {
    public static void main(String[] args) {
        SpringApplication.run(ManagementApplication.class, args);
        // 启动成功提示,便于确认项目启动状态
        System.out.println("======================================");
        System.out.println("  简单管理后台项目启动成功!");
        System.out.println("  访问地址:http://localhost:8080/management");
        System.out.println("======================================");
    }
}

注意事项:@MapperScan注解的路径必须与自己的Mapper接口包路径一致,否则MyBatis-Plus无法扫描到Mapper接口,会报“找不到Mapper”错误;三个注解(@EnableCaching、@EnableAsync、@EnableScheduling)必须添加,否则对应功能无法生效;启动类名称可自定义,但需与main方法中的类名一致。

四、核心功能实现(极简无导包,完整可落地)

本部分是项目的核心,按照“基础工具类→用户管理模块”的顺序实现,所有代码均剔除导包语句,直接复制即可使用,同时补充详细的文字描述,说明每段代码的功能、逻辑和实操注意事项,让新手不仅能复制代码,还能理解代码的作用,便于后续修改和扩展。核心功能围绕用户管理展开,串联Excel导入导出、Redis缓存、密码加密等知识点,实现完整的用户管理流程。

4.1 基础工具类(简化但完整,复用性强)

基础工具类是项目的通用组件,无需重复编写代码,重点实现密码加密和全局异常处理,密码加密用于保障用户密码安全,全局异常处理用于统一接口响应格式,提升项目健壮性,避免接口报错时返回杂乱的错误信息,便于前端对接。

4.1.1 密码加密工具类(PasswordUtil.java)

用户密码不能明文存储,本工具类使用BCrypt加密算法,该算法安全可靠,不可逆,能够有效保障用户密码安全,实现密码加密和密码校验两个核心方法,加密方法用于用户新增、密码修改时将明文密码转换为密文,校验方法用于用户登录时对比明文密码与数据库中的密文密码是否一致。

// 密码加密工具类:使用BCrypt加密,安全可靠,不可逆
@Component
public class PasswordUtil {
    private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    /**
     * 密码加密:将明文密码加密为密文,存储到数据库
     * @param rawPassword 明文密码(用户输入的密码)
     * @return 加密后的密文密码
     */
    public String encodePassword(String rawPassword) {
        return encoder.encode(rawPassword);
    }

    /**
     * 密码校验:对比明文密码与加密后的密文是否一致(登录时使用)
     * @param rawPassword 明文密码(用户登录输入)
     * @param encodedPassword 数据库中存储的密文密码
     * @return true:密码一致,false:密码不一致
     */
    public boolean matchesPassword(String rawPassword, String encodedPassword) {
        return encoder.matches(rawPassword, encodedPassword);
    }
}
4.1.2 全局异常处理(GlobalExceptionHandler.java)

全局异常处理器用于统一处理项目中所有未捕获的异常,包括系统异常、参数错误异常等,同时定义统一的接口响应格式,让接口返回的信息更规范,便于前端对接。无论接口出现何种异常,都能返回统一格式的响应,避免出现页面报错、返回杂乱错误信息的情况,提升项目的用户体验和健壮性。

// 全局异常处理器:统一处理所有接口异常,统一响应格式
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 统一接口响应格式(泛型,支持所有数据类型)
     * 包含状态码、提示信息、响应数据,规范接口返回格式
     */
    @Data
    public static class Result<T> {
        private Integer code; // 状态码(200:成功,400:参数错误,500:系统错误)
        private String message; // 提示信息
        private T data; // 响应数据(成功时返回,失败时为null)

        // 成功响应(带数据)
        public static <T> Result<T> success(T data) {
            Result&lt;T&gt; result = new Result<>();
            result.setCode(200);
            result.setMessage("操作成功");
            result.setData(data);
            return result;
        }

        // 成功响应(不带数据)
        public static <T> Result<T> success() {
            return success(null);
        }

        // 失败响应(自定义状态码和提示信息)
        public static <T> Result<T> fail(Integer code, String message) {
            Result&lt;T&gt; result = new Result<>();
            result.setCode(code);
            result.setMessage(message);
            result.setData(null);
            return result;
        }
    }

    /**
     * 处理所有未捕获的异常(系统异常)
     * 当项目中出现未捕获的异常时,统一返回500状态码和错误信息
     */
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        // 打印异常信息,便于开发调试(生产环境可注释,或输出到日志文件)
        e.printStackTrace();
        return Result.fail(500, "系统异常:" + e.getMessage());
    }

    /**
     * 处理参数错误异常(如非法参数、参数为空)
     * 专门捕获参数相关的异常,返回400状态码,提示参数错误
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public Result<Void> handleIllegalArgumentException(IllegalArgumentException e) {
        return Result.fail(400, e.getMessage());
    }
}

4.2 用户管理模块实现(核心模块,完整可运行)

用户管理是管理后台的核心模块,集成了用户增删改查、分页查询、Excel导入导出、Redis缓存等核心功能,所有代码均剔除导包语句,直接复制即可使用,同时补充详细的功能说明和实操提示,确保新手能够顺利实现。

4.2.1 实体类与DTO(SysUser.java、ExcelUserDTO.java)

实体类对应数据库中的sys_user表,字段与数据库表字段一一对应,使用Lombok的@Data注解,简化代码编写,无需手动生成get/set方法;ExcelUserDTO用于Excel导入导出,字段与Excel表格字段对应,实现批量导入导出用户数据的功能,同时添加数据校验,确保导入的数据合法。

// 实体类(SysUser.java):对应sys_user表,存储用户核心信息
@Data
@TableName("sys_user") // 关联数据库表名
public class SysUser {
    @TableId(type = IdType.AUTO) // 主键自增,对应数据库id字段
    private Long id;

    private String username; // 用户名(唯一,用于登录)

    private String password; // 加密后的密码,存储到数据库

    private String realName; // 真实姓名(可选,可根据需求添加)

    private Integer status; // 状态(1启用,0禁用)
}

// Excel导入导出DTO(ExcelUserDTO.java):与Excel表格字段对应
@Data
public class ExcelUserDTO {
    @ExcelIgnore // Excel导入导出时忽略该字段(自增主键,无需导入)
    private Long id;

    @ExcelProperty(value = "用户名", index = 0) // Excel第1列,列名“用户名”
    private String username;

    @ExcelProperty(value = "密码", index = 1) // Excel第2列,列名“密码”
    private String password;

    @ExcelProperty(value = "真实姓名", index = 2) // Excel第3列,列名“真实姓名”
    private String realName;

    @ExcelIgnore // 状态默认启用,无需导入导出
    private Integer status = 1;
}
4.2.2 Mapper与Service层(数据库操作与业务逻辑)

Mapper接口继承MyBatis-Plus的BaseMapper,自带增删改查、分页等基础方法,无需手动编写SQL;Service层实现核心业务逻辑,包括分页查询(集成Redis缓存)、Excel导入导出、用户状态更新等功能,串联密码加密、缓存等知识点,确保业务逻辑清晰、可复用。

// Mapper(SysUserMapper.java):数据库操作接口,无需编写SQL
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {}

// Service接口(SysUserService.java):定义业务方法
public interface SysUserService extends IService<SysUser> {
    // 分页查询用户(带Redis缓存)
    List<SysUser> getUserList(Integer pageNum, Integer pageSize);
    // Excel批量导入用户
    void importUser(MultipartFile file);
    // Excel导出用户
    void exportUser(HttpServletResponse response);
    // 启用/禁用用户
    boolean updateUserStatus(Long userId, Integer status);
}

// Service实现类(SysUserServiceImpl.java):核心业务逻辑实现
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired private PasswordUtil passwordUtil;

    /**
     * 分页查询用户:查询前先检查缓存,有缓存直接返回,无缓存查询数据库并存入缓存
     * @Cacheable:缓存注解,指定缓存名称和缓存key,避免缓存冲突
     */
    @Override
    @Cacheable(value = "user", key = "'list:pageNum:'+#pageNum+':pageSize:'+#pageSize")
    public List<SysUser> getUserList(Integer pageNum, Integer pageSize) {
        // 分页查询(MyBatis-Plus自带分页方法,无需编写SQL)
        Page<SysUser&gt; page = new Page<>(pageNum, pageSize);
        IPage<SysUser> userIPage = baseMapper.selectPage(page, null);
        return userIPage.getRecords(); // 返回分页数据列表
    }

    /**
     * Excel批量导入用户:批量插入数据,导入后清空缓存,避免缓存脏数据
     * @CacheEvict:清空用户相关缓存,确保缓存与数据库数据一致
     * @Transactional:事务注解,导入失败回滚,避免数据异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "user", allEntries = true)
    public void importUser(MultipartFile file) throws IOException {
        // 读取Excel文件,通过监听器处理每一行数据
        EasyExcel.read(file.getInputStream(), ExcelUserDTO.class, new ExcelUserImportListener(this, passwordUtil))
                .sheet() // 读取第一个sheet
                .headRowNumber(1) // 第1行为表头,从第2行开始读取数据
                .doRead(); // 开始读取并处理数据
    }

    /**
     * Excel导出用户:查询所有用户数据,导出为Excel文件,便于批量查看
     */
    @Override
    public void exportUser(HttpServletResponse response) throws IOException {
        // 1. 查询所有用户数据(实际项目可添加筛选条件)
        List<SysUser> userList = baseMapper.selectList(null);

        // 2. 将实体类转换为DTO(适配Excel导出字段)
        List<ExcelUserDTO> dtoList = userList.stream().map(user -> {
            ExcelUserDTO dto = new ExcelUserDTO();
            BeanUtils.copyProperties(user, dto); // 复制属性(实体类→DTO)
            return dto;
        }).collect(Collectors.toList());

        // 3. 配置响应头,避免Excel下载乱码
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("用户数据_" + System.currentTimeMillis(), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        // 4. 导出Excel文件
        EasyExcel.write(response.getOutputStream(), ExcelUserDTO.class)
                .sheet("用户列表") // sheet名称
                .doWrite(dtoList); // 写入数据
    }

    /**
     * 启用/禁用用户:更新用户状态,更新后清空缓存
     */
    @Override
    @CacheEvict(value = "user", allEntries = true)
    public boolean updateUserStatus(Long userId, Integer status) {
        // 校验状态参数,避免非法状态
        if (status != 0 && status != 1) {
            throw new IllegalArgumentException("状态参数错误,只能是0(禁用)或1(启用)");
        }

        // 更新用户状态
        SysUser user = new SysUser();
        user.setId(userId);
        user.setStatus(status);
        return updateById(user);
    }
}
4.2.3 Controller层(接口开发,对外提供访问)

Controller层是接口的入口,对外提供用户管理相关的HTTP接口,包括分页查询、新增、修改、删除、Excel导入导出、状态更新等接口,接口路径规范,统一响应格式,便于前端对接,所有接口均有清晰的说明,明确请求方式、请求参数和访问路径。

// 用户管理接口:对外提供访问入口,统一响应格式
@RestController
@RequestMapping("/user") // 接口路径前缀,访问接口时需加上
public class SysUserController {
    @Autowired private SysUserService sysUserService;
    @Autowired private PasswordUtil passwordUtil;

    /**
     * 分页查询用户
     * 访问路径:http://localhost:8080/management/user/list?pageNum=1&pageSize=10
     * @param pageNum 页码(默认1)
     * @param pageSize 每页条数(默认10)
     */
    @GetMapping("/list")
    public Result<List<SysUser>> getUserList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        List<SysUser> userList = sysUserService.getUserList(pageNum, pageSize);
        return Result.success(userList);
    }

    /**
     * 新增用户
     * 访问路径:http://localhost:8080/management/user/add(POST请求)
     * 请求参数:JSON格式,如{"username":"test","password":"123456","realName":"测试用户"}
     */
    @PostMapping("/add")
    public Result<Void> addUser(@RequestBody SysUser user) {
        // 校验用户名和密码不为空
        if (user.getUsername() == null || user.getUsername().isEmpty()) {
            return Result.fail(400, "用户名不能为空");
        }
        if (user.getPassword() == null || user.getPassword().isEmpty()) {
            return Result.fail(400, "密码不能为空");
        }
        // 密码加密,避免明文存储
        user.setPassword(passwordUtil.encodePassword(user.getPassword()));
        // 保存用户
        boolean success = sysUserService.save(user);
        return success ? Result.success() : Result.fail(400, "新增用户失败");
    }

    /**
     * Excel批量导入用户
     * 访问路径:http://localhost:8080/management/user/import(POST请求)
     * 请求参数:multipart/form-data格式,上传Excel文件
     */
    @PostMapping("/import")
    public Result<Void> importUser(@RequestParam("file") MultipartFile file) {
        try {
            sysUserService.importUser(file);
            return Result.success();
        } catch (Exception e) {
            return Result.fail(400, "Excel导入失败:" + e.getMessage());
        }
    }

    /**
     * Excel导出用户
     * 访问路径:http://localhost:8080/management/user/export(GET请求)
     * 直接访问即可下载Excel文件
     */
    @GetMapping("/export")
    public void exportUser(HttpServletResponse response) {
        try {
            sysUserService.exportUser(response);
        } catch (Exception e) {
            // 捕获异常,返回错误信息
            Result.fail(400, "Excel导出失败:" + e.getMessage());
        }
    }

    /**
     * 启用/禁用用户
     * 访问路径:http://localhost:8080/management/user/status/1/0(PUT请求)
     * @param userId 用户ID
     * @param status 状态(0禁用,1启用)
     */
    @PutMapping("/status/{userId}/{status}")
    public Result<Void> updateUserStatus(@PathVariable Long userId, @PathVariable Integer status) {
        boolean success = sysUserService.updateUserStatus(userId, status);
        return success ? Result.success() : Result.fail(400, "更新用户状态失败");
    }

    /**
     * 单条删除用户
     * 访问路径:http://localhost:8080/management/user/1(DELETE请求,1为用户ID)
     */
    @DeleteMapping("/{userId}")
    public Result<Void> deleteUser(@PathVariable Long userId) {
        boolean success = sysUserService.removeById(userId);
        return success ? Result.success() : Result.fail(400, "删除用户失败");
    }
}
4.2.4 Excel导入监听器(ExcelUserImportListener.java)

Excel导入时,需要通过监听器处理每一行数据,实现数据校验、密码加密、批量插入等功能,确保导入的数据合法、准确,避免出现数据异常,监听器代码直接复制即可使用,无需修改。

// Excel导入监听器:处理Excel每一行数据,实现批量导入
@Slf4j
@Getter
public class ExcelUserImportListener extends AnalysisEventListener<ExcelUserDTO> {

    private static final int BATCH_SIZE = 100; // 批量插入批次大小,提升导入效率
    private List&lt;ExcelUserDTO&gt; userList = new ArrayList<>(); // 临时存储导入数据
    private final SysUserService userService; // 用户Service,用于插入数据
    private final PasswordUtil passwordUtil; // 密码加密工具类
    private int importCount = 0; // 导入成功条数

    // 构造方法,注入Service和密码工具类
    public ExcelUserImportListener(SysUserService userService, PasswordUtil passwordUtil) {
        this.userService = userService;
        this.passwordUtil = passwordUtil;
    }

    /**
     * 每读取一行Excel数据,执行一次该方法
     */
    @Override
    public void invoke(ExcelUserDTO data, AnalysisContext context) {
        // 数据校验(简单校验,可根据需求扩展)
        if (data.getUsername() == null || data.getUsername().isEmpty()) {
            throw new RuntimeException("第" + (context.readRowHolder().getRowIndex() + 1) + "行:用户名不能为空");
        }
        if (data.getPassword() == null || data.getPassword().isEmpty()) {
            throw new RuntimeException("第" + (context.readRowHolder().getRowIndex() + 1) + "行:密码不能为空");
        }

        // 密码加密,将Excel中的明文密码转换为密文
        data.setPassword(passwordUtil.encodePassword(data.getPassword()));

        // 将数据加入临时列表
        userList.add(data);

        // 达到批次大小,批量插入数据,避免内存溢出
        if (userList.size() >= BATCH_SIZE) {
            batchInsert();
            userList.clear(); // 清空临时列表
        }
    }

    /**
     * Excel读取完成后,执行一次该方法,处理剩余数据
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (!userList.isEmpty()) {
            batchInsert(); // 处理剩余不足批次的数据
            userList.clear();
        }
        log.info("Excel用户导入完成,共导入{}条数据", importCount);
    }

    /**
     * 批量插入数据:将DTO转换为实体类,批量保存到数据库
     */
    private void batchInsert() {
        // DTO转换为实体类
        List<SysUser> sysUsers = userList.stream().map(dto -> {
            SysUser user = new SysUser();
            BeanUtils.copyProperties(dto, user);
            return user;
        }).toList();

        // 批量插入(MyBatis-Plus自带批量保存方法,提升效率)
        userService.saveBatch(sysUsers);

        // 更新导入成功条数
        importCount += sysUsers.size();
    }
}

实操提示:1. 所有代码均无导包,直接复制到对应类中即可使用,确保类名与文件名一致;2. 运行项目前,确保MySQL和Redis服务正常启动,配置文件中的数据库密码已修改为自己的;3. 测试接口时,可使用Postman工具,按照Controller层的接口路径和请求方式测试,确保接口正常返回数据;4. 角色、菜单模块的实现逻辑与用户模块一致,可参考用户模块仿写,核心是实体类、Mapper、Service、Controller的层层对应。

超详细从0开始搭建 Spring Boot 项目 1.0.0 创建项目 我使用的ide 是 idea 创建项目 选择 Spring initializr ,如果点Next一直在转圈,可能是 start.spring.io/ 在国外,访问比较慢。可以科学上网或者,使用自定义的 start.spring.io/ 主要改以下组织名称、项目名称和项目描述就好了 我创建项目的时候, Spring Boot 最新稳定版是 2.1.9 。要用就用最新的!!! 依赖先都不勾选,后期一项一项加 项目文件夹名称以及存放位置 添加maven镜像 添加 阅读详情

相关推荐

Spring Boot 从入门到精通:全面解析与实战指南

Spring Boot 是由 Pivotal 团队提供的全新框架,它基于 Spring 4.0 设计,不仅继承了 Spring 框架原有的优秀特性,还通过简化配置、自动化依赖管理等机制,降低了 Spring 应用的开发门槛,让开发者可以用最少的配置快速搭建一个生产级别的 Spring 应用程序。起步依赖是一种 Maven 项目对象模型(POM),定义了项目所需的相关依赖。以 Web 应用为例,当引入spring-boot-starter-web依赖后,Spring Boot 会自动配置以下内容:​。

daylight的博客 1257

《springboot实战》第一章 SpringBoot起步

使用Idea初始化springboot2.7工程

Java 技术专栏,从入门到精通,熟悉企业级开发 1720

Spring Boot在MyEclipse下的搭建

说明Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。特点1. 创建独立的Spring应用程序2. 嵌入的To...

芸灵fly的博客 1万+

SpringBoot实战——个人博客项目

项目名称:个人博客系统主要操作的对象是:文章和用户,用户可在该系统上发表自己的博客,查看自己或别人已经发表的文章需要用到两张表:userinfo(用户表)、articleinfo(文章表)登录+注册博客的分页列表功能新增发表博客修改、删除自己的博客项目技术栈MySQLjQuery项目亮点手动对用户密码实现随机加盐统一异常处理、拦截器用户登录持久化(session内存)分页功能。

m0_66323401的博客 1852

Spring Boot后端开发入门指南:从0到1搭建项目

本指南旨在为初学者提供一个清晰的Spring Boot入门路径,从项目初始化到构建一个功能完整的后端服务。Spring Boot的核心优势项目结构和配置RESTful API开发数据库集成测试和部署基础首先介绍Spring Boot的核心概念然后详细讲解项目搭建步骤接着通过实际代码示例演示关键功能实现最后讨论进阶主题和最佳实践:基于Spring框架的快速应用开发工具,简化配置和部署自动配置:Spring Boot根据类路径和已定义的bean自动配置应用程序起步依赖。

架构师的AI之路,分享AI应用开发架构的学习与实践。 1517

#前后端分离# 头条发布系统

SpringBoot 3.0+ Vue3.0

NVG_Haru的博客 1700

Spring Boot 实战篇(一):实战概述

在本实战项目中,我们将构建一个完整的后端管理系统,包括系统架构设计、功能模块实现以及技术要点解析等内容,以下将详细介绍。

m0_57836225的博客 1538

JAVA:Spring Boot 集成 renren-fast 快速搭建后台

本文介绍了如何使用人人开源(renren.io)快速搭建管理后台系统。文章分为环境准备和项目搭建两大部分:环境需配置JDK1.8+、Maven3.5+、MySQL8.02、Node.js16.8.0等;项目搭建包括后端(renren-fast)和前端(renren-fast-vue)两部分,详细说明了代码下载、数据库配置、依赖安装等步骤。通过该方案,开发者可以基于Spring Boot和Vue快速构建企业级管理后台,实现用户管理、权限控制等功能。文中提供了官方网址和样例代码链接,方便开发者参考使用。

木头 1261

Spring Boot 后台管理系统

构建一个基于Spring Boot后台管理 1. 项目工程结构与模块职责说明,controller、service、mapper等分层结构及职责划分。 2. 统一登录认证与Token鉴权机制实现,说明JWT的生成、校验流程,以及前后端登录状态保持方式。 3. 系统用户、角色与菜单权限设计,说明RBAC权限模型,并展示数据库设计与接口调用逻辑。 4. 统一异常处理与接口返回规范设计,讲解全局异常捕获、统一响应格式的设计原因与实现方式。 5. 接口联调与系统运行效果展示,提供接口测试截图或前端联调说明。

lza_csdn2019的博客 907

【商城实战(18)】后台管理系统基础搭建:从0到1构建电商中枢

本文详细阐述了基于 Element Plus 的后台管理系统搭建过程。先利用 Vue CLI 初始化项目,安装并引入 Element Plus,搭建基础页面布局。接着通过 Vue Router 定义路由规则,创建菜单组件并关联路由,实现导航与权限验证。随后构建用户登录及权限验证机制,包括登录流程、Token 验证和权限控制。最后回顾搭建过程,提出后续可从性能优化、安全加固、用户体验改进及功能完善等方面进行优化,以打造更稳定、高效、安全且功能丰富的后台管理系统。

邓邓子的博客 943

基于spring boot的后台管理系统

Guns基于SpringBoot全面升级,完美整合springmvc + shiro + mybatis-plus + beetl!Guns项目代码简洁,注释丰富,上手容易,同时Guns包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块),可以直接作为一个后台管理系统的脚手架.

从 0 到 1 搭建 Spring Boot 项目:

本文分享了作者从SSM框架转向SpringBoot的开发经验,详细介绍了从零搭建Web项目的完整流程。文章包含五个核心部分:1)项目初始化,使用Spring Initializr快速创建基础架构;2)核心配置,讲解数据库、MyBatis和服务器的简化配置;3)功能实现,展示用户管理模块的完整开发流程;4)测试与部署的注意事项;5)学习总结,强调"约定优于配置"的优势。作者通过实战案例展示了SpringBoot简化开发、提升效率的特点,同时分享了常见问题的解决方案,为新手开发者提供了实用参

2401_82825386的博客 1136

基于springboot的后台管理系统

基于springboot的后台管理系统,包含数据库,可直接运行。

实验:搭建Spring Boot+MyBatis-Plus后台

文章里用到的大部分图片是作业里直接复制过来的,所以有些图片看着很糊,不过也能看得出来要干什么(主要是懒得再截一遍了)。不过还是很抱歉的啦!・_・。

问君能有几多愁. 2218

Maltab GUI课程设计——网络爬虫程序(基金连涨连跌提醒)

Maltab GUI课程设计——网络爬虫程序(基金连涨连跌提醒)

果果爱腰果的博客 848

Ventoy引导自定义菜单配置详解:手把手教你用ventoy_grub.cfg启动硬盘里的Manjaro

本文详细解析了Ventoy引导自定义菜单配置方法,重点介绍如何通过ventoy_grub.cfg文件启动硬盘中的Manjaro系统。从Ventoy与GRUB2的协作原理到具体配置步骤,包括分区布局设计、关键参数解析及常见问题解决方案,帮助用户实现多系统引导的灵活管理。

weixin_28738165的博客 299

Spring Boot 2.0 微服务架构实战:从搭建到部署

在包中,定义一个简单的模型类。例如,创建一个Product@Entity@Id通过本文的讲解,您已经掌握了如何使用 Spring Boot 2.0 构建和部署一个简单的微服务架构,包括项目初始化、配置、数据库连接、服务注册与发现以及微服务的部署等关键步骤。Spring Boot 2.0 在性能和功能上的提升,使得微服务开发变得更加简单高效。在实际开发中,您可以根据需求进一步扩展和优化微服务架构,处理更多复杂的业务逻辑、实现分布式事务、监控与日志管理等。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2071

AI for Science:GNN预测分子性质全流程详解与工业实践

从分子表示到工业落地,一文掌握图神经网络在药物研发与材料设计中的核心实战近年来,的浪潮正深刻变革着传统科研范式。在药物研发与材料设计领域,作为核心环节,已从传统的实验试错转向基于图神经网络(GNN)的智能计算。本文将深入解析GNN预测分子性质的,涵盖数据准备、模型设计、训练优化到工业部署,并揭秘前沿技术与实战案例。

datacanvas2426的博客 1674

Aurora IDE 1.0 深度体验:从环境搭建到 Spring Boot 实战开发

集成开发环境(IDE)是现代软件开发的核心工具,它通过整合代码编辑、编译、调试和项目管理等功能,极大提升了开发效率。其工作原理在于为特定技术栈提供深度支持,包括智能代码补全、语法检查和可视化调试等。在云原生和微服务架构兴起的背景下,一款优秀的IDE能显著降低开发者的环境配置成本,加速从编码到部署的全流程。Aurora IDE作为一款新兴的国产集成开发环境,针对Java和Web开发场景进行了优化,特别在Spring Boot项目创建和Docker工具集成方面提供了开箱即用的体验。对于寻求轻量高效替代方案的开发

weixin_30410119的博客 450

深度理解嵌入(embedding)层

首先从one_hot开始: one_hot的优点:计算方便快捷、表达能力强。 one_hot的缺点:过于稀疏,过于占用资源,尤其是在数据量特别大时;数据之间完全独立。

weixin_44441131的博客 5658

RK3568 解决MIPI屏幕开机只显示uboot logo的问题

之前写过一篇文章介绍了RK3568驱动MIPI屏幕的方法,这次产品迭代,硬件改版,选型的新的屏幕了。所以再次开启调试屏幕的过程。本以为会和上次一样会轻车熟路,事情总是事与愿违,同样的路,遇到新的坑。

fhqlongteng的博客 5425

如何使用Spring Boot从0到1搭建一个Java后台(二)

本篇文章将一步步地来实现一个完整的RESTful接口以及对应的单元测试与集成测试。

国士梅花 1309

TensorFlow2深度学习实战(十四):目标检测算法 YOLOv4 解析

最易上手的【计算机视觉】小白教程!

不积跬步,无以至千里! 7630

从0到1:Spring Boot新手成神之路

本文系统介绍了SpringBoot框架的核心概念与应用实践。首先阐述了SpringBoot作为简化Spring应用开发的框架,其"约定优于配置"的设计理念和自动配置、起步依赖等核心特性。然后详细讲解了从开发环境搭建、项目创建到构建RESTful API的全过程,包括常用注解解读、数据访问(JPA/MyBatis)、异常处理和日志管理等关键开发技术。最后提供了应用部署方案(JAR/WAR)和性能优化建议。文章通过"Hello World"示例展示了SpringBoot的

2401_89739979的博客 1347

ChangeMamba训练调试

此仓库的代码是在 Linux 系统下运行的。我们尚未测试是否能在其他操作系统下运行。 首先需要安装VMama仓库。以下安装顺序取自VMama仓库。克隆该版本库并导航至项目目录: 建议设置 conda 环境并通过 pip 安装依赖项。使用以下命令设置环境: 创建并激活新的 conda 环境 安装依赖项 检测和分割任务的依赖库(在 VMamba 中为可选项) 二、下载预训练权重 另外,请下载VMamba-Tiny, VMamba-Small, and VMamba-Base在ImageNet上的预训练权重并把它

hanfeng5268的博客 575

Supreme小程序自动化抢购终端——源码架构与执行流程全解析

本系统是一套基于开发的桌面端小程序自动化抢购终端。把只有开发者能跑的脚本,包装成普通用户也能操作的桌面工具。参数自动捕获 → 商品多关键词检索 → sku/尺码/库存映射 → 多商品任务队列 → 定时/立即抢购 → 订单创建 → 支付参数拉取 → 本地服务生成支付链接 → 手机微信扫码付款这套 Supreme 抢购终端,表面上看是一个"下单工具"。但从工程角度审视,它已经具备了一个小型桌面自动化系统GUI 层:CustomTkinter 现代化界面,线程安全业务层:多商品队列、定时调度、任务编排。

猫敷雪 202
上一篇: Spring Boot 缓存优化:Redis 实战
下一篇: Spring Boot 参数校验全局处理(JSR380 + 自定义校验)
码客日记
博客等级 码龄6年 149粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值