Springboot项目开发流程总结

Todo-app开发流程

一、后端配置

1.1创建Springboot工程

打开idea->file->new->project

选择spring Initializer进行配置,java版本选择8,点击next

在这里插入图片描述
Springboot版本选3.0以下版本,勾选Lombok和spring Web这两个依赖一会都会用到

在这里插入图片描述

进入目录src.java.com.zjz._01todo下可以看到已经创建好了启动类Application,点击绿色三角启动Springboot应用

在这里插入图片描述

可以看到在8080端口已经启动服务

在这里插入图片描述

创建一个controller包,编写测试类HelloController

在这里插入图片描述

注意:该类上需要加注解@RestController

@RestController
public class HelloController {
    
    @RequestMapping("/hello")
    public String Hello(){
        return "Hello";
    }
}

打开浏览输入http://localhost:8080/hello就可以看到页面输出Hello,该工程就没有问题

1.2.数据库表创建
CREATE TABLE tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    completed BOOLEAN
);
INSERT INTO mybatis_db.tasks (id, name, completed)
VALUES (1, '吃饭', 0);

我直接使用idea连接本地mysql在数据库mybatis_db中创建tasks表,含有三个字段
在这里插入图片描述

1.3实体类创建

创建实体类Task,在com.zjz._01todo下创建domain包,创建实体类Task,实体类中字段名称和数据类型严格对照tasks表。

在这里插入图片描述

上面三个注解是Lombok提供用来自动添加构造函数和set,get方法,很方便

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Task {
    private Long id;
    private String name;
    private Boolean completed;
}
1.4获取所有任务方法实现
1.4.1编写controller层业务

在controller包下创建TaskController

在这里插入图片描述

@RestController
public class TaskController {

    @Autowired
    private TaskService taskService;

    @GetMapping("/tasks")
    public List<Task> getAllTask(){
        return taskService.getAllTask();
    }
}

我们要求改方法返回所有任务,所有返回类型用List封装,同时注入TaskService,调用个getAllTask方法来实现。

1.4.2编写Service层

首先创建service包,包下创建接口TaskService

在这里插入图片描述

public interface TaskService {

    List<Task> getAllTask();
}

1.4.3下面在service包下创建impl包用于写实现类

impl下创建TaskService的实现类TaskServiceImpl类

在这里插入图片描述

注意:添加注解@Service,重新方法getAllTask() ,注入mapper层taskMapper,调用mapper层方法对数据库进行操作

@Service
public class TaskServiceImpl implements TaskService {
    @Autowired
    private TaskMapper taskMapper;
    @Override
    public List<Task> getAllTask() {
        return taskMapper.getAllTask();
    }
}
1.4.4添加数据库操作所需依赖

在pom.xml文件中添加以下依赖

 <!--mybatis启动器-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
            <scope>runtime</scope>
        </dependency>
1.4.5配置application.yml文件

在resource目录下添加文件application.yml文件

在这里插入图片描述

还有mybatis的配置

在这里插入图片描述

server:
  port: 8080
#整合Mybatis相关配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_db?characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml  #mapper映射文件路径
  type-aliases-package: com.zjz._01todo.domain            #配置哪个包下面的类有默认的别名
1.4.6创建mapper接口

创建mapper包,taskMapper接口

在这里插入图片描述

@Mapper
public interface TaskMapper {
    List<Task> getAllTask();
}
1.4.7编写mapper.xml文件,进行数据库操作

在resource包下创建mapper文件夹,创建TaskMapper.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.zjz._01todo.mapper.TaskMapper">
    <select id="getAllTask" resultType="com.zjz._01todo.domain.Task">
        select * from tasks
    </select>
</mapper>

至此,该功能的后端编码已经完成,测试一下,启动应用,打开浏览器输入http://localhost:8080/tasks

在这里插入图片描述

看到这个说明成功了

1.4.8统一返回对象

在domain包下创建CommonResult类

import lombok.Data;

import java.io.Serializable;

@Data
public class CommonResult<T> implements Serializable {

    private Integer code;
    private String msg;
    private T data;


    public static <T> CommonResult<T> success(T data) {
        CommonResult<T> result = new CommonResult<>();
        result.code = 200;
        result.data = data;
        result.msg = "操作成功";
        return result;
    }

    public static <T> CommonResult<T> error(Integer code, String message) {
        CommonResult<T> result = new CommonResult<>();
        result.code = code;
        result.msg = message;
        return result;
    }
}

修改controller方法

@RestController
public class TaskController {

    @Autowired
    private TaskService taskService;

    @GetMapping("/tasks")
    public CommonResult<?> getAllTask(){
        return CommonResult.success(taskService.getAllTask());
    }
}

重启应用,打开浏览器输入http://localhost:8080/tasks

在这里插入图片描述

成功!

1.5 剩余方法实现
1.5.1 controller层
@RestController
public class TaskController {

    @Autowired
    private TaskService taskService;

    @GetMapping("/tasks")
    public CommonResult<?> getAllTask(){
        return CommonResult.success(taskService.getAllTask());
    }

    //添加任务
    @PostMapping("/tasks") 
    public CommonResult<?> addTask(@RequestBody Task task) {
        return CommonResult.success(taskService.addTask(task));
    }
   //更新任务内容
    @PutMapping("/tasks/{id}")
    public CommonResult<?> updateTask(@PathVariable long id, @RequestBody Task task) {
        task.setId(id);
        return CommonResult.success(taskService.updateTask(task));
    }
    //删除任务
    @DeleteMapping("/tasks/{id}")
    public CommonResult<?> deleteTask(@PathVariable long id) {
        return CommonResult.success(taskService.deleteTask(id));
    }

}
1.5.2 Service层
public interface TaskService {

    List<Task> getAllTask();

    int addTask(Task task);

    int updateTask(Task task);

    int deleteTask(long id);
}
1.5.3 Service实现类
@Service
public class TaskServiceImpl implements TaskService {
    @Autowired
    private TaskMapper taskMapper;
    @Override
    public List<Task> getAllTask() {
        return taskMapper.getAllTask();
    }

    @Override
    public int addTask(Task task) {
       return taskMapper.addTask(task);
    }

    @Override
    public int updateTask(Task task) {
        return taskMapper.updateTask(task);
    }

    @Override
    public int deleteTask(long id) {
        return taskMapper.deleteTask(id);
    }
}
1.5.4 Mapper接口类
@Mapper
public interface TaskMapper {
    List<Task> getAllTask();

    int addTask(Task task);

    int updateTask(Task task);

    int deleteTask(long id);
}

1.5.5 TaskMapper.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.zjz._01todo.mapper.TaskMapper">
    <insert id="addTask" parameterType="com.zjz._01todo.domain.Task">
        INSERT INTO tasks(name,completed) VALUES (#{name},#{completed})
    </insert>
    <update id="updateTask" parameterType="com.zjz._01todo.domain.Task">
        UPDATE tasks SET name=#{name},completed=#{completed} WHERE id=#{id}
    </update>
    <delete id="deleteTask">
        DELETE FROM tasks WHERE id=#{id}
    </delete>

    <select id="getAllTask" resultType="com.zjz._01todo.domain.Task">
        select * from tasks
    </select>
</mapper>
1.6 接口测试

使用软件Apifox对编写的三个接口进行测试

添加任务测试

在这里插入图片描述

查询所有任务,可以看到已添加,id数据库会自动添加

在这里插入图片描述

测试更新任务
在这里插入图片描述

在这里插入图片描述

测试删除任务
在这里插入图片描述
在这里插入图片描述

所有接口测试成功

1.7 补充跨域配置

创建config包,编写如下文件

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*") // 使用allowedOriginPatterns替代allowedOrigins
                .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
                .allowedHeaders("Authorization", "Cache-Control", "Content-Type")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

二、前端配置

2.1 Vue工程创建

至于VUE的安装啥的就不写了

找到要存放工程的文件夹,在文件管理器上输入cmd打开命令控制器

在这里插入图片描述

输入以下命令创建vue工程

vue create todovue

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

开始创建,等一会
在这里插入图片描述

创建完成后有VsCode打开

在这里插入图片描述

终端运行 npm run serve ,单击生成的链接

在这里插入图片描述

2.2前端项目编写

编写App.vue文件

<template>
  <div id="app">
    <div>
      <input type="text" v-model="newTask" placeholder="请输入你的任务名称">
      <button @click="addTask">添加</button>
    </div>

    <div>
      <ul>
        <li v-for="task in tasks" :key="task.id" :class="{ completed: task.completed }">
          <span @click="toggleCompletion(task)">{{ task.name }}</span>
          <button @click="deleteTask(task)">删除</button>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import axios from 'axios';
export default {
  name: 'App',
  data() {
    return {
      newTask: '',
      tasks: [],
    };
  },
  created() {
    this.fetchTasks();
  },
  methods: {
    addTask() {
      if (this.newTask.trim()) {
        this.tasks.push({ id: Date.now(), name: this.newTask.trim(), completed: false });
        this.newTask = '';
      }
    },
    fetchTasks() {
      axios.get('http://localhost:8080/tasks')
        .then(response => {
          if (response.data.code === 200) {
            this.tasks = response.data.data;
          } else {
            console.error(response.data.msg);
          }
        })
        .catch(error => {
          console.error(error);
        });
    },
    deleteTask(task) {
      axios.delete(`http://localhost:8080/tasks/${task.id}`)
        .then(response => {
          if (response.data.code === 200) {
            this.fetchTasks();  // 重新获取任务列表
          } else {
            console.error(response.data.msg);
          }
        })
        .catch(error => {
          console.error(error);
        });
    },
    addTask() {
      if (this.newTask.trim()) {
        const task = { name: this.newTask.trim(), completed: false };
        axios.post('http://localhost:8080/tasks', task)
          .then(response => {
            if (response.data.code === 200) {
              this.newTask = '';
              this.fetchTasks();  // 重新获取任务列表
            } else {
              console.error(response.data.msg);
            }
          })
          .catch(error => {
            console.error(error);
          });
      }
    },
    toggleCompletion(task) {
      task.completed = !task.completed;
      axios.put(`http://localhost:8080/tasks/${task.id}`, task)
        .then(response => {
          if (response.data.code !== 200) {
            console.error(response.data.msg);
          }
        })
        .catch(error => {
          console.error(error);
        });
    }
  },
};
</script>

<style>
body {
  font-family: 'Arial', sans-serif;
  background-color: #F7F9FC;
  padding: 20px;
}

li {
  color: #333;
  cursor: pointer;
  padding: 5px;
  border-radius: 3px;
  transition: background-color 0.3s ease;
}

li:hover {
  background-color: #E4E7ED;
}

.completed {
  color: #A5ACB3;
  text-decoration: line-through;
}

input[type="text"],
button {
  padding: 10px;
  border: 1px solid #D4D9E1;
  border-radius: 4px;
  font-size: 16px;
  margin-right: 10px;
}

button {
  background-color: #4C8EF7;
  color: #FFF;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

button:hover {
  background-color: #357ABD;
}
</style>

注意:如果有报错 ERROR in [eslint],编辑vue.config.js文件,添加如下代码:

lintOnSave: false

在这里插入图片描述

2.3前后端调试

启动Springboot项目,然后在VsCode中断输入 npm run serve,单击链接即可

在这里插入图片描述

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当前课程中博客项目的实战源码是我在 GitHub上开源项目 My-Blog,目前已有 3000 多个 star:本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 个人博客项目功能的讲解,通过本课程的学习,不仅仅让你掌握基本的 Spring Boot 开发能力以及 Spring Boot 项目的大部分开发使用场景,同时帮你提前甄别和处理掉将要遇到的技术难点,认真学完这个课程后,你将会对 Spring Boot 有更加深入而全面的了解,同时你也会得到一个大家都在使用的博客系统源码,你可以根据自己的需求和想法进行改造,也可以直接使用它来作为自己的个人网站,这个课程一定会给你带来巨大的收获。作者寄语本课程录制于 2020 年,代码基于 Spring Boot 2.x 版本。到目前为止,Spring Boot 技术栈也有一些版本升级,比如 Spring Boot 2.7 发版、Spring Boot 3.x 版本发布正式版本。对于这些情况,笔者会在本课程实战项目的开源仓库中创建不同的代码分支,保持实战项目的源码更新,保证读者朋友们不会学习过气的知识点。课程特色 课程内容紧贴 Spring Boot 技术栈,涵盖大部分 Spring Boot 使用场景。开发教程详细完整、文档资源齐全、实验过程循序渐进简单明了。实践项目页面美观且实用,交互效果完美。包含从零搭建项目、以及完整的后台管理系统和博客展示系统两个系统的功能开发流程。技术栈新颖且知识点丰富,学习后可以提升大家对于知识的理解和掌握,对于提升你的市场竞争力有一定的帮助。实战项目预览    

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值