VsCode中开发Java项目

文章目录

  • 一、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 &lt;= #{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修改是因为数据库环境切换、端口冲突等
相关推荐
宠友信息1 小时前
内容社区源码开发实践解析,用Spring Boot打造1:1仿小红书源码平台
java·spring boot·redis·websocket·mysql·spring·uni-app
行百里er2 小时前
加个依赖就生效?一行搞定 Spring Boot Starter 自动装配
java·后端·监控
月华路2 小时前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
AI人工智能+电脑小能手2 小时前
大白话说Java设计模式-34-命令模式(业务实战篇)
java·spring·设计模式·命令模式·异步任务·撤销重做·事务封装
净重21克2 小时前
万字长文!TLS协议升级避坑手册:JDK老项目适配TLS1.2/1.3全流程拆解
java·springboot·java安全
一直C2 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
paopaokaka_luck2 小时前
基于springboot3+vue3的车间生产管理系统(Echarts图形化分析、BI报表)
java·前端·spring boot·学习·echarts
Zane19943 小时前
遍历时删元素为什么报错:modCount 这个"计数器"在背后盯着你
java·后端
电商API_180079052473 小时前
速卖通商品采集API技术文章
java·开发语言·c++·api·跨境电商·商品详情