后端框架搭建完全指南

后端框架搭建完全指南

📖 写给小白的话

你好!欢迎来到Java后端开发的世界。这是一份专门为零基础小白准备的后端框架搭建教程。

你将学到

  • ✅ 如何搭建一个完整的Java后端框架
  • ✅ 各种技术的作用和原理
  • ✅ 如何从零开始配置项目
  • ✅ 如何启动和测试后端服务

不需要担心

  • ❌ 我会用最简单的语言解释
  • ❌ 每一步都有详细的代码示例
  • ❌ 遇到问题有解决方案

🎯 课程目标

学完本教程后,你将能够:

  1. 理解Java后端框架的核心技术
  2. 独立搭建一个完整的后端服务
  3. 配置数据库连接
  4. 开发增删改查接口
  5. 启动和测试后端服务

🛠️ 第一章:开发环境准备

1.1 安装JDK(Java开发工具包)

什么是JDK?

  • JDK = Java Development Kit(Java开发工具包)
  • 包含Java编译器、运行环境、类库等
  • 是开发Java程序的基础

安装步骤

  1. 下载JDK

  2. 安装JDK

    • 双击安装包,按照提示安装
    • 记住安装路径(后面会用到)
  3. 配置环境变量

    Windows系统

    bash 复制代码
    # 1. 新建系统变量
    变量名:JAVA_HOME
    变量值:C:\Program Files\Java\jdk1.8.0_301
    
    # 2. 编辑Path变量,添加:
    %JAVA_HOME%\bin
    %JAVA_HOME%\jre\bin

    Mac/Linux系统

    bash 复制代码
    # 打开终端,编辑配置文件
    vi ~/.bash_profile
    
    # 添加以下内容
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk/Contents/Home
    export PATH=$JAVA_HOME/bin:$PATH
    
    # 使配置生效
    source ~/.bash_profile
  4. 验证安装

    bash 复制代码
    java -version
    # 显示类似信息表示安装成功
    # java version "1.8.0_301"

1.2 安装Maven(项目构建工具)

什么是Maven?

  • Maven是一个项目管理和构建工具
  • 可以自动下载和管理项目依赖
  • 可以编译、测试、打包项目
  • 类似于前端的npm

安装步骤

  1. 下载Maven

  2. 解压Maven

    • 将压缩包解压到一个目录(如:D:\maven\apache-maven-3.6.3)
  3. 配置环境变量

    Windows系统

    bash 复制代码
    # 新建系统变量
    变量名:MAVEN_HOME
    变量值:D:\maven\apache-maven-3.6.3
    
    # 编辑Path变量,添加:
    %MAVEN_HOME%\bin

    Mac/Linux系统

    bash 复制代码
    vi ~/.bash_profile
    
    export MAVEN_HOME=/Users/yourname/maven/apache-maven-3.6.3
    export PATH=$MAVEN_HOME/bin:$PATH
    
    source ~/.bash_profile
  4. 验证安装

    bash 复制代码
    mvn -version
    # 显示类似信息表示安装成功
    # Apache Maven 3.6.3
  5. 配置Maven仓库(重要)

    Maven默认从国外仓库下载依赖,速度很慢。我们需要配置国内镜像(阿里云)。

    找到Maven配置文件

    复制代码
    conf/settings.xml

    修改配置

    xml 复制代码
    <!-- 在<mirrors>标签内添加 -->
    <mirror>
        <id>aliyunmaven</id>
        <mirrorOf>*</mirrorOf>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>

1.3 安装MySQL数据库

什么是MySQL?

  • MySQL是一个关系型数据库管理系统
  • 用于存储和管理数据
  • 是后端开发中最常用的数据库

安装步骤

  1. 下载MySQL

  2. 安装MySQL

    • 双击安装包,按照提示安装
    • 设置root用户密码(记住这个密码!)
  3. 验证安装

    bash 复制代码
    mysql -u root -p
    # 输入密码后进入MySQL命令行
  4. 安装数据库管理工具(可选但推荐)

1.4 安装IDE(集成开发环境)

什么是IDE?

  • IDE = Integrated Development Environment(集成开发环境)
  • 是编写、调试、运行代码的工具
  • 类似于Word,但专门用于写代码

推荐IDE

  1. IntelliJ IDEA(推荐)

  2. Eclipse

安装步骤

  • 下载安装包
  • 双击安装
  • 启动IDE,选择工作空间(项目存放目录)

1.5 安装Git(版本控制工具)

什么是Git?

  • Git是一个版本控制工具
  • 可以追踪代码的变化
  • 可以回滚到历史版本
  • 方便多人协作开发

安装步骤

  1. 下载:https://git-scm.com/

  2. 安装:双击安装包

  3. 验证:

    bash 复制代码
    git --version

📚 第二章:核心技术栈介绍

2.1 Spring Boot(框架核心)

什么是Spring Boot?

  • Spring Boot是一个快速开发框架
  • 可以自动配置Spring应用
  • 简化XML配置
  • 内嵌Tomcat服务器
  • 可以快速创建独立运行的Java应用

为什么用Spring Boot?

java 复制代码
// 传统Spring应用需要大量XML配置
// Spring Boot只需要一个启动类

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Spring Boot的优点

  • ✅ 快速开发
  • ✅ 自动配置
  • ✅ 内嵌服务器
  • ✅ 简化依赖管理
  • ✅ 监控和管理

2.2 MyBatis(数据库访问框架)

什么是MyBatis?

  • MyBatis是一个持久层框架
  • 用于Java对象和数据库表之间的映射
  • 简化SQL操作
  • 支持动态SQL

为什么用MyBatis?

java 复制代码
// 传统JDBC代码
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM user");

// MyBatis代码
List<User> users = userMapper.selectAll();

MyBatis的优点

  • ✅ 简化数据库操作
  • ✅ 支持动态SQL
  • ✅ SQL与代码分离
  • ✅ 结果集自动映射

2.3 Shiro(安全框架)

什么是Shiro?

  • Shiro是一个Java安全框架
  • 提供身份认证、授权、加密、会话管理
  • 保护应用程序的安全性

Shiro的核心功能

复制代码
1. Authentication(身份认证)
   - 验证用户身份(登录)
   - 检查用户名和密码

2. Authorization(授权)
   - 验证用户权限
   - 控制用户能访问哪些资源

3. Cryptography(加密)
   - 加密敏感数据
   - 如密码加密存储

4. Session Management(会话管理)
   - 管理用户会话
   - 记录用户登录状态

为什么用Shiro?

  • ✅ 功能全面
  • ✅ 易于使用
  • ✅ 轻量级
  • ✅ 与Spring Boot集成良好

2.4 MySQL(数据库)

什么是数据库?

  • 数据库是存储数据的仓库
  • 类似于Excel表格,但功能更强大
  • 可以存储大量数据
  • 可以快速查询和修改数据

数据库的基本概念

复制代码
数据库(Database)→ 包含多个表
  ├─ 表(Table)→ 包含多个行
  │   ├─ 行(Row)→ 一条数据记录
  │   ├─ 列(Column)→ 数据字段
  │   └─ 主键(Primary Key)→ 唯一标识
  └─ 关系(Relationship)→ 表之间的关联

为什么用MySQL?

  • ✅ 免费开源
  • ✅ 性能稳定
  • ✅ 社区活跃
  • ✅ 文档丰富

2.5 Maven(项目管理工具)

什么是Maven?

  • Maven是一个项目管理和构建工具
  • 可以自动下载和管理项目依赖
  • 可以编译、测试、打包项目
  • 类似于前端的npm

Maven的核心概念

复制代码
1. POM(Project Object Model)
   - 项目对象模型
   - 用XML描述项目信息
   - 包含依赖、插件、配置等

2. 依赖管理
   - 声明项目需要的库
   - Maven自动下载
   - 管理依赖版本

3. 生命周期
   - clean:清理
   - compile:编译
   - test:测试
   - package:打包
   - install:安装

为什么用Maven?

  • ✅ 自动下载依赖
  • ✅ 管理依赖版本
  • ✅ 统一项目结构
  • ✅ 简化构建过程

2.6 Tomcat(Web服务器)

什么是Tomcat?

  • Tomcat是一个Web服务器
  • 可以运行Java Web应用
  • 处理HTTP请求
  • 返回HTTP响应

Tomcat的作用

复制代码
用户浏览器 → HTTP请求 → Tomcat → Spring Boot应用 → 处理请求 → Tomcat → HTTP响应 → 用户浏览器

为什么用Tomcat?

  • ✅ 免费开源
  • ✅ 轻量级
  • ✅ 性能稳定
  • ✅ 与Spring Boot集成良好

🏗️ 第三章:从零搭建后端框架

3.1 创建Maven项目

步骤1:创建父项目

  1. 打开IntelliJ IDEA
  2. 点击「New Project」
  3. 选择「Maven」
  4. 点击「Next」
  5. 填写项目信息:
    • GroupId: com.yuppie
    • ArtifactId: yuppie
    • Version: 1.0.0
  6. 点击「Finish」

步骤2:创建项目结构

在父项目中创建以下模块:

复制代码
yuppie/                    # 父项目
├── yuppie-admin/          # 启动模块
├── yuppie-framework/      # 框架核心
├── yuppie-system/         # 系统业务
├── yuppie-common/         # 公共模块
└── pom.xml               # 父项目配置

步骤3:配置父项目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>
    
    <!-- 项目信息 -->
    <groupId>com.yuppie</groupId>
    <artifactId>yuppie</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <name>yuppie</name>
    <description>yuppie管理系统</description>
    
    <!-- 模块声明 -->
    <modules>
        <module>yuppie-admin</module>
        <module>yuppie-framework</module>
        <module>yuppie-system</module>
        <module>yuppie-common</module>
    </modules>
    
    <!-- 版本属性 -->
    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.5.15</spring-boot.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <!-- 依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <!-- 子模块依赖 -->
            <dependency>
                <groupId>com.yuppie</groupId>
                <artifactId>yuppie-common</artifactId>
                <version>${project.version}</version>
            </dependency>
            
            <dependency>
                <groupId>com.yuppie</groupId>
                <artifactId>yuppie-framework</artifactId>
                <version>${project.version}</version>
            </dependency>
            
            <dependency>
                <groupId>com.yuppie</groupId>
                <artifactId>yuppie-system</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <!-- 全局依赖 -->
    <dependencies>
        <!-- Lombok(简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    
    <!-- 构建配置 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
            </plugin>
        </plugins>
    </build>
</project>

3.2 创建公共模块(yuppie-common)

步骤1:创建模块

  1. 右键父项目 → New → Module
  2. 选择Maven
  3. 填写ArtifactId: yuppie-common
  4. 点击Finish

步骤2:配置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">
    
    <parent>
        <groupId>com.yuppie</groupId>
        <artifactId>yuppie</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yuppie-common</artifactId>
    <name>yuppie-common</name>
    <description>公共模块</description>
    
    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Spring Boot Validation(参数验证) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        
        <!-- FastJSON(JSON处理) -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        
        <!-- Apache Commons Lang(工具类) -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>
</project>

步骤3:创建基础类

1. 响应结果类

创建文件:src/main/java/com/yuppie/common/core/domain/AjaxResult.java

java 复制代码
package com.yuppie.common.core.domain;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * 响应结果类
 */
public class AjaxResult extends JSONObject {
    
    private static final long serialVersionUID = 1L;
    
    /** 状态码 */
    public static final String CODE_TAG = "code";
    
    /** 返回内容 */
    public static final String MSG_TAG = "msg";
    
    /** 数据对象 */
    public static final String DATA_TAG = "data";
    
    /**
     * 初始化一个新创建的AjaxResult对象
     */
    public AjaxResult() {
    }
    
    /**
     * 初始化一个新创建的AjaxResult对象
     * 
     * @param code 状态码
     * @param msg  返回内容
     */
    public AjaxResult(int code, String msg) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }
    
    /**
     * 初始化一个新创建的AjaxResult对象
     * 
     * @param code 状态码
     * @param msg  返回内容
     * @param data 数据对象
     */
    public AjaxResult(int code, String msg, Object data) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (data != null) {
            super.put(DATA_TAG, data);
        }
    }
    
    /**
     * 返回成功消息
     * 
     * @return 成功消息
     */
    public static AjaxResult success() {
        return AjaxResult.success("操作成功");
    }
    
    /**
     * 返回成功数据
     * 
     * @return 成功消息
     */
    public static AjaxResult success(Object data) {
        return AjaxResult.success("操作成功", data);
    }
    
    /**
     * 返回成功消息
     * 
     * @param msg 返回内容
     * @return 成功消息
     */
    public static AjaxResult success(String msg) {
        return AjaxResult.success(msg, null);
    }
    
    /**
     * 返回成功消息
     * 
     * @param msg  返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static AjaxResult success(String msg, Object data) {
        return new AjaxResult(200, msg, data);
    }
    
    /**
     * 返回错误消息
     * 
     * @return 错误消息
     */
    public static AjaxResult error() {
        return AjaxResult.error("操作失败");
    }
    
    /**
     * 返回错误消息
     * 
     * @param msg 返回内容
     * @return 错误消息
     */
    public static AjaxResult error(String msg) {
        return AjaxResult.error(msg, null);
    }
    
    /**
     * 返回错误消息
     * 
     * @param msg  返回内容
     * @param data 数据对象
     * @return 错误消息
     */
    public static AjaxResult error(String msg, Object data) {
        return new AjaxResult(500, msg, data);
    }
    
    /**
     * 返回错误消息
     * 
     * @param code 状态码
     * @param msg  返回内容
     * @return 错误消息
     */
    public static AjaxResult error(int code, String msg) {
        return new AjaxResult(code, msg, null);
    }
}

2. 分页对象类

创建文件:src/main/java/com/yuppie/common/core/domain/PageQuery.java

java 复制代码
package com.yuppie.common.core.domain;

import lombok.Data;

/**
 * 分页查询对象
 */
@Data
public class PageQuery {
    
    /** 当前页号 */
    private Integer pageNum = 1;
    
    /** 每页记录数 */
    private Integer pageSize = 10;
    
    /** 排序字段 */
    private String orderByColumn;
    
    /** 排序方式 */
    private String isAsc = "asc";
}

3. 基础实体类

作用:基础实体类,用于封装数据实体,包含通用的字段(如创建者、创建时间、更新者、更新时间等字段。

创建文件:src/main/java/com/yuppie/common/core/domain/BaseEntity.java

java 复制代码
package com.yuppie.common.core.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 基础实体类
 */
@Data
public class BaseEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /** 搜索值 */
    private String searchValue;
    
    /** 创建者 */
    private String createBy;
    
    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    
    /** 更新者 */
    private String updateBy;
    
    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    
    /** 备注 */
    private String remark;
    
    /** 请求参数 */
    private Map<String, Object> params = new HashMap<>();
}

3.3 创建框架核心模块(yuppie-framework)

步骤1:创建模块

  1. 右键父项目 → New → Module
  2. 选择Maven
  3. 填写ArtifactId: yuppie-framework
  4. 点击Finish

步骤2:配置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">
    
    <parent>
        <groupId>com.yuppie</groupId>
        <artifactId>yuppie</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yuppie-framework</artifactId>
    <name>yuppie-framework</name>
    <description>框架核心模块</description>
    
    <dependencies>
        <!-- 公共模块 -->
        <dependency>
            <groupId>com.yuppie</groupId>
            <artifactId>yuppie-common</artifactId>
        </dependency>
        
        <!-- Spring Boot MyBatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        
        <!-- PageHelper(分页插件) -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.7</version>
        </dependency>
        
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        
        <!-- Druid(数据库连接池) -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.16</version>
        </dependency>
    </dependencies>
</project>

步骤3:创建配置类

1. MyBatis配置

创建文件:src/main/java/com/yuppie/framework/config/MyBatisConfig.java

java 复制代码
package com.yuppie.framework.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

/**
 * MyBatis配置类
 */
@Configuration
@MapperScan("com.yuppie.**.mapper")
public class MyBatisConfig {
    
}

2. 分页插件配置

创建文件:src/main/java/com/yuppie/framework/config/PageHelperConfig.java

java 复制代码
package com.yuppie.framework.config;

import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * PageHelper分页插件配置
 */
@Configuration
public class PageHelperConfig {
    
    @Bean
    public PageHelper pageHelper() {
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("offsetAsPageNum", "true");
        properties.setProperty("rowBoundsWithCount", "true");
        properties.setProperty("reasonable", "true");
        properties.setProperty("dialect", "mysql");
        pageHelper.setProperties(properties);
        return pageHelper;
    }
}

3.4 创建系统业务模块(yuppie-system)

步骤1:创建模块

  1. 右键父项目 → New → Module
  2. 选择Maven
  3. 填写ArtifactId: yuppie-system
  4. 点击Finish

步骤2:配置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">
    
    <parent>
        <groupId>com.yuppie</groupId>
        <artifactId>yuppie</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yuppie-system</artifactId>
    <name>yuppie-system</name>
    <description>系统业务模块</description>
    
    <dependencies>
        <!-- 框架核心模块 -->
        <dependency>
            <groupId>com.yuppie</groupId>
            <artifactId>yuppie-framework</artifactId>
        </dependency>
    </dependencies>
</project>

步骤3:创建用户管理功能

1. 创建数据库表

创建文件:src/main/resources/sql/sys_user.sql

sql 复制代码
-- 创建用户表
CREATE TABLE `sys_user` (
    `user_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    `dept_id` BIGINT(20) DEFAULT NULL COMMENT '部门ID',
    `user_name` VARCHAR(50) NOT NULL COMMENT '用户账号',
    `nick_name` VARCHAR(50) DEFAULT NULL COMMENT '用户昵称',
    `email` VARCHAR(100) DEFAULT NULL COMMENT '用户邮箱',
    `phonenumber` VARCHAR(20) DEFAULT NULL COMMENT '手机号码',
    `sex` CHAR(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
    `avatar` VARCHAR(255) DEFAULT NULL COMMENT '头像地址',
    `password` VARCHAR(200) DEFAULT NULL COMMENT '密码',
    `status` CHAR(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
    `del_flag` CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
    `login_ip` VARCHAR(128) DEFAULT NULL COMMENT '最后登录IP',
    `login_date` DATETIME DEFAULT NULL COMMENT '最后登录时间',
    `create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
    `create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
    `update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
    `update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
    `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
    PRIMARY KEY (`user_id`),
    UNIQUE KEY `uk_user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';

-- 插入初始数据
INSERT INTO `sys_user` (`user_name`, `nick_name`, `email`, `phonenumber`, `sex`, `password`, `status`, `create_by`, `create_time`) VALUES
('admin', '管理员', 'admin@yuppie.com', '13800138000', '0', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', 'admin', NOW()),
('test', '测试用户', 'test@yuppie.com', '13800138001', '0', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', 'admin', NOW());

2. 创建实体类

创建文件:src/main/java/com/yuppie/system/domain/SysUser.java

java 复制代码
package com.yuppie.system.domain;

import com.yuppie.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * 用户实体类
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SysUser extends BaseEntity {
    
    private static final long serialVersionUID = 1L;
    
    /** 用户ID */
    private Long userId;
    
    /** 部门ID */
    private Long deptId;
    
    /** 用户账号 */
    @NotBlank(message = "用户账号不能为空")
    @Size(min = 0, max = 50, message = "用户账号长度不能超过50个字符")
    private String userName;
    
    /** 用户昵称 */
    @Size(min = 0, max = 50, message = "用户昵称长度不能超过50个字符")
    private String nickName;
    
    /** 用户邮箱 */
    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 100, message = "邮箱长度不能超过100个字符")
    private String email;
    
    /** 手机号码 */
    @Size(min = 0, max = 20, message = "手机号码长度不能超过20个字符")
    private String phonenumber;
    
    /** 用户性别 */
    private String sex;
    
    /** 头像地址 */
    private String avatar;
    
    /** 密码 */
    private String password;
    
    /** 帐号状态 */
    private String status;
    
    /** 删除标志 */
    private String delFlag;
    
    /** 最后登录IP */
    private String loginIp;
    
    /** 最后登录时间 */
    private java.util.Date loginDate;
}

3. 创建Mapper接口

创建文件:src/main/java/com/yuppie/system/mapper/SysUserMapper.java

java 复制代码
package com.yuppie.system.mapper;

import com.yuppie.system.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 用户Mapper接口
 */
@Mapper
public interface SysUserMapper {
    
    /**
     * 查询用户列表
     * 
     * @param user 用户信息
     * @return 用户列表
     */
    List<SysUser> selectUserList(SysUser user);
    
    /**
     * 根据用户ID查询用户
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    SysUser selectUserById(Long userId);
    
    /**
     * 根据用户名查询用户
     * 
     * @param userName 用户名
     * @return 用户信息
     */
    SysUser selectUserByUserName(String userName);
    
    /**
     * 新增用户
     * 
     * @param user 用户信息
     * @return 结果
     */
    int insertUser(SysUser user);
    
    /**
     * 修改用户
     * 
     * @param user 用户信息
     * @return 结果
     */
    int updateUser(SysUser user);
    
    /**
     * 删除用户
     * 
     * @param userId 用户ID
     * @return 结果
     */
    int deleteUserById(Long userId);
    
    /**
     * 批量删除用户
     * 
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    int deleteUserByIds(Long[] userIds);
    
    /**
     * 检查用户名是否唯一
     * 
     * @param userName 用户名
     * @return 结果
     */
    int checkUserNameUnique(String userName);
    
    /**
     * 检查邮箱是否唯一
     * 
     * @param email 邮箱
     * @return 结果
     */
    SysUser checkEmailUnique(String email);
    
    /**
     * 检查手机号是否唯一
     * 
     * @param phonenumber 手机号
     * @return 结果
     */
    SysUser checkPhoneUnique(String phonenumber);
}

4. 创建Mapper XML

创建文件:src/main/resources/mapper/system/SysUserMapper.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.yuppie.system.mapper.SysUserMapper">
    
    <resultMap type="SysUser" id="SysUserResult">
        <id property="userId" column="user_id" />
        <result property="deptId" column="dept_id" />
        <result property="userName" column="user_name" />
        <result property="nickName" column="nick_name" />
        <result property="email" column="email" />
        <result property="phonenumber" column="phonenumber" />
        <result property="sex" column="sex" />
        <result property="avatar" column="avatar" />
        <result property="password" column="password" />
        <result property="status" column="status" />
        <result property="delFlag" column="del_flag" />
        <result property="loginIp" column="login_ip" />
        <result property="loginDate" column="login_date" />
        <result property="createBy" column="create_by" />
        <result property="createTime" column="create_time" />
        <result property="updateBy" column="update_by" />
        <result property="updateTime" column="update_time" />
        <result property="remark" column="remark" />
    </resultMap>
    
    <sql id="selectUserVo">
        SELECT user_id, dept_id, user_name, nick_name, email, phonenumber, sex, avatar, password, status, del_flag, login_ip, login_date, create_by, create_time, update_by, update_time, remark
        FROM sys_user
    </sql>
    
    <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
        <include refid="selectUserVo" />
        <where>
            <if test="userName != null and userName != ''">
                AND user_name LIKE CONCAT('%', #{userName}, '%')
            </if>
            <if test="phonenumber != null and phonenumber != ''">
                AND phonenumber LIKE CONCAT('%', #{phonenumber}, '%')
            </if>
            <if test="status != null and status != ''">
                AND status = #{status}
            </if>
            <if test="params.beginTime != null and params.beginTime != ''">
                AND DATE_FORMAT(create_time,'%y%m%d') >= DATE_FORMAT(#{params.beginTime},'%y%m%d')
            </if>
            <if test="params.endTime != null and params.endTime != ''">
                AND DATE_FORMAT(create_time,'%y%m%d') <= DATE_FORMAT(#{params.endTime},'%y%m%d')
            </if>
            AND del_flag = '0'
        </where>
    </select>
    
    <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
        <include refid="selectUserVo" />
        WHERE user_id = #{userId}
    </select>
    
    <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
        <include refid="selectUserVo" />
        WHERE user_name = #{userName}
    </select>
    
    <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
        INSERT INTO sys_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="deptId != null">dept_id,</if>
            <if test="userName != null and userName != ''">user_name,</if>
            <if test="nickName != null and nickName != ''">nick_name,</if>
            <if test="email != null and email != ''">email,</if>
            <if test="phonenumber != null and phonenumber != ''">phonenumber,</if>
            <if test="sex != null and sex != ''">sex,</if>
            <if test="password != null and password != ''">password,</if>
            <if test="status != null and status != ''">status,</if>
            <if test="createBy != null and createBy != ''">create_by,</if>
            create_time,
        </trim>
        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
            <if test="deptId != null">#{deptId},</if>
            <if test="userName != null and userName != ''">#{userName},</if>
            <if test="nickName != null and nickName != ''">#{nickName},</if>
            <if test="email != null and email != ''">#{email},</if>
            <if test="phonenumber != null and phonenumber != ''">#{phonenumber},</if>
            <if test="sex != null and sex != ''">#{sex},</if>
            <if test="password != null and password != ''">#{password},</if>
            <if test="status != null and status != ''">#{status},</if>
            <if test="createBy != null and createBy != ''">#{createBy},</if>
            NOW(),
        </trim>
    </insert>
    
    <update id="updateUser" parameterType="SysUser">
        UPDATE sys_user
        <set>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
            <if test="email != null and email != ''">email = #{email},</if>
            <if test="phonenumber != null and phonenumber != ''">phonenumber = #{phonenumber},</if>
            <if test="sex != null and sex != ''">sex = #{sex},</if>
            <if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
            <if test="password != null and password != ''">password = #{password},</if>
            <if test="status != null and status != ''">status = #{status},</if>
            <if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
            <if test="loginDate != null">login_date = #{loginDate},</if>
            <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
            update_time = NOW()
        </set>
        WHERE user_id = #{userId}
    </update>
    
    <delete id="deleteUserById" parameterType="Long">
        DELETE FROM sys_user WHERE user_id = #{userId}
    </delete>
    
    <delete id="deleteUserByIds" parameterType="Long">
        DELETE FROM sys_user WHERE user_id IN
        <foreach item="userId" collection="array" open="(" separator="," close=")">
            #{userId}
        </foreach>
    </delete>
    
    <select id="checkUserNameUnique" parameterType="String" resultType="int">
        SELECT COUNT(*) FROM sys_user WHERE user_name = #{userName}
    </select>
    
    <select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
        <include refid="selectUserVo" />
        WHERE email = #{email}
    </select>
    
    <select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
        <include refid="selectUserVo" />
        WHERE phonenumber = #{phonenumber}
    </select>
</mapper>

5. 创建Service接口

创建文件:src/main/java/com/yuppie/system/service/ISysUserService.java

java 复制代码
package com.yuppie.system.service;

import com.yuppie.system.domain.SysUser;

import java.util.List;

/**
 * 用户服务接口
 */
public interface ISysUserService {
    
    /**
     * 查询用户列表
     * 
     * @param user 用户信息
     * @return 用户列表
     */
    List<SysUser> selectUserList(SysUser user);
    
    /**
     * 根据用户ID查询用户
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    SysUser selectUserById(Long userId);
    
    /**
     * 根据用户名查询用户
     * 
     * @param userName 用户名
     * @return 用户信息
     */
    SysUser selectUserByUserName(String userName);
    
    /**
     * 新增用户
     * 
     * @param user 用户信息
     * @return 结果
     */
    int insertUser(SysUser user);
    
    /**
     * 修改用户
     * 
     * @param user 用户信息
     * @return 结果
     */
    int updateUser(SysUser user);
    
    /**
     * 删除用户
     * 
     * @param userId 用户ID
     * @return 结果
     */
    int deleteUserById(Long userId);
    
    /**
     * 批量删除用户
     * 
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    int deleteUserByIds(Long[] userIds);
    
    /**
     * 检查用户名是否唯一
     * 
     * @param user 用户信息
     * @return 结果
     */
    boolean checkUserNameUnique(SysUser user);
    
    /**
     * 检查邮箱是否唯一
     * 
     * @param user 用户信息
     * @return 结果
     */
    boolean checkEmailUnique(SysUser user);
    
    /**
     * 检查手机号是否唯一
     * 
     * @param user 用户信息
     * @return 结果
     */
    boolean checkPhoneUnique(SysUser user);
}

6. 创建Service实现类

创建文件:src/main/java/com/yuppie/system/service/impl/SysUserServiceImpl.java

java 复制代码
package com.yuppie.system.service.impl;

import com.yuppie.system.domain.SysUser;
import com.yuppie.system.mapper.SysUserMapper;
import com.yuppie.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 用户服务实现类
 */
@Service
public class SysUserServiceImpl implements ISysUserService {
    
    @Autowired
    private SysUserMapper userMapper;
    
    @Override
    public List<SysUser> selectUserList(SysUser user) {
        return userMapper.selectUserList(user);
    }
    
    @Override
    public SysUser selectUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }
    
    @Override
    public SysUser selectUserByUserName(String userName) {
        return userMapper.selectUserByUserName(userName);
    }
    
    @Override
    public int insertUser(SysUser user) {
        return userMapper.insertUser(user);
    }
    
    @Override
    public int updateUser(SysUser user) {
        return userMapper.updateUser(user);
    }
    
    @Override
    public int deleteUserById(Long userId) {
        return userMapper.deleteUserById(userId);
    }
    
    @Override
    public int deleteUserByIds(Long[] userIds) {
        return userMapper.deleteUserByIds(userIds);
    }
    
    @Override
    public boolean checkUserNameUnique(SysUser user) {
        Long userId = user.getUserId() == null ? -1L : user.getUserId();
        SysUser info = userMapper.selectUserByUserName(user.getUserName());
        if (info != null && info.getUserId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }
    
    @Override
    public boolean checkEmailUnique(SysUser user) {
        Long userId = user.getUserId() == null ? -1L : user.getUserId();
        SysUser info = userMapper.checkEmailUnique(user.getEmail());
        if (info != null && info.getUserId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }
    
    @Override
    public boolean checkPhoneUnique(SysUser user) {
        Long userId = user.getUserId() == null ? -1L : user.getUserId();
        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        if (info != null && info.getUserId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }
}

7. 创建Controller

创建文件:src/main/java/com/yuppie/system/controller/SysUserController.java

java 复制代码
package com.yuppie.system.controller;

import com.yuppie.common.core.domain.AjaxResult;
import com.yuppie.system.domain.SysUser;
import com.yuppie.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController {
    
    @Autowired
    private ISysUserService userService;
    
    /**
     * 获取用户列表
     */
    @GetMapping("/list")
    public AjaxResult list(SysUser user) {
        List<SysUser> list = userService.selectUserList(user);
        return AjaxResult.success(list);
    }
    
    /**
     * 根据用户ID获取详细信息
     */
    @GetMapping("/{userId}")
    public AjaxResult getInfo(@PathVariable Long userId) {
        return AjaxResult.success(userService.selectUserById(userId));
    }
    
    /**
     * 新增用户
     */
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        if (!userService.checkUserNameUnique(user)) {
            return AjaxResult.error("新增用户" + user.getUserName() + "失败,用户名已存在");
        } else if (!userService.checkPhoneUnique(user)) {
            return AjaxResult.error("新增用户" + user.getUserName() + "失败,手机号码已存在");
        } else if (!userService.checkEmailUnique(user)) {
            return AjaxResult.error("新增用户" + user.getUserName() + "失败,邮箱账号已存在");
        }
        return toAjax(userService.insertUser(user));
    }
    
    /**
     * 修改用户
     */
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysUser user) {
        if (!userService.checkPhoneUnique(user)) {
            return AjaxResult.error("修改用户" + user.getUserName() + "失败,手机号码已存在");
        } else if (!userService.checkEmailUnique(user)) {
            return AjaxResult.error("修改用户" + user.getUserName() + "失败,邮箱账号已存在");
        }
        return toAjax(userService.updateUser(user));
    }
    
    /**
     * 删除用户
     */
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds) {
        return toAjax(userService.deleteUserByIds(userIds));
    }
    
    /**
     * 返回操作结果
     */
    private AjaxResult toAjax(int rows) {
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }
}

3.5 创建启动模块(yuppie-admin)

步骤1:创建模块

  1. 右键父项目 → New → Module
  2. 选择Maven
  3. 填写ArtifactId: yuppie-admin
  4. 点击Finish

步骤2:配置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">
    
    <parent>
        <groupId>com.yuppie</groupId>
        <artifactId>yuppie</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yuppie-admin</artifactId>
    <name>yuppie-admin</name>
    <description>启动模块</description>
    <packaging>jar</packaging>
    
    <dependencies>
        <!-- 系统业务模块 -->
        <dependency>
            <groupId>com.yuppie</groupId>
            <artifactId>yuppie-system</artifactId>
        </dependency>
        
        <!-- Spring Boot DevTools(热部署) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        
        <!-- Spring Boot Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

步骤3:创建配置文件

1. 应用配置

创建文件:src/main/resources/application.yml

yaml 复制代码
# 应用名称
spring:
  application:
    name: yuppie-admin
  
  # 数据源配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yp?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: your_password
    
    # Druid连接池配置
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat,wall,log4j
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        reset-enable: false
        login-username: admin
        login-password: admin
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"

# MyBatis配置
mybatis:
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  type-aliases-package: com.yuppie.**.domain
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# PageHelper配置
pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
  params: count=countSql

# 服务器配置
server:
  port: 8080
  servlet:
    context-path: /

# 日志配置
logging:
  level:
    com.yuppie: debug
    org.springframework: warn

注意 :将 password: your_password 改为你的MySQL密码

2. 日志配置

创建文件:src/main/resources/logback-spring.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
    <property name="log.path" value="logs" />
    
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
    
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
    <!-- 系统模块日志级别控制 -->
    <logger name="com.yuppie" level="debug" />
    
    <!-- 第三方日志级别控制 -->
    <logger name="org.springframework" level="warn" />
    <logger name="org.mybatis" level="warn" />
    
    <!-- 根日志级别 -->
    <root level="info">
        <appender-ref ref="console" />
    </root>
    
    <!-- 开发环境 -->
    <springProfile name="dev">
        <logger name="com.yuppie" level="debug" />
    </springProfile>
    
    <!-- 生产环境 -->
    <springProfile name="prod">
        <root level="info">
            <appender-ref ref="console" />
            <appender-ref ref="file_info" />
            <appender-ref ref="file_error" />
        </root>
    </springProfile>
</configuration>

步骤4:创建启动类

创建文件:src/main/java/com/yuppie/yuppieApplication.java

java 复制代码
package com.yuppie;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 */
@SpringBootApplication
public class yuppieApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(yuppieApplication.class, args);
        System.out.println("\n" +
                "┌─────────────────────────────────────────────────┐\n" +
                "│  yuppie管理系统启动成功!                          │\n" +
                "│  访问地址: http://localhost:8080               │\n" +
                "│  文档地址: http://doc.yuppie.vip                │\n" +
                "└─────────────────────────────────────────────────┘\n");
    }
}

🚀 第四章:启动项目

4.1 准备数据库

步骤1:创建数据库

sql 复制代码
CREATE DATABASE yp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

步骤2:导入表结构

执行 yuppie-system/src/main/resources/sql/sys_user.sql 文件

4.2 启动项目

方法1:在IDE中启动

  1. 打开IntelliJ IDEA
  2. 找到 yuppieApplication.java
  3. 右键点击 → Run 'yuppieApplication'
  4. 等待控制台输出启动信息

方法2:使用Maven命令启动

bash 复制代码
# 进入项目根目录
cd yuppie

# 编译项目
mvn clean compile

# 启动项目
mvn spring-boot:run -pl yuppie-admin

方法3:打包后启动

bash 复制代码
# 打包项目
mvn clean package -DskipTests

# 启动项目
java -jar yuppie-admin/target/yuppie-admin-1.0.0.jar

4.3 验证启动

成功标志

控制台输出类似信息:

复制代码
┌─────────────────────────────────────────────────┐
│  yuppie管理系统启动成功!                          │
│  访问地址: http://localhost:8080               │
│  文档地址: http://doc.yuppie.vip                │
└─────────────────────────────────────────────────┘

测试接口

使用Postman或浏览器访问:

复制代码
GET http://localhost:8080/system/user/list

预期响应

json 复制代码
{
    "code": 200,
    "msg": "操作成功",
    "data": [
        {
            "userId": 1,
            "userName": "admin",
            "nickName": "管理员",
            "email": "admin@yuppie.com",
            "phonenumber": "13800138000",
            "sex": "0",
            "status": "0",
            "createTime": "2024-01-01 10:00:00"
        },
        {
            "userId": 2,
            "userName": "test",
            "nickName": "测试用户",
            "email": "test@yuppie.com",
            "phonenumber": "13800138001",
            "sex": "0",
            "status": "0",
            "createTime": "2024-01-01 10:00:00"
        }
    ]
}

🧪 第五章:测试接口

5.1 使用Postman测试

什么是Postman?

  • Postman是一个API测试工具
  • 可以发送HTTP请求
  • 可以查看响应结果
  • 方便调试接口

下载地址https://www.postman.com/

测试步骤

  1. 获取用户列表

    复制代码
    方法:GET
    URL:http://localhost:8080/system/user/list
    
    响应:
    {
        "code": 200,
        "msg": "操作成功",
        "data": [
            {
                "userId": 1,
                "userName": "admin",
                ...
            }
        ]
    }
  2. 新增用户

    复制代码
    方法:POST
    URL:http://localhost:8080/system/user
    Headers:Content-Type: application/json
    Body:
    {
        "userName": "testuser",
        "nickName": "测试用户",
        "email": "test@example.com",
        "phonenumber": "13900000000",
        "sex": "0",
        "password": "123456",
        "status": "0"
    }
    
    响应:
    {
        "code": 200,
        "msg": "操作成功"
    }
  3. 修改用户

    复制代码
    方法:PUT
    URL:http://localhost:8080/system/user
    Headers:Content-Type: application/json
    Body:
    {
        "userId": 3,
        "userName": "testuser",
        "nickName": "修改后的昵称",
        "email": "newemail@example.com",
        ...
    }
  4. 删除用户

    复制代码
    方法:DELETE
    URL:http://localhost:8080/system/user/3
    
    响应:
    {
        "code": 200,
        "msg": "操作成功"
    }

5.2 常见错误及解决

错误1:数据库连接失败

复制代码
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

解决

  • 检查MySQL服务是否启动
  • 检查数据库地址、端口、用户名、密码
  • 检查防火墙是否阻止连接

错误2:表不存在

复制代码
Table 'yp.sys_user' doesn't exist

解决

  • 检查数据库是否创建
  • 检查SQL脚本是否执行
  • 检查数据库名称是否正确

错误3:端口被占用

复制代码
Address already in use

解决

  • 修改 application.yml 中的端口号

  • 或杀死占用端口的进程:

    bash 复制代码
    # Windows
    netstat -ano | findstr :8080
    taskkill /PID <进程ID> /F
    
    # Mac/Linux
    lsof -i :8080
    kill -9 <进程ID>

错误4:依赖缺失

复制代码
NoClassDefFoundError: org/springframework/boot/SpringApplication

解决

  • 执行 mvn clean install 重新编译
  • 检查Maven仓库是否有相关依赖
  • 检查网络连接,确保依赖能下载

📚 第六章:技术深入讲解

6.1 Spring Boot自动配置原理

什么是自动配置?

Spring Boot会根据项目中的依赖自动配置应用程序。

工作原理

复制代码
1. @SpringBootApplication注解
   ├── @SpringBootConfiguration(配置类)
   ├── @EnableAutoConfiguration(启用自动配置)
   └── @ComponentScan(组件扫描)

2. @EnableAutoConfiguration
   ├── @Import(AutoConfigurationImportSelector.class)
   └── 加载META-INF/spring.factories中的自动配置类

3. 条件注解
   ├── @ConditionalOnClass(类存在时配置)
   ├── @ConditionalOnMissingBean(Bean不存在时配置)
   ├── @ConditionalOnProperty(配置属性存在时配置)
   └── 等...

示例

java 复制代码
// 当项目中有spring-web依赖时,自动配置WebMvc
@Configuration
@ConditionalOnClass(WebMvcConfigurer.class)
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
    // ...
}

6.2 MyBatis工作原理

什么是ORM?

ORM = Object Relational Mapping(对象关系映射)

将Java对象与数据库表进行映射:

复制代码
Java对象 ←→ 数据库表
  属性   ←→   列
  对象   ←→   行

MyBatis工作流程

复制代码
1. 加载配置文件
   ├── mybatis-config.xml(全局配置)
   └── *Mapper.xml(SQL映射)

2. 创建SqlSessionFactory
   ├── 解析配置文件
   └── 创建数据库连接池

3. 创建SqlSession
   ├── 获取数据库连接
   └── 执行SQL语句

4. 执行SQL
   ├── Mapper接口代理
   ├── 动态SQL生成
   ├── 参数映射
   ├── 结果集映射
   └── 返回Java对象

示例

java 复制代码
// Mapper接口
public interface UserMapper {
    User selectUserById(Long id);
}

// Mapper XML
<select id="selectUserById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

// 使用
User user = userMapper.selectUserById(1L);
// MyBatis执行:SELECT * FROM user WHERE id = 1
// 并将结果映射为User对象

6.3 MVC架构模式

什么是MVC?

MVC = Model View Controller(模型-视图-控制器)

各部分职责

复制代码
Model(模型)
├── 数据模型(Entity)
├── 业务逻辑(Service)
└── 数据访问(Mapper)

View(视图)
├── 前端页面
├── 模板引擎
└── 响应数据

Controller(控制器)
├── 接收请求
├── 调用Service
└── 返回响应

工作流程

复制代码
用户浏览器 → HTTP请求 → Controller → Service → Mapper → 数据库
                                      ↓
用户浏览器 ← HTTP响应 ← Controller ← Service ← Mapper ← 数据库

优点

  • ✅ 职责分离,易于维护
  • ✅ 代码复用
  • ✅ 便于测试
  • ✅ 支持多人协作

6.4 RESTful API设计

什么是RESTful?

REST = Representational State Transfer(表述性状态转移)

设计原则

复制代码
1. 资源标识
   └── 使用URL标识资源
   例如:/users, /users/1, /users/1/posts

2. HTTP方法
   ├── GET(获取资源)
   ├── POST(创建资源)
   ├── PUT(更新资源)
   ├── DELETE(删除资源)
   └── PATCH(部分更新)

3. 统一接口
   ├── 使用标准HTTP方法
   ├── 使用JSON格式
   └── 使用标准状态码

4. 无状态
   ├── 每个请求都包含所有必要信息
   └── 服务器不保存客户端状态

示例

复制代码
GET /users              # 获取用户列表
GET /users/1            # 获取用户1的信息
POST /users             # 新增用户
PUT /users/1            # 修改用户1的信息
DELETE /users/1         # 删除用户1
GET /users/1/posts      # 获取用户1的所有帖子

状态码

复制代码
2xx(成功)
├── 200 OK(成功)
├── 201 Created(创建成功)
└── 204 No Content(无内容)

4xx(客户端错误)
├── 400 Bad Request(请求错误)
├── 401 Unauthorized(未授权)
├── 403 Forbidden(禁止访问)
├── 404 Not Found(资源不存在)
└── 409 Conflict(冲突)

5xx(服务器错误)
├── 500 Internal Server Error(服务器内部错误)
└── 503 Service Unavailable(服务不可用)

🎯 第七章:实战项目建议

7.1 扩展功能建议

1. 权限管理

  • 集成Shiro安全框架
  • 实现登录认证
  • 实现权限控制
  • 实现会话管理

2. 日志管理

  • 操作日志记录
  • 登录日志记录
  • 异常日志记录

3. 数据字典

  • 字典类型管理
  • 字典数据管理
  • 前端字典使用

4. 文件上传

  • 单文件上传
  • 多文件上传
  • 文件预览
  • 文件下载

5. 定时任务

  • 任务管理
  • 任务执行
  • 任务日志

7.2 学习路径建议

第一阶段:基础

  • Java基础语法
  • 面向对象编程
  • 集合框架
  • 异常处理
  • IO流

第二阶段:Web开发

  • HTML/CSS/JavaScript
  • HTTP协议
  • Servlet/JSP
  • MVC模式

第三阶段:框架

  • Spring框架
  • Spring Boot
  • MyBatis
  • Maven/Gradle

第四阶段:数据库

  • SQL语法
  • MySQL数据库
  • 数据库设计
  • 索引优化

第五阶段:实战

  • 项目搭建
  • 功能开发
  • 测试调试
  • 部署上线

7.3 推荐学习资源

官方文档

在线教程

书籍推荐

  • 《Java核心技术》
  • 《Spring实战》
  • 《深入浅出MyBatis》
  • 《Head First Servlet & JSP》

视频教程


🎉 第八章:总结与展望

8.1 你已经学会了什么

环境搭建

  • JDK安装和配置
  • Maven安装和配置
  • MySQL安装和配置
  • IDE安装和使用

项目搭建

  • Maven多模块项目
  • Spring Boot应用
  • MyBatis集成
  • 数据库配置

功能开发

  • 实体类设计
  • Mapper层开发
  • Service层开发
  • Controller层开发

接口测试

  • Postman使用
  • 接口调试
  • 错误处理

技术原理

  • Spring Boot自动配置
  • MyBatis工作原理
  • MVC架构
  • RESTful API设计

8.2 下一步学习建议

深入学习

  • Spring框架源码
  • MyBatis源码
  • 设计模式
  • 性能优化

扩展技术

  • Redis缓存
  • RabbitMQ消息队列
  • Elasticsearch搜索引擎
  • Docker容器
  • Kubernetes容器编排

实战项目

  • 开发完整的管理系统
  • 开发电商平台
  • 开发API接口服务
  • 参与开源项目

8.3 鼓励的话

恭喜你完成了本教程!🎉

学习编程是一个持续的过程,遇到困难不要放弃。记住:

  • ✨ 每一个大神都是从小白开始的
  • ✨ 遇到问题是成长的机会
  • ✨ 多写代码,多实践
  • ✨ 阅读优秀的开源代码
  • ✨ 参与技术社区,分享经验

坚持下去,你一定会成为优秀的Java开发工程师!


📞 附录:常见问题

Q1:如何选择Java版本?

建议

  • 学习阶段:Java 8(稳定,资料多)
  • 新项目:Java 11或17(LTS版本)
  • 老项目:根据项目要求

Q2:IDE选择IntelliJ IDEA还是Eclipse?

IntelliJ IDEA

  • 优点:功能强大,智能提示,用户体验好
  • 缺点:收费(社区版免费)

Eclipse

  • 优点:免费开源,插件丰富
  • 缺点:启动慢,界面较旧

建议:初学者推荐IntelliJ IDEA Community版

Q3:如何提高代码质量?

方法

  • 遵循编码规范(阿里巴巴Java开发手册)
  • 使用Lombok简化代码
  • 编写单元测试
  • 使用代码审查工具(SonarQube)
  • 学习设计模式

Q4:如何解决依赖冲突?

方法

  • 使用 mvn dependency:tree 查看依赖树
  • 在pom.xml中排除冲突的依赖
  • 使用 <dependencyManagement> 统一版本
  • 升级到兼容的版本

Q5:如何部署到生产环境?

方法

  • 使用Docker容器部署
  • 使用Jenkins持续集成
  • 使用Nginx反向代理
  • 使用Linux服务器
  • 配置SSL证书

📚 文档信息

文档版本 :v1.0
更新日期 :2026-01-16
维护人员 :yuppie
适用人群 :Java后端开发初学者
项目地址https://gitee.com/yuppie_lucky

反馈与建议

  • 如果发现错误,请及时反馈
  • 如果有更好的建议,欢迎提出
  • 文档会持续更新和完善

感谢阅读!祝你学习愉快! 🎊

相关推荐
roman_日积跬步-终至千里2 小时前
【SQL】SQL 语句的解析顺序:理解查询执行的逻辑
java·数据库·sql
雨中飘荡的记忆2 小时前
Spring Test 从入门到实战
java·后端·spring
TeamDev2 小时前
JxBrowser 8.16.0 版本发布啦!
java·chromium·浏览器自动化·jxbrowser·浏览器控件·枚举清理·跨配置文件复制密码
毕设源码-钟学长2 小时前
【开题答辩全过程】以 高校体育赛事管理系统的设计与实现为例,包含答辩的问题和答案
java
Remember_9932 小时前
【LeetCode精选算法】双指针专题一
java·数据结构·算法·leetcode
未来龙皇小蓝2 小时前
策略模式:Spring Bean策略与枚举 Lambda策略
java·windows·spring boot·spring·策略模式
LiRuiJie2 小时前
从OS层面深入剖析JVM如何实现多线程与同步互斥
java·jvm·os·底层
m0_719084112 小时前
滴滴滴滴滴
java·开发语言
张乔242 小时前
spring boot项目中设置默认的方法实现
java·数据库·spring boot