文章目录
- 一、Java项目结构
- 二、源代码根目录
-
- [2.1 源代码结构](#2.1 源代码结构)
- [2.2 controller控制层](#2.2 controller控制层)
- [2.3 service业务核心层](#2.3 service业务核心层)
- [2.4 mapper数据访问层](#2.4 mapper数据访问层)
- [2.5 entity实体类](#2.5 entity实体类)
- [2.6 DTO请求数据结构](#2.6 DTO请求数据结构)
- [2.7 vo视图对象](#2.7 vo视图对象)
- [2.8 config配置类](#2.8 config配置类)
- [2.9 common公共工具](#2.9 common公共工具)
- [2.10 exception全局异常处理](#2.10 exception全局异常处理)
- [2.11 interceptor拦截器](#2.11 interceptor拦截器)
- [2.12 utils工具类](#2.12 utils工具类)
- [2.13 enums](#2.13 enums)
- 三、resources
-
- [3.1 目录](#3.1 目录)
- [3.2 配置文件](#3.2 配置文件)
- [3.3 静态文件](#3.3 静态文件)
- 四、测试和临时文件
-
- [4.4 测试代码test](#4.4 测试代码test)
- [4.5 target 文件](#4.5 target 文件)
- 五、pom
-
- [5.1 pom.xml](#5.1 pom.xml)
- 六、工作分配
Java项目结构以及功能分析,拆解业务代码各类模块的作用等;
一、Java项目结构
xml
E:\2026\javaProject\demo/
│
├── pom.xml ← 项目配置文件(心脏)
│
├── src/ ← 所有源代码和资源文件
│ ├── main/ ← 主要代码(写代码的地方)
│ │ ├── java/ ← Java 源代码
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── demo/ ← 你的包名
│ │ │ ├── DemoApplication.java ← 启动类(入口)
│ │ │ ├── controller/
│ │ │ │ └── UserController.java
│ │ │ ├── mapper/
│ │ │ │ └── UserMapper.java
│ │ │ └── entity/
│ │ │ └── User.java
│ │ │
│ │ └── resources/ ← 配置文件 & 静态资源
│ │ ├── application.yml ← Spring Boot 核心配置
│ │ ├── static/ ← 静态文件(CSS/JS/图片)
│ │ ├── templates/ ← 模板文件(HTML页面)
│ │ └── META-INF/ ← 元数据(一般不管)
│ │
│ └── test/ ← 测试代码(写单元测试的地方)
│ └── java/
│ └── com/example/demo/
│ └── DemoApplicationTests.java
│
├── target/ ← 编译后的产物(自动生成,不用管)
│ ├── classes/ ← 编译后的 .class 文件和资源
│ ├── generated-sources/ ← 自动生成的代码
│ └── ... (还有其他临时文件)
│
└── .mvn/ ← Maven 包装器(可选,加速用)
└── wrapper/
二、源代码根目录
2.1 源代码结构
xml
src/main/java/com/example/demo/
│
├── DemoApplication.java ← 启动类(唯一入口)
│
├── controller/ ← 控制层(接收 HTTP 请求)
│ ├── UserController.java
│ ├── OrderController.java
│ └── AuthController.java
│
├── service/ ← 业务逻辑层(处理业务)
│ ├── UserService.java ← 接口(定义业务方法)
│ └── impl/
│ └── UserServiceImpl.java ← 实现类(真正写业务逻辑)
│
├── mapper/ ← 数据访问层(操作数据库)
│ ├── UserMapper.java
│ └── OrderMapper.java
│
├── entity/ ← 实体类(映射数据库表)
│ ├── User.java
│ └── Order.java
│
├── dto/ ← 数据传输对象(接口层专用)
│ ├── UserLoginDTO.java
│ └── UserRegisterDTO.java
│
├── vo/ ← 视图对象(返回给前端)
│ ├── UserVO.java
│ └── ResultVO.java ← 统一响应格式
│
├── config/ ← 配置类(自定义配置)
│ ├── MyBatisPlusConfig.java ← 分页插件配置
│ ├── WebConfig.java ← CORS跨域配置
│ └── RedisConfig.java ← Redis配置
│
├── common/ ← 公共工具/常量
│ ├── Result.java ← 统一返回结果封装
│ ├── ResultCode.java ← 状态码枚举
│ └── PageResult.java ← 分页结果封装
│
├── exception/ ← 全局异常处理
│ ├── GlobalExceptionHandler.java ← 统一处理所有异常
│ ├── BusinessException.java ← 自定义业务异常
│ └── ErrorCode.java ← 错误码枚举
│
├── interceptor/ ← 拦截器(请求过滤)
│ ├── LoginInterceptor.java
│ └── LogInterceptor.java
│
├── utils/ ← 工具类
│ ├── JwtUtils.java ← JWT token 工具
│ ├── RedisUtils.java
│ └── DateUtils.java
│
├── annotation/ ← 自定义注解
│ ├── RequireLogin.java
│ └── LogRecord.java
│
└── enums/ ← 枚举类
├── UserStatusEnum.java
└── OrderStatusEnum.java
2.2 controller控制层
- 接受请求,调用server,返回对应数据;
- 业务员逻辑在Service中完成,而不是直接使用Mapper
java
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService; // ← 调用 Service,不是直接调 Mapper
@PostMapping("/login")
public Result<UserVO> login(@RequestBody UserLoginDTO dto) {
UserVO user = userService.login(dto);
return Result.success(user); // ← 统一返回格式
}
}
2.3 service业务核心层
- 增加灵活、复杂的业务处理,增加事务管理;
- 把逻辑从controller中拆出来,让接口更加简洁

java
// 接口:定义方法签名
public interface UserService {
UserVO login(UserLoginDTO dto);
void register(UserRegisterDTO dto);
}
// 实现类:写具体逻辑
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public UserVO login(UserLoginDTO dto) {
// 1. 校验参数
// 2. 查数据库
User user = userMapper.selectByPhone(dto.getPhone());
// 3. 校验密码
// 4. 生成 Token
// 5. 返回 VO
return userVO;
}
}
2.4 mapper数据访问层
- 执行 SQL,操作数据库。
- 继承了BaseMapper的17个方法,所以大部分时候mapper只是一层壳
java
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 自定义 SQL(在 XML 里写)
User selectByPhone(@Param("phone") String phone);
// 用注解写简单 SQL
@Select("SELECT * FROM user WHERE age > #{minAge}")
List<User> selectByAge(@Param("minAge") Integer minAge);
}
- 复杂sql,使用xml;
- @Param("xxx"):给参数起别名,XML 中用 #{xxx} 引用
- 方法名 = XML 中 标签的 id
java
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper extends BaseMapper<User> {
// ✅ 自定义方法1:根据姓名模糊查询(XML 实现)
List<User> selectByNameLike(@Param("name") String name);
// ✅ 自定义方法2:根据年龄范围查询(XML 实现)
List<User> selectByAgeBetween(@Param("minAge") Integer minAge,
@Param("maxAge") Integer maxAge);
// ✅ 自定义方法3:多条件动态查询(XML 实现)
List<User> selectByCondition(@Param("name") String name,
@Param("minAge") Integer minAge,
@Param("maxAge") Integer maxAge);
}
- 创建 XML 映射文件
- 配置识别xml
java
<?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">
<!-- namespace:对应哪个 Mapper 接口,必须写全限定名 -->
<mapper namespace="com.example.demo.mapper.UserMapper">
<!-- ============================================================ -->
<!-- 1. 基础查询:根据姓名模糊查询 -->
<!-- ============================================================ -->
<select id="selectByNameLike" resultType="com.example.demo.entity.User">
SELECT id, name, age, email
FROM user
WHERE name LIKE CONCAT('%', #{name}, '%')
</select>
<!-- ============================================================ -->
<!-- 2. 根据年龄范围查询 -->
<!-- ============================================================ -->
<select id="selectByAgeBetween" resultType="com.example.demo.entity.User">
SELECT id, name, age, email
FROM user
WHERE age BETWEEN #{minAge} AND #{maxAge}
</select>
<!-- ============================================================ -->
<!-- 3. 多条件动态查询(关键:用 <where> 和 <if> 实现动态SQL) -->
<!-- ============================================================ -->
<select id="selectByCondition" resultType="com.example.demo.entity.User">
SELECT id, name, age, email
FROM user
<where>
<!-- 如果 name 不为空,拼接条件 -->
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<!-- 如果 minAge 不为空,拼接条件 -->
<if test="minAge != null">
AND age >= #{minAge}
</if>
<!-- 如果 maxAge 不为空,拼接条件 -->
<if test="maxAge != null">
AND age <= #{maxAge}
</if>
</where>
</select>
</mapper>
在 application.yml 中配置:
java
mybatis-plus:
# 指定 XML 文件位置(重要!)
mapper-locations: classpath*:mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.5 entity实体类
对应数据库表结构(特定表以及主键),定义同样结构的类对象

2.6 DTO请求数据结构
- 在前端传参格式和实体类对象格式不一致时,使用DTO类,用来转化字段
- 这里自动带上了getter、setter
java
package com.example.demo.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@Data
public class UserRegisterDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度2-20位")
private String userName; // 前端传 userName,不是 name
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度6-20位")
private String pwd; // 前端传 pwd,不是 password
@NotBlank(message = "确认密码不能为空")
private String confirmPwd; // 数据库里没有这个字段
private Boolean agreeTerms; // 数据库里没有这个字段
}
简单说进行了数据映射,后面通过Mapper存储到数据库
java
package com.example.demo.service;
import com.example.demo.dto.UserRegisterDTO;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void register(UserRegisterDTO dto) {
// 1. 校验确认密码是否一致
if (!dto.getPwd().equals(dto.getConfirmPwd())) {
throw new RuntimeException("两次密码输入不一致");
}
// 2. 校验手机号是否已被注册
// LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
// wrapper.eq(User::getPhone, dto.getPhone());
// if (userMapper.selectCount(wrapper) > 0) {
// throw new RuntimeException("手机号已注册");
// }
// 3. 把 DTO 转成 Entity(关键步骤)
User user = new User();
user.setName(dto.getUserName()); // userName → name
user.setPhone(dto.getPhone()); // phone → phone
user.setPassword(encryptPassword(dto.getPwd())); // pwd → password(加密)
// confirmPwd 和 agreeTerms 不转,因为数据库没有这两列
// 4. 保存到数据库
userMapper.insert(user);
}
private String encryptPassword(String password) {
// 简单示例:MD5 加密(实际项目用 BCrypt)
return DigestUtils.md5DigestAsHex(password.getBytes());
}
}
2.7 vo视图对象
与DTO一样,当返回值格式和实体类不一致时,用VO规定返回值类型;
2.8 config配置类
写入分页、跨域、redis配置等插件
2.9 common公共工具
统一返回格式
java
@Data
public class Result<T> {
private Integer code; // 状态码:200=成功,500=失败
private String message; // 提示信息
private T data; // 实际数据
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage(message);
return result;
}
}
案例
java
@GetMapping("/{id}")
public Result<User> getById(@PathVariable Long id) {
User user = userService.getById(id);
return Result.success(user); // 封装成 {code:200, message:"success", data:{...}}
}
2.10 exception全局异常处理
统一返回错误json,其他地方只用抛出异常
java
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理业务异常
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusiness(BusinessException e) {
return Result.error(e.getMessage());
}
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<?> handleValidation(MethodArgumentNotValidException e) {
return Result.error("参数校验失败:" + e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
}
2.11 interceptor拦截器
- 登录校验、登录后记录日志
- 执行时间是请求到达接口层Controller 之前或者之后
java
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
if (token == null || !JwtUtils.verify(token)) {
throw new BusinessException("未登录");
}
return true;
}
}
2.12 utils工具类
- 一般验证token、封装redis、文件上传下载
2.13 enums
存放常量枚举值,如状态、类型
三、resources
3.1 目录
包含各种静态文件、模版文件
xml
src/main/resources/
│
├── application.yml ← Spring Boot 核心配置(数据库、端口、日志等)
│
├── application-dev.yml ← 开发环境配置
├── application-prod.yml ← 生产环境配置
├── application-test.yml ← 测试环境配置
│
├── static/ ← 静态资源(前端直接访问)
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── main.js
│ ├── images/
│ │ └── logo.png
│ └── index.html ← 访问 http://localhost:8080/index.html 直接显示
│
├── templates/ ← 后端渲染模板(Thymeleaf)
│ ├── index.html ← Controller 返回 "index" 时加载
│ ├── user/
│ │ └── detail.html
│ └── error/
│ └── 404.html
│
├── mapper/ ← MyBatis XML 映射文件(自定义 SQL)
│ └── UserMapper.xml
│
├── db/ ← 数据库脚本(自己建的,非强制)
│ ├── schema.sql ← 建表语句
│ └── data.sql ← 初始数据
│
└── META-INF/ ← 元数据(一般不用管)
└── spring.factories
3.2 配置文件
数据库、服务器等配置
java
# 服务器配置
server:
port: 8080 # 端口
# Spring 核心配置
spring:
datasource: # 数据库连接
url: jdbc:mysql://localhost:3306/demo_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
thymeleaf: # 模板引擎配置
cache: false # 开发时关闭缓存,改 HTML 立即生效
prefix: classpath:/templates/
suffix: .html
servlet:
multipart: # 文件上传配置
max-file-size: 10MB
max-request-size: 10MB
# MyBatis-Plus 配置
mybatis-plus:
mapper-locations: classpath*:mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 自定义配置(你自己的配置)
app:
jwt:
secret: mySecretKey
expire: 7200 # 2小时
3.3 静态文件
前端渲染,和后端渲染的区别

四、测试和临时文件
4.4 测试代码test
测试代码只写核心代码去测试;
4.5 target 文件
属于临时文件,属于编译后产物;
五、pom
5.1 pom.xml
- 规定了项目基本信息,parent是继承默认的大量配置,配置依赖库、打包构建配置等;
- 管理所有依赖(Spring、MyBatis-Plus、MySQL驱动等)
java
<project>
<!-- 基础信息 -->
<groupId>com.example</groupId> <!-- 你的组织/公司 -->
<artifactId>demo</artifactId> <!-- 项目名称 -->
<version>0.0.1-SNAPSHOT</version> <!-- 版本号 -->
<packaging>jar</packaging> <!-- 打包类型:jar/war -->
<!-- 父项目(继承 Spring Boot 的所有配置) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
</parent>
<!-- 依赖列表(所有第三方库都在这里) -->
<dependencies>
<dependency>...</dependency>
...
</dependencies>
<!-- 构建配置(编译插件等) -->
<build>
<plugins>
<plugin>spring-boot-maven-plugin</plugin>
</plugins>
</build>
</project>
六、工作分配
- 大部分时间在写业务源代码
- application.yml修改是因为数据库环境切换、端口冲突等
