从零到一:使用Cursor构建Java+Vue前后端分离项目的完整指南

个人名片
在这里插入图片描述
🎓作者简介:java领域优质创作者
🌐个人主页码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?

  • 专栏导航:

码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀

从零到一:使用Cursor构建Java+Vue前后端分离项目的完整指南

引言

在现代Web开发中,前后端分离架构已成为行业标准。这种架构模式不仅提高了开发效率,还让团队协作更加顺畅。今天,我们将探讨如何利用Cursor这个强大的AI编程助手,从零开始构建一个完整的Java后端和Vue前端分离项目。无论你是刚入门的开发者还是经验丰富的工程师,这篇文章都将为你提供一个清晰的路线图。

一、项目架构设计

1.1 为什么选择前后端分离架构?

前后端分离架构的核心思想是将用户界面(前端)与业务逻辑和数据存储(后端)完全解耦。这种架构的优势在于:

  • 并行开发:前后端团队可以同时工作,提高开发效率
  • 技术栈灵活性:前后端可以独立选择最适合的技术栈
  • 更好的可维护性:清晰的分离让代码更易于理解和维护
  • 可扩展性:可以轻松添加移动端应用或其他客户端
  • 性能优化:前端可以独立部署和优化用户体验

1.2 技术栈选择

后端技术栈:

  • Java 11+:稳定可靠的企业级编程语言
  • Spring Boot 2.7+:快速构建生产级应用的框架
  • Spring Security:安全认证和授权
  • JPA/Hibernate:对象关系映射
  • MySQL 8.0:关系型数据库
  • Maven:项目构建和依赖管理

前端技术栈:

  • Vue 3.0+:渐进式JavaScript框架
  • TypeScript:提供类型安全的JavaScript超集
  • Element Plus:UI组件库
  • Axios:HTTP客户端
  • Vue Router:路由管理
  • Pinia:状态管理
  • Vite:构建工具,提供极速的开发体验

二、给Cursor的完整提示工程

2.1 理解Cursor的能力

Cursor是基于GPT-4的AI编程助手,它能够:

  • 生成完整的代码文件
  • 解释复杂的技术概念
  • 调试和修复代码错误
  • 提供最佳实践建议
  • 协助架构设计决策

2.2 构建完整提示的要素

一个优秀的提示应该包含以下要素:

  1. 明确的目标:清楚说明你要构建什么
  2. 技术栈要求:指定使用的技术和版本
  3. 架构规范:定义项目结构和设计模式
  4. 功能需求:详细描述项目功能
  5. 代码风格:指定编码规范和约定
  6. 特殊要求:任何特定的业务或技术需求

2.3 完整提示示例

以下是我为Cursor设计的完整提示模板:

我正在创建一个Java + Vue的前后端分离项目,需要你帮助我从零开始构建完整的代码结构。

## 项目概述
开发一个任务管理系统,包含用户认证、任务创建、分配、跟踪和报告功能。

## 后端要求 (Java/Spring Boot)
1. 使用Spring Boot 2.7.5和Java 11
2. 采用三层架构:Controller → Service → Repository
3. 实现RESTful API设计
4. 使用JWT进行安全认证
5. 集成Spring Security
6. 使用MySQL数据库,配置连接池
7. 实现全局异常处理
8. 添加请求参数验证
9. 配置CORS支持前端访问
10. 集成Swagger/OpenAPI文档

## 数据库设计
需要以下核心表:
1. users: 用户表 (id, username, email, password, roles, created_at)
2. tasks: 任务表 (id, title, description, status, priority, assignee_id, creator_id, due_date, created_at)
3. comments: 评论表 (id, task_id, user_id, content, created_at)

## 前端要求 (Vue 3 + TypeScript)
1. 使用Vue 3.2+和TypeScript 4.9+
2. 采用Composition API风格
3. 使用Element Plus组件库
4. 实现路由守卫进行权限控制
5. 封装axios请求拦截器
6. 使用Pinia进行状态管理
7. 实现响应式布局
8. 添加表单验证
9. 配置环境变量
10. 遵循ESLint + Prettier代码规范

## 功能模块
1. 用户认证模块(登录、注册、退出)
2. 任务管理模块(增删改查、筛选、排序)
3. 用户管理模块(仅管理员可见)
4. 仪表板(统计图表)
5. 个人中心(个人信息、修改密码)

## 部署要求
1. 后端打包为Docker镜像
2. 前端部署到Nginx
3. 提供docker-compose配置
4. 配置生产环境和开发环境

## 其他要求
1. 代码注释率不低于20%
2. 使用中文注释
3. 遵循阿里巴巴Java开发手册
4. 前端组件和函数使用英文命名
5. 所有API返回统一JSON格式

请从项目结构设计开始,逐步生成所有必要的配置文件、实体类、接口和组件。

三、后端实现详解

3.1 项目结构设计

backend/
├── src/main/java/com/taskmanager/
│   ├── TaskManagerApplication.java
│   ├── config/          # 配置类
│   ├── controller/      # 控制器层
│   ├── service/         # 业务逻辑层
│   ├── repository/      # 数据访问层
│   ├── model/          # 实体类
│   ├── dto/            # 数据传输对象
│   ├── security/       # 安全相关
│   └── exception/      # 异常处理
├── src/main/resources/
│   ├── application.yml
│   ├── application-dev.yml
│   └── application-prod.yml
└── pom.xml

3.2 Spring Boot应用主类

package com.taskmanager;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;

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

3.3 统一响应格式

package com.taskmanager.dto;

import lombok.Data;
import java.io.Serializable;

@Data
public class ApiResponse<T> implements Serializable {
    private Integer code;
    private String message;
    private T data;
    private Long timestamp;

    public ApiResponse() {
        this.timestamp = System.currentTimeMillis();
    }

    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setMessage("操作成功");
        response.setData(data);
        return response;
    }

    public static <T> ApiResponse<T> error(Integer code, String message) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(code);
        response.setMessage(message);
        return response;
    }
}

3.4 用户实体类

package com.taskmanager.model;

import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    private String username;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "user_roles", 
                     joinColumns = @JoinColumn(name = "user_id"))
    @Column(name = "role")
    private Set<String> roles = new HashSet<>();

    @Column(name = "created_at")
    private LocalDateTime createdAt = LocalDateTime.now();

    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
    }
}

3.5 JWT认证配置

package com.taskmanager.security;

import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtTokenUtil {
    
    @Value("${jwt.secret}")
    private String secret;
    
    @Value("${jwt.expiration}")
    private Long expiration;
    
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, userDetails.getUsername());
    }
    
    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
    
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
    
    // 其他工具方法...
}

四、前端实现详解

4.1 Vue项目结构

frontend/
├── src/
│   ├── api/            # API接口
│   ├── assets/         # 静态资源
│   ├── components/     # 组件
│   ├── composables/    # 组合式函数
│   ├── layout/         # 布局组件
│   ├── router/         # 路由配置
│   ├── stores/         # Pinia状态管理
│   ├── types/          # TypeScript类型定义
│   ├── utils/          # 工具函数
│   ├── views/          # 页面组件
│   ├── App.vue
│   └── main.ts
├── public/
├── .env.development    # 开发环境变量
├── .env.production     # 生产环境变量
├── vite.config.ts      # Vite配置
└── package.json

4.2 环境配置

// .env.development
VITE_APP_TITLE = '任务管理系统 - 开发环境'
VITE_APP_BASE_API = 'http://localhost:8080/api'
VITE_APP_UPLOAD_URL = 'http://localhost:8080/api/upload'

// .env.production
VITE_APP_TITLE = '任务管理系统'
VITE_APP_BASE_API = '/api'
VITE_APP_UPLOAD_URL = '/api/upload'

4.3 Axios实例封装

// src/utils/request.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'

const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

// 请求拦截器
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    const userStore = useUserStore()
    if (userStore.token && config.headers) {
      config.headers['Authorization'] = `Bearer ${userStore.token}`
    }
    return config
  },
  (error: any) => {
    Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data
    if (res.code !== 200) {
      ElMessage.error(res.message || '请求失败')
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res.data
    }
  },
  (error: any) => {
    if (error.response?.status === 401) {
      // 处理未授权
      const userStore = useUserStore()
      userStore.logout()
      window.location.href = '/login'
    }
    ElMessage.error(error.message || '请求失败')
    return Promise.reject(error)
  }
)

export default service

4.4 用户状态管理

// src/stores/user.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { login, logout, getUserInfo } from '@/api/user'
import type { LoginForm, UserInfo } from '@/types/user'

export const useUserStore = defineStore('user', () => {
  const token = ref(localStorage.getItem('token') || '')
  const userInfo = ref<UserInfo | null>(null)
  const roles = ref<string[]>([])

  const isLoggedIn = computed(() => !!token.value)
  const isAdmin = computed(() => roles.value.includes('ROLE_ADMIN'))

  const loginAction = async (loginForm: LoginForm) => {
    try {
      const data = await login(loginForm)
      token.value = data.token
      localStorage.setItem('token', data.token)
      await getUserInfoAction()
      return data
    } catch (error) {
      return Promise.reject(error)
    }
  }

  const getUserInfoAction = async () => {
    try {
      const data = await getUserInfo()
      userInfo.value = data.user
      roles.value = data.roles
      return data
    } catch (error) {
      return Promise.reject(error)
    }
  }

  const logoutAction = async () => {
    try {
      await logout()
    } finally {
      resetState()
    }
  }

  const resetState = () => {
    token.value = ''
    userInfo.value = null
    roles.value = []
    localStorage.removeItem('token')
  }

  return {
    token,
    userInfo,
    roles,
    isLoggedIn,
    isAdmin,
    loginAction,
    getUserInfoAction,
    logoutAction
  }
})

五、数据库设计与优化

5.1 数据库表结构

-- 用户表
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_username (username),
    INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 用户角色关联表
CREATE TABLE user_roles (
    user_id BIGINT NOT NULL,
    role VARCHAR(50) NOT NULL,
    PRIMARY KEY (user_id, role),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 任务表
CREATE TABLE tasks (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    description TEXT,
    status ENUM('PENDING', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED') DEFAULT 'PENDING',
    priority ENUM('LOW', 'MEDIUM', 'HIGH', 'URGENT') DEFAULT 'MEDIUM',
    assignee_id BIGINT,
    creator_id BIGINT NOT NULL,
    due_date DATE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL,
    FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE,
    INDEX idx_status (status),
    INDEX idx_priority (priority),
    INDEX idx_assignee (assignee_id),
    INDEX idx_creator (creator_id),
    INDEX idx_due_date (due_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 评论表
CREATE TABLE comments (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    task_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    INDEX idx_task (task_id),
    INDEX idx_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

5.2 数据库优化策略

  1. 索引优化

    • 为经常查询的字段创建索引
    • 使用复合索引优化联合查询
    • 定期分析查询性能,删除不必要的索引
  2. 查询优化

    • 避免SELECT *,只选择需要的字段
    • 使用分页查询大数据集
    • 合理使用JOIN,避免笛卡尔积
  3. 连接池配置

    spring:
      datasource:
        hikari:
          maximum-pool-size: 20
          minimum-idle: 5
          connection-timeout: 30000
          idle-timeout: 600000
          max-lifetime: 1800000
    

六、部署与运维

6.1 Docker容器化部署

# 后端Dockerfile
FROM openjdk:11-jre-slim
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# 前端Dockerfile
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

6.2 Docker Compose配置

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: task-manager-mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: taskmanager
      MYSQL_USER: taskuser
      MYSQL_PASSWORD: taskpass
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - task-network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: task-manager-backend
    environment:
      SPRING_PROFILES_ACTIVE: prod
      DB_HOST: mysql
      DB_PORT: 3306
      DB_NAME: taskmanager
      DB_USERNAME: taskuser
      DB_PASSWORD: taskpass
    ports:
      - "8080:8080"
    depends_on:
      - mysql
    networks:
      - task-network

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: task-manager-frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - task-network

networks:
  task-network:
    driver: bridge

volumes:
  mysql-data:

七、开发流程优化

7.1 Git分支策略

main
├── develop
│   ├── feature/user-auth
│   ├── feature/task-management
│   └── bugfix/login-issue
├── release/v1.0.0
└── hotfix/v1.0.1

7.2 CI/CD流水线

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build Backend
      run: |
        cd backend
        mvn clean package -DskipTests
        
    - name: Build Frontend
      run: |
        cd frontend
        npm install
        npm run build
        
    - name: Deploy to Server
      uses: appleboy/ssh-action@v0.1.5
      with:
        host: ${{ secrets.SERVER_HOST }}
        username: ${{ secrets.SERVER_USER }}
        key: ${{ secrets.SERVER_SSH_KEY }}
        script: |
          cd /var/www/task-manager
          git pull origin main
          docker-compose down
          docker-compose up -d --build

八、使用Cursor的最佳实践

8.1 迭代式开发

不要期望Cursor一次性生成完美的代码。采用迭代方式:

  1. 先生成基础框架
  2. 添加核心功能
  3. 逐步完善细节
  4. 不断优化和重构

8.2 精准提问技巧

  • 具体化需求:不要问"如何实现登录",要问"如何使用Spring Security实现JWT认证"
  • 提供上下文:给出相关代码片段或错误信息
  • 分步骤请求:先要架构设计,再要具体实现
  • 验证和测试:生成的代码一定要手动测试

8.3 代码审查与优化

即使是AI生成的代码也需要人工审查:

  1. 检查安全性问题
  2. 验证业务逻辑正确性
  3. 优化性能瓶颈
  4. 确保代码符合规范

九、项目扩展与优化

9.1 后续功能扩展

  1. 即时通讯:集成WebSocket实现实时通知
  2. 文件管理:支持任务附件上传和预览
  3. 数据导出:导出任务数据为Excel或PDF
  4. 移动端适配:使用响应式设计或开发移动端应用
  5. 第三方集成:集成日历、邮件通知等服务

9.2 性能优化策略

  1. 前端优化

    • 代码分割和懒加载
    • 图片压缩和CDN加速
    • 服务端渲染(SSR)考虑
  2. 后端优化

    • 数据库查询缓存
    • API响应压缩
    • 异步处理耗时操作
  3. 监控和日志

    • 集成Prometheus和Grafana
    • 统一日志收集
    • 错误追踪和报警

结语

通过本文的详细指南,你已经掌握了使用Cursor从零开始构建Java+Vue前后端分离项目的完整流程。从项目架构设计到具体实现,从本地开发到生产部署,每一个环节都有详细的说明和示例代码。

记住,AI助手如Cursor是强大的工具,但它不能替代开发者的思考和决策。最成功的项目往往是人类智慧与AI能力完美结合的产物。随着你对Cursor等工具的熟练使用,你会发现开发效率大幅提升,同时也能保证代码质量。

现在,你已经具备了构建企业级应用的所有知识。开始你的项目吧,在实践中不断学习和完善。开发之旅充满挑战,但也充满乐趣和成就感。祝你在编码的世界里探索出更多精彩!

posted @ 2026-01-14 12:48  性感的猴子  阅读(6)  评论(0)    收藏  举报  来源