SpringBoot学习笔记(一)——SpringBoot概要与快速入门
一、Spring Boot概要
没有Spring Boot开发项目时各框架间的集成(如SSM)非常繁琐,兼容性问题处理麻烦,开发效率低。
1.1、Spring Boot 简介
使用 Spring Boot 可以很容易地创建出能直接运行的独立的、生产级别的基于 Spring 的应用。我们对 Spring 平台和第三方类库有自己的考虑,因此您可以从最基本的开始。大多数 Spring Boot 应用只需要很少的 Spring 配置。
您可以使用 Spring Boot 来创建一个可以使用 java -jar
命令来运行或者基于传统的 war 包部署的应用程序。我们还提供了一个用于运行 spring scripts 的命令行工具。
我们的主要目标是:
- 为所有 Spring Boot 开发提供一个更快、更全面的入门体验。
- 坚持自我虽好,但当需求出现偏离,您需要能迅速摆脱出来。
- 提供大量非功能性特性相关项目(例如:内嵌服务器、安全、指标、健康检查、外部配置)。
- 绝对没有代码生成,也不要求 XML 配置。
SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。2014 年 4 月,Spring Boot 1.0.0 发布。Spring的顶级项目之一(https://spring.io)。
1.2、Spring Boot特性
Spring Boot包含以下几个特性:
(1)、默认提供了大部分框架的使用方式,方便进行快速集
(2)、Spring Boot应用可以独立运行,符合微服务的开发理念
(3)、Spring Boot内置WEB容器,无需部署WAR包即可运行
(4)、提供了各种生产就绪型功能,如指标,健康检查和外部配置
(5)、Spring Boot通过网站提供了项目模板,方便项目的初始化
Spring Boot 兼容 Apache Maven 3.2 或更高版本。如果您还没有安装 Maven,可以到 maven.apache.org
您可以跟使用任何标准 Java 库的方式一样使用 Spring Boot。只需要在 classpath 下包含相应的 spring-boot-*.jar
文件即可。Spring Boot 不需要任何专用的工具来集成,因此您可以使用任何 IDE 或者文本编辑器,并且 Spring Boot 应用也没什么特殊之处,因此可以像任何其它 Java 程序一样运行和调试。
虽然您可以复制 Spring Boot 的 jar 文件,但我们通常建议您使用支持依赖管理的构建工具(比如 Maven 或者 Gradle)。
您可以将 Spring Boot 应用部署到任何一个 Servlet 3.0+ 兼容容器中。
虽然您可以在 Java 6 或者 Java 7 上使用 Spring Boot,但我们还是强烈推荐您使用 Java 8+。
1.3、Spring Boot资源
官网:
https://spring.io/projects/spring-boot
官方文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/
官方文档翻译:
https://www.springcloud.cc/spring-boot.html
http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/
https://github.com/DocsHome/springboot
banner生成:
https://www.bootschool.net/ascii
1.4、前置学习内容
视频bilibili:
(1)、Java编程(JavaSE、JavaWeb、反射、泛型、多线程、AJAX)
(4)、Spring MVC(IDEA、Maven、SSM框架集成、多模块)
博客园文章:
1.5、其它说明
(1)、本教程有许多内容来自互联网,如果侵害了您的版权我将迅速处理
(2)、本教程仅针对有一定基础的Java学习或开发者,听课的对象是全栈开发班的学员,仅需使用Spring Boot开发可以提供给前端的后台服务即可,如果您想精通Spring Boot可能不适合您
(3)、教学全程都会录视频,发布在bilibili,请搜索“张果1”
(4)、该教程使用Spring Boot2
(5)、开发工具使用IDEA,Java版本是1.8
二、我的第一个SpringBoot程序
2.1、生成项目模板
2.1.1、在线生成项目模板
为方便我们初始化项目,Spring Boot给我们提供一个项目模板生成网站。
(1). 打开浏览器,访问:https://start.spring.io/
(2). 根据页面提示,选择构建工具,开发语言,项目信息等。
(3). 点击 Generate the project,生成项目模板,生成之后会将压缩包下载到本地。
当然,也可以在线预览项目生成后的代码,只需点击如下按钮即可:
在新窗口中就可以查看生成的代码了:
(4). 使用IDE导入项目,我这里使用IDEA,通过导入Maven项目的方式导入。
选择Maven项目:
多数情况下都直接Next就可以了,导入成功的项目如下所示:
2.1.2、IDE(集成开发工具)生成项目模板
(1)、创建新项目
(2)、选择Spring Initializr
(3)、选择填写项目信息
(4)、添加依赖
(5)项目位置与名称设定
点击完成就创建成功。
2.2、添加控制器
在“com.gdnf.hello”这个包下面添加一个类取名“HelloController”:
添加一个Action,并注解好:
package com.gdnf.hello; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController //注解告诉Spring将结果字符串直接呈现给调用者 public class HelloController { @RequestMapping("/hi") //路径映射 public String hello(){ return "Hello Spring Boot!"; } }
添加成功后:
2.3、启动并运行
点击右上角绿色箭头就可以直接运行了,如要端口被占用(默认8080),可以配置修改,控制台信息如下:
在浏览器中输入:localhost:8081/hi就可以访问到定义到的action,如下所示
2.4、Maven打包
点击IDEA右侧Maven Projects目录,双击Lifecycle中的package命令就可以打包了:
打包时对网络有一定要求,成功时提示如下:
2.5、脱离开发环境运行jar包
target上右键Show in Explorer,在文件夹中显示目录:
创建一个可批处理文件run.bat,内容如下:
java -jar hello2-0.0.1-SNAPSHOT.jar
注意:hello2-0.0.1-SNAPSHOT.jar是包名,需要根据实际打包的名称修改,另外要注意先停止原IDEA的程序运行,防止端口占用
点击运行效果如下:
查看运行效果如下:
三、SpringBoot项目组成与原理分析
3.1、默认目录结构
刚创建好的Spring Boot的项目结构比较简单,只包含三个文件夹。
src/main/java 放置程序开发代码
src/main/resources 放置配置文件
src/test/java 放置测试程序代码
而在其下,包含以下主要文件。
xxxApplication.java 应用的启动类,包含MAIN方法,是程序的入口
application.properties 一个空的配置文件,后续可以配置数据源等信息,比如修改端口号
xxxApplicationTests.java 一个简单的单元测试类
pom.xml mave的配置文件,是管理整个项目开发流程的核心文件
3.2、注解与代码
3.2.1、@RestController和@RequestMapping 注解
Example
类的第一个注解是@RestController
。这被称为 构造型注释。它为阅读代码的人提供了提示,并为Spring提供了该类扮演特定角色的提示。在这种情况下,我们的类是一个web @Controller
,所以Spring在处理传入的Web请求时会考虑它。
@RequestMapping注解
提供“路由”信息。它告诉Spring任何带有/
路径的HTTP请求都应该映射到home
方法。
@RestController
注解告诉Spring将结果字符串直接呈现给调用者。
@RestController的作用等同于@Controller + @ResponseBody
3.2.2、@EnableAutoConfiguration注解
第二个类级别注释是@EnableAutoConfiguration。这个注释告诉Spring Boot根据你添加的jar依赖关系“猜测”你想要如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,因此自动配置假定您正在开发Web应用程序并相应地设置Spring。
Starters和自动配置
自动配置旨在与“Starters”配合使用,但这两个概念并不直接相关。您可以自由选择并在首发之外选择jar依赖项。Spring Boot仍然尽力自动配置您的应用程序。
3.2.3、main方法
我们的应用程序的最后一部分是main
方法。这只是遵循应用程序入口点的Java约定的标准方法。我们的主要方法是通过调用run
来委托Spring Boot的SpringApplication
类。SpringApplication
引导我们的应用程序,从Spring开始,然后启动自动配置的Tomcat Web服务器。我们需要将Example.class
作为参数传递给run
方法,以告诉SpringApplication
哪个是主要的Spring组件。还会传递args
数组以公开任何命令行参数。
3.3、SpringBoot 起步依赖原理分析
3.3.1、spring-boot-starter-parent
在spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本。
在各种starter中,定义了完成该功能需要的坐标合集,其中大部分版本信息来自于父工程。
每个版本的SpringBoot都会对兼容的插件进行版本的控制(版本锁定)。
- 按住Ctrl点击pom.xml中的spring-boot-starter
-
<!--所有的springboot应用都要以该工程为父工程--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.7.RELEASE</version> </parent>
-
- 再按住Ctrl点击pom.xml中parent的spring-boot-starters
-
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.7.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>
-
- 再按住Ctrl点击pom.xml中parent的spring-boot-parent
-
<?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>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.7.RELEASE</version> <packaging>pom</packaging> 。。。 <properties> 。。。 <json-path.version>2.4.0</json-path.version> <jstl.version>1.2</jstl.version> <jtds.version>1.3.1</jtds.version> <junit.version>4.12</junit.version> <junit-jupiter.version>5.5.2</junit-jupiter.version> <kafka.version>2.3.1</kafka.version> <kotlin.version>1.3.72</kotlin.version> <kotlin-coroutines.version>1.3.5</kotlin-coroutines.version> <lettuce.version>5.2.2.RELEASE</lettuce.version> <liquibase.version>3.8.9</liquibase.version> <log4j2.version>2.12.1</log4j2.version> <logback.version>1.2.3</logback.version> <lombok.version>1.18.12</lombok.version> 。。。 <spring-amqp.version>2.2.6.RELEASE</spring-amqp.version> <spring-batch.version>4.2.2.RELEASE</spring-batch.version> <spring-cloud-connectors.version>2.0.7.RELEASE</spring-cloud-connectors.version> <spring-data-releasetrain.version>Moore-SR7</spring-data-releasetrain.version> <spring-framework.version>5.2.6.RELEASE</spring-framework.version> <spring-hateoas.version>1.0.5.RELEASE</spring-hateoas.version> <spring-integration.version>5.2.6.RELEASE</spring-integration.version> <spring-kafka.version>2.3.8.RELEASE</spring-kafka.version> <spring-ldap.version>2.3.3.RELEASE</spring-ldap.version> <spring-restdocs.version>2.0.4.RELEASE</spring-restdocs.version> <spring-retry.version>1.2.5.RELEASE</spring-retry.version> <spring-security.version>5.2.4.RELEASE</spring-security.version> <spring-session-bom.version>Corn-SR2</spring-session-bom.version> <spring-ws.version>3.0.9.RELEASE</spring-ws.version> <sqlite-jdbc.version>3.28.0</sqlite-jdbc.version> <sun-mail.version>${jakarta-mail.version}</sun-mail.version> <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version> <thymeleaf-extras-data-attribute.version>2.0.1</thymeleaf-extras-data-attribute.version> <thymeleaf-extras-java8time.version>3.0.4.RELEASE</thymeleaf-extras-java8time.version> <thymeleaf-extras-springsecurity.version>3.0.4.RELEASE</thymeleaf-extras-springsecurity.version> <thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version> <tomcat.version>9.0.34</tomcat.version> 。。。。 </properties> <dependencyManagement> 版本锁定 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test-autoconfigure</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-actuator</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-actuator-autoconfigure</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure-processor</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-metadata</artifactId> <version>2.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.2.7.RELEASE</version> </dependency> 。。。 </dependencyManagement> 。。。 </project>
从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了,就不需要开发人员自己去版本控制了。所以起步依赖的作用就是进行依赖的传递。
-
3.3.2、spring-boot-starter-web
我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在
版本冲突等问题。
从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的
spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的
坐标就可以进行web开发了,同样体现了依赖传递的作用。
四、Vue+Axios+Spring Boot用户管理
4.1、Vue.js
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与 现代化的工具链以及各种 支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
如果你已经是有经验的前端开发者,想知道 Vue 与其它库/框架有哪些区别,请查看 对比其它框架。
不适合SEO、交互频繁的,如游戏之类交互体验网站
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>天狗商城 - 商品管理</title> <link rel="stylesheet" href="../css/gomall.css" /> </head> <body> <div id="app" class="main"> <h2 class="title"><span>天狗商城 - 商品管理</span></h2> <table border="1" cellspacing="0" cellpadding="0" width="100%" class="tab"> <tr> <th>序号</th> <th>编号</th> <th>名称</th> <th>单价</th> <th>库存</th> <th>小计</th> <th>操作</th> </tr> <!--循环渲染出产品,隔行换色,index为序号从0开始--> <tr v-for="(pdt,index) in products" v-bind:class="{bg:index%2==0}"> <td>{{index+1}}</td> <td>{{pdt.id}}</td> <td>{{pdt.title}}</td> <td>{{pdt.price|currency}}</td> <td> <!--减少产品数量,表达式--> <a v-on:click="pdt.quantity<=0?0:(pdt.quantity-=1)" class="abtn"> - </a> <input v-model="pdt.quantity" class="quantity" v-on:keyup="pdt.quantity=(pdt.quantity<0?0:pdt.quantity)" /> <!--增加产品数量,表达式--> <a v-on:click="pdt.quantity+=1" class="abtn"> + </a> </td> <!--合计,过滤器--> <td>{{pdt.quantity*pdt.price | currency(1)}}</td> <td> <a v-on:click="remove(index,pdt)" class="abtn">删除</a> <a v-on:click="edit(index,pdt)" class="abtn">编辑</a> </td> </tr> <tr> <td colspan="7" align="right" class="total"> {{total|currency}} </td> </tr> </table> <form id="formDetails" name="formDetails"> <fieldset> <legend>商品详细</legend> <p> <label>编号:</label> <input v-model="product.id" :disabled="!isAdd?'disabled':false" required="required" type="number"/> </p> <p> <label>名称:</label> <input v-model="product.title" required="required"/> </p> <p> <label>单价:</label> <input v-model="product.price" type="number" required="required"/> </p> <p> <label>库存:</label> <input v-model="product.quantity" required="required"/> </p> <p> <label>简介:</label> <textarea v-model="product.description" cols="50" rows="3" required="required"></textarea> </p> <p> <button @click="save" class="btn out" type="button">保存</button> <button @click="clear" class="btn out" type="button">清空</button> </p> <p class="poster"> <!--图片加载失败时使用logo--> <img :src="'../img/'+product.id+'.jpg'" onerror="this.src='../img/logo.jpg'"/> </p> </fieldset> </form> </div> <script src="../js/vue/vue.min.js"></script> <script src="../js/jQuery/jquery-1.11.3.min.js"></script> <script type="text/javascript"> //添加货币格式过滤器 Vue.filter('currency', function (v, n) { if (!v) { return '' } return '¥' + parseFloat(v).toFixed(n || 2); }) //实例 var app = new Vue({ el: '#app', data: { //商品列表 products: [], //单个商品对象 product: {}, //是否为添加状态 isAdd: true, }, created() { //当实例创建完成时的钩子 //使用jQuery AJAX加载所有商品信息 $.ajax({ url: 'http://localhost:8089/api/getProductItems', type: 'GET', dataType: 'json', data: {}, success: function (data) { //获取后台数据,重新渲染视图 app.products = data; }, }) }, computed: { //计算属性 //用于计算合计的计算属性 total: function () { var sum = 0 for (var i = 0; i < this.products.length; i++) { sum += this.products[i].price * this.products[i].quantity; } return sum; }, }, methods: { //移除商品事件 remove(i, product) { if (confirm('您确定要移除吗?')) { $.ajax({ url: 'http://localhost:8089/api/RemoveProduct', contentType: 'application/json', type: 'DELETE', //方法类型为DELETE dataType: 'json', data: JSON.stringify(product), success: function (data) { if (data) { //删除成功 //将数据中的产品列表中对应项删除,触发重新渲染界面 app.products.splice(i, 1); } else { alert('移除失败!'); } }, }) } }, //编辑事件 edit(index, pdt) { this.isAdd = false; //绑定当前绑定的商品对象 this.product = pdt; }, //保存事件 save() { //如果是添加 if (this.isAdd) { $.ajax({ url: 'http://localhost:8089/api/AddProduct', contentType: 'application/json', type: 'POST', dataType: 'json', data: JSON.stringify(app.product), success: function (data) { if (data) { //添加成功时在前台集合中添加新商品,重新渲染视图 app.products.push(app.product); alert('添加成功!'); //清空当前项 app.product={}; } else { alert('添加失败!'); } }, }) } else { //更新 $.ajax({ url: 'http://localhost:8089/api/UpdateProduct', contentType: 'application/json', type: 'PUT', //请求方法是PUT dataType: 'json', data: JSON.stringify(app.product), success: function (data) { if (data) { alert('更新成功!'); app.clear(); } else { alert('更新失败!'); } }, }) } }, //清空 clear(){ //将当前操作的产品对象置空 this.product={}; //设置为添加状态 this.isAdd = true; } } }) </script> </body> </html>
4.2、axios
Vue更新到2.0之后宣告不再对vue-resource更新,推荐使用axios,axios是一个用于客户端与服务器通信的组件,axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端javaScript工具。通俗来说可以实现客户端请求服务器端提供的服务获得数据。
源码与帮助:https://github.com/axios/axios
服务器端跨域支持请查看:http://www.cnblogs.com/best/p/6196202.html#_label2
点击查看:学习资料(前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库)
4.3、构建项目
(1)、创建一个名为UserMIS的Spring Boot项目,依赖Spring Web
(2)、创建一个实体类User
package com.gdnf.usermis.entity; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /**用户实体类*/ public class User implements Serializable { public static List<User> users=new ArrayList<>(); static { users.add(new User("zhangsan",18)); users.add(new User("lisi",19)); users.add(new User("wangwu",91)); } public User() { } public User(String username, int age) { this.username = username; this.age = age; } private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", age=" + age + '}'; } }
(3)、创建一个用户服务类,UserService
package com.gdnf.usermis.service; import com.gdnf.usermis.entity.User; import org.springframework.stereotype.Service; import java.util.List; /**用户服务*/ @Service public class UserService { public List<User> getAllUser(){ return User.users; } }
(4)、创建一个控制器,UserController,向前端提供服务
package com.gdnf.usermis.controller; import com.gdnf.usermis.entity.User; import com.gdnf.usermis.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /**用户控制器*/ @RestController public class UserController { @Autowired private UserService userService; /**Spring将使用UserSerive实例注入给userService成员*/ @RequestMapping("/users") public List<User> users(){ return userService.getAllUser(); } }
(5)、测试运行后台服务
(6)、在static文件下创建一个名为index.html的前端页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <h2>用户管理</h2> <table width="100%" border="1"> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> </tr> <tr v-for="(user,index) in users"> <td>{{index+1}}</td> <td>{{user.username}}</td> <td>{{user.age}}</td> </tr> </table> </div> <script src="js/vue.js"></script> <script src="js/axios.min.js"></script> <script> var app = new Vue({ el: "#app", data: { users: [] }, created() { axios.get('/users', { }).then(function (response) { app.users=response.data; }) .catch(function (error) { console.log(error); }) .then(function () { }); } }); </script> </body> </html>
(7)、运行效果
服务器端获得客户端的参数
@RequestMapping("/delete") public int delete(@RequestParam(defaultValue ="0") int id){ return id; }
五、项目实战(见任务指导手册)
4.1、完成小米商城后台管理系统,实现功能如下:
- 后台登录
- 修改密码
- 用户管理(CRUD)
- 管理员管理(CRUD)
- 商品类型管理(CRUD)
- 商品管理(CRUD)
- 订单管理(CRUD)
4.2、完成小米商城PC端动态化,所有数据来自数据库,消费后端向前端提供的服务
- 商品展示
- 登录
- 添加商品到购物车
- 购买
- 订单管理
4.3、完成小米商城移动端动态化,所有数据来自数据库,消费后端向前端提供的服务
- 商品展示
- 登录
- 添加商品到购物车
- 购买
- 订单管理
六、作业
6.1、配置好Spring Boot开发环境。
6.2、完成第一个Spring Boot程序,要求如下:
- 编写后台服务接收前端提交的参数,n1,n2
- 前端使用vue与axios消费后台提供的服务,将响应回前台的数据填写在文档框n3中
6.3、创建小米商城的数据库,参考表结构如下:
1、商品类型表
编号,名称,状态,父节点...
2、商品表
编号,名称,价格,详细,海报,库存,状态,上货日期...
3、用户表
编号,用户名,姓名,密码,手机,邮箱,在线状态...
4、订单表
编号,订单号,下单日期,订单状态,用户编号,总价,地址/地址编号,留言
5、订单商品表
编号,订单号,商品编号,价格
6、收货地址表
编号,用户编号,国家,省,市,县(区),街道/乡镇,地址,邮编,电话,收货人,是否为默认地址...
6.4、拓展作业
使用Vue.js+axios+Spring Boot完成如下示例,实现CURD功能。
6.5、请按顺序看完下面的视频,调试示例
七、视频
https://www.bilibili.com/video/BV1fi4y1S79P?share_source=copy_web
https://space.bilibili.com/87194917/video
作业解答:https://www.bilibili.com/video/BV1Hs411F71x?share_source=copy_web