大家好,我是邵奈一,一個不務正業的程式猿、正兒八經的斜杠青年。
1、世人稱我為:被代碼耽誤的詩人、沒天賦的書法家、五音不全的歌手、專業跑龍套演員、不合格的運動員…
教程目錄
- 00x0 目标
-
- 學習前提
- 教程亮點與難點
-
- 00x1 後端代碼實作
-
- 步驟總覽
- 步驟實作
-
- 1、功能需求分析
- 2、建立資料庫表
- 3、SSM背景代碼實作
- 編寫 `Product.java`
- 編寫 `ProductController.java`
- 編寫 `IProductService.java`
- 編寫 `ProductServiceImpl.java`
- 編寫 `ProductDao.java`
- 編寫 `ProductDao.xml`
- 4、部署Tomcat
- 5、編寫測試用例
-
-
- 00x2 前端代碼實作
-
-
-
- 1、編寫未對接資料庫的前端代碼
- 2、對接查詢商品清單接口
- 3、對接删除商品接口
- 4、對接增加商品接口
- 5、對接修改商品接口
- 6、index.html 完整代碼
-
-
- 0xFF 總結
搭建SSM架構,并且能夠打通前後端,是一個稍微進階但是又非常基礎的教程。
幾乎是零基礎都可以,當然,如果你有學過一些
SSM
和
Vue
基礎内容,那這篇教程更加适合你!
1、搭建通用的SSM架構
2、直接內建CDN的Vue,脫離Node.js使用Vue
3、實作跨域問題,為後端工程師進階全棧提供思路
在開始确定題目的時候,我專門去搜了一下百度,看有沒有類似的文章,發現很多都是
SpringBoot+SSM+Vue
的,好坑,可能小夥伴們就隻是學了
SSM
,能不能快速入門,實作一個增删改查案例呢,答案自然是有的!那讓我來實作一下吧,小夥伴們如果覺得文章寫得不錯,請一鍵三連,甚至掃個二維碼防走丢哈!
因為需求比較簡單,我給張圖大家應該就清楚了:

就是實作增删改查功能,資料表
product
,字段如下:
字段 | 說明 |
---|---|
productName | 商品名稱 |
num | 數量 |
其實,這個需求是來源于部落客的另外一篇部落格:Vue2.x案例之商品增删改查的實作。
隻不過呢,這篇部落格是沒有對接背景的,隻是在前端實作了功能而已。而我們這一次,相當于要把後端打通!期不期待呢?!
把下面的語句丢去執行即可,當然,你用
navicat
直接填也可以:
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`productname` varchar(255),
`num` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8;
INSERT INTO `product` VALUES (1, '鞋子', 100);
INSERT INTO `product` VALUES (2, '襯衫', 200);
注意:我這裡寫的字段名是
productname
,注意大小寫!
步驟比較多,總體思路:
建立Maven項目,我們這裡選擇
空模闆
,本意是為了讓大家一步一步上手(當然,你也可以選擇
webapp
模闆),建構好後,結構如下圖所示:
接着引入SSM依賴,
pom.xml
檔案中的完整依賴如下:
<?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>com.shaonaiyi</groupId>
<artifactId>minimall</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.5.RELEASE</spring.version>
<mybatis.version>3.5.3</mybatis.version>
<jackson.version>2.9.8</jackson.version>
</properties>
<dependencies>
<!--javaWeb元件庫-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Spring核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Spring 應用上下文,進行注解、xml、config加載-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Spring提供的Web上下文,可與Web架構內建,如struts-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Spring IOC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--SpringMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--持久層架構支援-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--AOP支援-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring事務-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- DBCP資料庫連接配接池,SSM架構一般搭配DBCP連接配接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!--MyBatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--MyBatis與Spring的內建-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.0</version>
</dependency>
<!--MySql資料庫-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- Json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
注意的地方:
1、添加了
<packaging>
标簽,我們是打包成
war
包,後面是內建
Tomcat
部署。
添加依賴後,需要建構目錄結構,把相應的包和檔案夾建好:
除此之外,因為選擇的是 Maven
空模闆
項目,是以要設定成 web 項目。先建立
webapp
檔案夾和
WEB-INF
子檔案夾(不清楚可以看下面第二張圖):
建立好後,如圖所示:
接着,就是要建立相應的配置檔案了,小夥伴們可以直接複制粘貼,都是建立在
resources
檔案夾裡。
最終目錄結構,可以參考這張圖:
先拷貝
web.xml
的内容:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
拷貝完會報錯,沒關系,因為還沒有其他檔案,可以不用管它,繼續操作。
接着繼續建立
applicationContext.xml
檔案:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 加載db.properties-->
<context:property-placeholder location="classpath:db.properties" />
<!-- 掃描包,将标注Spring注解的類自動轉化對象,同時完成Bean的注入 -->
<context:component-scan base-package="com.shaonaiyi.minimall"/>
<!-- 啟動對@AspectJ注解的支援 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 配置資料源 ,使用dbcp資料庫連接配接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="20" />
</bean>
<!--配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<!-- mapper掃描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shaonaiyi.minimall.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 事務管理器 對mybatis操作資料庫事務控制,spring使用jdbc的事務控制類 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 傳播行為 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="search*" propagation="SUPPORTS" read-only="true" />
<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- aop -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.shaonaiyi.minimall.service.impl.*.*(..))" />
</aop:config>
</beans>
*.xml
處會報紅,是因為還沒有xml檔案,先不用管。
建立
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 掃描帶注解的包下的類,注冊Bean-->
<context:component-scan base-package="com.shaonaiyi.minimall.controller" />
<!-- 通過注解,把URL映射到Controller上,該标簽預設注冊DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
<mvc:annotation-driven />
</beans>
db.properties
檔案
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/minimall?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
配置檔案都搞定之後,就可以敲代碼了,說實話,用過SpringBoot之後,再用起SSM來,就像說一個字:絕!(真繁瑣…)
編寫代碼的順序一般是這樣的,先把對應的實體類給建好,必須清楚自己到底想幹啥,然後你可以從
Controller
再到
Service
Dao
層,再把
MyBatis
的xml檔案搞定。
但實際上開發要比這個輕松很多,因為一般都會用代碼生成工具,把很多瑣碎的代碼都自動生成了,可以減少很多工作,比如增删改查,隻需要寫少量
Controller
Service
層代碼就可以了。
當然,在實際開發上,還可以繼續再簡化,這個就需要衡量一下你項目的夠不夠大了,如果項目比較小,複制粘貼就可以搞定了,但如果體量比較大,複制粘貼都非常繁瑣。當然,你也可以選擇一些低代碼開發平台,配置一下、跑一下,很多功能都可以實作,具體大家也可以去了解一下:
其實隻有寫教程是最費時間的:
我不忍了,你們在學校學的都是…沒有沒有,隻是太基礎而已。
彩蛋:列印日志實作
為了使用日志,我們在util包裡編寫工具類:
package com.shaonaiyi.minimall.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 23:58
* @Description:
*/
@Component
@Aspect
public class LogPrint {
@Before("execution(* com.shaonaiyi.minimall.service.impl.*.*(..))")
public void methodBegin(JoinPoint joinPoint){
System.out.println("方法開始了");
}
@After("execution(* com.shaonaiyi.minimall.service.impl.*.*(..))")
public void methodEnd(){
System.out.println("方法結束了");
}
@Before("execution(* com.shaonaiyi.minimall.service.impl.*.*(..))")
public void methodBegin1(JoinPoint joinPoint){
System.out.println(joinPoint.getTarget()+" "+joinPoint.getSignature().getName()+"方法開始了");
}
}
增删改查實作
先把實體類建構好,然後的寫代碼順序可以靈活處理,一般是先寫Controller,然後是Service接口,接着是Service實作,然後是Dao層接口,然後是Dao的xml檔案。
簡單來說就是:
entity
=>
XxxController
iXxxService
XxxServiceImpl
XxxDao.java
XxxDao.xml
。
代碼結構請參考下圖,以免有些小夥伴不知道要複制到哪裡:
編寫
Product.java
完整代碼:
package com.shaonaiyi.minimall.entity;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 14:09
* @Description: 商品實體類
*/
public class Product {
private Integer id;
private String productName;
private Integer nums;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getNums() {
return nums;
}
public void setNums(Integer nums) {
this.nums = nums;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Product{");
sb.append("id=").append(id);
sb.append(", productName='").append(productName).append('\'');
sb.append(", nums=").append(nums);
sb.append('}');
return sb.toString();
}
}
注意:資料庫裡商品名稱為
productname
,而實體類裡字段為
productName
,是以後面操作要額外注意,這裡寫不同,友善各位小夥伴有個差別。
ProductController.java
package com.shaonaiyi.minimall.controller;
import com.shaonaiyi.minimall.entity.Product;
import com.shaonaiyi.minimall.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 14:10
* @Description: 商品控制器
*/
@Controller
@RequestMapping("/product")
@CrossOrigin
public class ProductController {
@Autowired
private IProductService iProductService;
@RequestMapping("/list")
@ResponseBody
public List<Product> list() {
return iProductService.list();
}
@RequestMapping(value = "/add",method = RequestMethod.POST)
@ResponseBody
public boolean add(@RequestBody Product product) {
return iProductService.add(product);
}
@RequestMapping(value = "/update",method = RequestMethod.POST)
@ResponseBody
public boolean update(@RequestBody Product product) {
return iProductService.update(product);
}
@RequestMapping(value = "/delete",method = RequestMethod.POST)
@ResponseBody
public boolean delete(@RequestBody Product product) {
return iProductService.delete(product);
}
@RequestMapping(value = "/add-test",method = RequestMethod.POST)
@ResponseBody
public boolean addTest(String productName,Integer nums) {
Product product = new Product();
product.setProductName(productName);
product.setNums(nums);
return iProductService.add(product);
}
@RequestMapping(value = "/delete-test",method = RequestMethod.POST)
@ResponseBody
public boolean deleteTest(int id) {
Product product = new Product();
product.setId(id);
return iProductService.delete(product);
}
}
說明:
1、這裡提供多了兩個接口:
/add-test
、
/delete-test
,友善大家對比學習,兩種方式的接受參數的方式不一樣,
Content-Type
一個是
JSON
,一個是
application/x-www-form-urlencoded
,方式不同,如果不對應上,會報400錯誤,後面有測試用例,可以看後面内容。
2、目前的開發模式一般都是前後端分離開發,是以用
JSON
格式進行互動是最常見的;如果想按照自己的風格,沒有前後端分離的話,可以使用另外一種。初學者比較容易對這裡的内容有誤解,可以查閱相關資料。
IProductService.java
package com.shaonaiyi.minimall.service;
import com.shaonaiyi.minimall.entity.Product;
import java.util.List;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 14:13
* @Description: 商品邏輯接口
*/
public interface IProductService {
List<Product> list();
boolean add(Product product);
boolean update(Product product);
boolean delete(Product product);
}
ProductServiceImpl.java
package com.shaonaiyi.minimall.service.impl;
import com.shaonaiyi.minimall.dao.ProductDao;
import com.shaonaiyi.minimall.entity.Product;
import com.shaonaiyi.minimall.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 14:13
* @Description: 商品邏輯實作
*/
@Service
public class ProductServiceImpl implements IProductService {
@Autowired
private ProductDao productDao;
@Override
public List<Product> list() {
return productDao.list();
}
@Override
public boolean add(Product product) {
int result = productDao.add(product);
return result > 0;
}
@Override
public boolean update(Product product) {
int result = productDao.update(product);
return result > 0;
}
@Override
public boolean delete(Product product) {
int result = productDao.delete(product.getId());
return result > 0;
}
}
ProductDao.java
package com.shaonaiyi.minimall.dao;
import com.shaonaiyi.minimall.entity.Product;
import java.util.List;
/**
* @Auther: [email protected]
* @Date: 2021/8/17 14:18
* @Description: 商品Dao接口
*/
public interface ProductDao {
List<Product> list();
int add(Product product);
int update(Product product);
int delete(int id);
}
ProductDao.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.shaonaiyi.minimall.dao.ProductDao">
<resultMap id="Product" type="com.shaonaiyi.minimall.entity.Product">
<id property="id" column="id"></id>
<result property="productName" column="productName"/>
<result property="nums" column="nums"/>
</resultMap>
<select id="list" resultMap="Product">
select * from product;
</select>
<insert id="add">
insert into product
(productname,nums) values(#{productName},#{nums})
</insert>
<update id="update" parameterType="com.shaonaiyi.minimall.entity.Product">
update product set productname = #{productName},
nums = #{nums} where
id = #{id}
</update>
<delete id="delete" parameterType="int">
delete from product where
id = #{id}
</delete>
</mapper>
注意:到底是寫
productname
還是
productName
,需要厘清。寫好之後,你就可以進行部署運作和測試了。
此步驟比較簡單,可以自行搜一下資料,靈感參考如下:
随便建立個檔案夾,然後建立一個以
http
字尾結尾的檔案,然後寫測試用例即可:
完整的測試用例
### 1、擷取商品清單
GET http://localhost:8080/product/list
### 2、添加商品
POST http://localhost:8080/product/add
Content-Type: application/json
{
"productName": "裙子",
"nums": 150
}
### 3、更新商品
POST http://localhost:8080/product/update
Content-Type: application/json
{
"id":1,
"productName": "皮靴",
"nums": 88
}
### 4、删除商品
POST http://localhost:8080/product/delete
Content-Type: application/json
{
"id":30
}
### 5、添加商品(非JSON方式)
POST http://localhost:8080/product/add-test
Content-Type: application/x-www-form-urlencoded
productName=裙子&nums=150
### 6、删除商品(非JSON方式)
POST http://localhost:8080/product/delete-test
Content-Type: application/x-www-form-urlencoded
id=29
###
寫好測試用例後,左邊會有個運作按鈕,當你的
Tomcat
啟動後,點選綠色小三角按鈕就可以測試了:
下面會有傳回的結果。是以,直接使用
IDEA
進行測試是非常友善的。
測試小技巧:
在
http
檔案中,直接打
gtr
gtrp
ptr
ptrg
可以生成相應的代碼,隻需要寫必要的參數就可以了,自己可以多試試。
參考教程::Vue2.x案例之商品增删改查的實作。
在項目中建立一個
web
檔案夾,然後建立
index.html
檔案,因為代碼比較簡單,是以這裡我使用傳統的開發模式,友善大家入門:
然後就可以把教程中的代碼粘貼進去了,用浏覽器打開
index.html
檔案,其實就可以實作增删改查了,隻不過,頁面都是沒有對接資料庫的,是以重新整理頁面的時候,頁面會恢複原樣,這當然不是我們所想要實作的效果!
目前的商品資料是直接寫死的:
var data = {
products: [
{ id: 1, productName: '襪子', nums: 15},
{ id: 2, productName: '羊毛衫', nums: 20},
{ id: 3, productName: '雪紡衫', nums: 24},
{ id: 4, productName: '高跟鞋', nums: 30}
],
product4Add: { id: 0, productName: '', nums: '0'},
product4Update: { id: 0, productName: '', nums: '0'}
};
并且綁定到了Vue裡面的data:
var vue = new Vue({
el: '#app',
data: data,
...
而我們應該做的是從背景的接口裡擷取到資料。
步驟如下:
我們将會引入
axios
,友善我們請求背景接口,然後寫
list
方法對接背景的接口,查詢到商品清單資訊,你可以給出一個按鈕,然後再執行list方法,但一般清單應該是一加載頁面就去查詢的。是以,我們可以使用Vue中的
mounted
鈎子函數來達到這個目的。
1、引入axios
添加AJAX
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
2、編寫list方法對接背景接口
list() {
let _this = this;
axios.get("http://localhost:8080/product/list").then(
(response) => {
console.log("查詢使用者清單結果:", response);
_this.products = response.data;
}
)
},
3、添加
mounted
鈎子函數
mounted: function () {
let _this = this;
_this.list();
},
4、删除初始化的商品資料
var data = {
products: [],
...
};
目前的完整代碼如下:
<html>
<head>
<meta charset="utf-8"/>
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
...省略部分未變代碼
<script type="text/javascript">
$("#div4Update").hide();
//Model
var data = {
products: [],
product4Add: {id: 0, productName: '', nums: '0'},
product4Update: {id: 0, productName: '', nums: '0'}
};
...省略部分未變代碼
//ViewModel
var vue = new Vue({
el: '#app',
data: data,
mounted: function () {
let _this = this;
_this.list();
},
methods: {
list() {
let _this = this;
axios.get("http://localhost:8080/product/list").then(
(response) => {
console.log("查詢使用者清單結果:", response);
_this.products = response.data;
}
)
},
add: function (event) {
...省略以下未變代碼
代碼比較多,其實沒改幾個地方,放出來代碼,友善大家查閱。
因為我們目前的
id
不是從背景擷取的,是以,你可以把
id
擷取到,然後顯示出來,當然你也可以隐藏掉。隐藏掉操作如下,隻需要加一句話就可以:
<td hidden>{{product.id}}</td>
但是你不擷取,其實也可以,目前我們沒有涉及到,是以不操作上面的步驟。
我們可以先把這段代碼删掉,因為沒有意義了:
var maxId = 5;
for (var i = 0; i < data.products.length; i++) {
if (data.products[i].id > maxId)
maxId = this.products[i].id;1
}
然後将删除方法的代碼修改為:
deleteProduct: function (id) {
let _this = this;
axios.post("http://localhost:8080/product/delete",
{
id: id
}
).then(
(response) => {
if (response.data) {
console.log("删除商品成功!");
_this.list();
}
}
)
},
說明:這裡傳參數,需要傳
JSON
格式,否則無法跟背景接口對應上!(教程後面有完整代碼)
增加接口與删除接口類似,把資料
post
給後端就可以了。
修改
product4Add
,删除初始值:
var data = {
products: [],
product4Add: {},
product4Update: {id: 0, productName: '', nums: '0'}
};
注意:
1、這裡是大括号
{}
,不是中括号
[]
,不然不行!
2、
[]
表示一個數組,
{}
表示一個對象。
add
方法:
add: function (product) {
let _this = this;
axios.post("http://localhost:8080/product/add", product).then(
(response) => {
if (response.data) {
console.log("添加商品成功!");
_this.product4Add = {};
_this.list();
}
}
)
},
跟删除的方法非常相似,隻不過這裡是直接就傳了一個
product
對象而已,與
JSON
格式是比對的。
注意,此時,在點選
增加
按鈕的時候,需要傳一個
product
參數進來,是以需要加上:
<button type="button" v-on:click="add(product4Add)">增加</button>
修改接口與增加接口類似,修改
product4Update
var data = {
products: [],
product4Add: {},
product4Update: {}
};
edit
update
方法
edit: function (product) {
$("#productListTable").hide();
$("#div4Update").show();
let _this = this;
_this.product4Update = product;
},
update: function (product) {
let _this = this;
axios.post("http://localhost:8080/product/update", product).then(
(response) => {
if (response.data) {
console.log("修改商品成功!");
_this.product4Add = {};
$("#productListTable").show();
$("#div4Update").hide();
}
}
)
},
需要傳一個
product
<button type="button" v-on:click="update(product4Update)">修改</button>
說明:雖然更新頁面裡沒有要求輸入
id
,但是當你點選
編輯
按鈕之後,其實是有帶了
id
進去的。
那麼到這裡,然後修改功能就實作了!
<html>
<head>
<meta charset="utf-8"/>
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
<style type="text/css">
td {
border: 1px solid #000;
}
</style>
</head>
<body>
<div id="app">
<table id="productListTable">
<thead>
<tr>
<th>商品名稱</th>
<th>數量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="product in products">
<td>{{product.productName}}</td>
<td>{{product.nums}}</td>
<td>
<a href="#nowhere" @click="edit(product)">編輯</a>
<a href="#nowhere" @click="deleteProduct(product.id)">删除</a>
</td>
</tr>
<tr>
<td colspan="3">
商品名稱:
<input type="text" v-model="product4Add.productName"/>
<br>
數量:
<input type="number" v-model="product4Add.nums"/>
<br>
<button type="button" v-on:click="add(product4Add)">增加</button>
</td>
</tr>
</tbody>
</table>
<div id="div4Update">
商品名稱:
<input type="text" v-model="product4Update.productName"/>
<br>
數量:
<input type="number" v-model="product4Update.nums"/>
<input type="hidden" v-model="product4Update.id"/>
<br>
<button type="button" v-on:click="update(product4Update)">修改</button>
<button type="button" v-on:click="cancel">取消</button>
</div>
</div>
<script type="text/javascript">
$("#div4Update").hide();
//Model
var data = {
products: [],
product4Add: {},
product4Update: {}
};
//ViewModel
var vue = new Vue({
el: '#app',
data: data,
mounted: function () {
let _this = this;
_this.list();
},
methods: {
list() {
let _this = this;
axios.get("http://localhost:8080/product/list").then(
(response) => {
console.log("查詢使用者清單結果:", response);
_this.products = response.data;
}
)
},
add: function (product) {
let _this = this;
axios.post("http://localhost:8080/product/add", product).then(
(response) => {
if (response.data) {
console.log("添加商品成功!");
_this.product4Add = {};
_this.list();
}
}
)
},
deleteProduct: function (id) {
let _this = this;
console.log("id" + id);
axios.post("http://localhost:8080/product/delete",
{
id: id
}
).then(
(response) => {
if (response.data) {
console.log("删除商品成功!");
_this.list();
}
}
)
},
edit: function (product) {
$("#productListTable").hide();
$("#div4Update").show();
let _this = this;
_this.product4Update = product;
},
update: function (product) {
let _this = this;
axios.post("http://localhost:8080/product/update", product).then(
(response) => {
if (response.data) {
console.log("修改商品成功!");
_this.product4Add = {};
$("#productListTable").show();
$("#div4Update").hide();
}
}
)
},
cancel: function () {
//恢複顯示
$("#productListTable").show();
$("#div4Update").hide();
}
}
});
</script>
</body>
</html>
- 這篇文章使用SSM技術實作了後端,并且通過IDEA實作了測試,完全不依賴前端操作。然後随便建了檔案夾就可以把前端給實作了,讓有點前端基礎的人也能輕松實作我們這一次的操作。完全打工前後端分離開發的流程!
- 請關注本部落格,本部落格很多文章都是在原部落格上疊代寫的,提供多種解決方案,有利于小夥伴們不迷路,感謝支援!
- 小夥伴們肯定覺得這個樣式太難看了吧!本部落格裡有一篇配套的調整樣式的文章,請參考:Bootstrap全局css樣式的使用,效果是這樣子滴,希望大家學得開心:
使用SSM+Vue前後端分離開發實作增删改查(超詳細)