MVC(Model–view–controller)是軟件工程中的一種軟件架構模式,基於此模式把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。目的是經過這樣的設計使程序結構更加簡潔、直觀,下降問題的複雜度。其中各個組成部分的職責爲:
視圖(View) - UI設計人員進行圖形界面設計,負責實現與用戶交互。
控制器(Controller)- 負責獲取請求,處理請求,響應結果。
模型(Model) - 實現業務邏輯,數據邏輯實現。html
咱們在軟件設計時,一般要遵循必定的設計原則。MVC架構模式的設計中,首先基於單一職責原則(SRP-Single responsibility principle)讓每一個對象各司其職,各盡所能。
而後再基於「高內聚,低耦合」的設計思想實現相關層對象之間的交互。這樣能夠更好提升程序的可維護性和可擴展性。
JavaEE技術體系中,MVC設計思想的實現,如圖-14所示:
前端
在上圖中,Servlet充當MVC中的Controller,負責調用model處理業務,負責轉發或重定向某個頁面,在頁面(view)上呈現數據。
模塊封裝了對Servlet的技術的應用,簡化了程序員對請求和響應過程當中數據的處理。Spring MVC 是Spring 框架中基於MVC設計思想實現的一個用於處理Web請求的模塊。其簡易架構分析,以下圖所示:
java
DispatcherServlet :前端控制器, 處理請求的入口。
HandlerMapping:映射器對象, 用於管理url與對應controller的映射關係。
Interceptors:攔截器,實現請求響應的共性處理。
Controller:後端控制器-handler, 負責處理請求的控制邏輯。
ViewResolver:視圖解析器,解析對應的視圖關係(前綴+viewname+後綴)。
備註:假如但願瞭解Spring MVC的詳細處理流程能夠基於斷點調試法進行跟蹤。程序員
編輯pom.xml文件,添加web依賴,Thymeleaf依賴,代碼以下:
Web依賴(提供了Spring MVC核心API,同時會嵌入一個Tomcat服務器)web
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Thymeleaf依賴(提供了一個視圖解析器對象以及數據綁定機制)面試
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
其中: Spring Web Starter 提供Spring MVC 依賴支持,並會自動添加一個tomcat依賴,做爲嵌入式web服務器使用.thymeleaf是一個html模板引擎,提供了與Spring MVC進行整合的API,可做爲MVC架構中Web應用的View層。spring
在application.proper視ties文件中添加圖解析器配置(假如沒有配置也會默認配置,在默認配置中prefix默認值爲classpath:/templates/,後綴默認爲.html)。sql
spring.thymeleaf.prefix=classpath:/templates/pages/ spring.thymeleaf.suffix=.html
說明:要基於配置在src/main/resources目錄下建立templates/pages目錄數據庫
第一步:編寫GoodsController類並將其交給spring管理。這樣的Controller在SpringMVC 規範中一般稱之爲Handler(處理器),咱們在企業中有時也會將此對象理解爲一個後端控制器。apache
package com.cy.pj.goods.controller; @Controller @RequestMapping("/goods/") public class GoodsController { @RequestMapping("doGoodsUI") public String doGoodsUI() { return "goods"; } }
第二步:須要在/templates/pages/目錄下建立goods.html
第三步:啓動服務器(默認項目嵌入的是tomcat),打開瀏覽器進行訪問測試。
http://localhost:8080/goods/doGoodsUI
API應用設計,如圖所示:
package com.cy.pj.goods.pojo; import java.util.Date; /** * pojo對象,基於此對象封裝從數據庫查詢到的數據 * 思考:對象靠什麼存儲數據?屬性 */ public class Goods { private Long id;//id bigint primary key auto_increment private String name;//name varchar(100) not null private String remark;//remark text private Date createdTime;//createdTime datetime public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public Date getCreatedTime() { // System.out.println("==getCreatedTime=="); return createdTime; } public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; } @Override public String toString() { return "Goods{" + "id=" + id + ", name='" + name + '\'' + ", remark='" + remark + '\'' + ", createdTime=" + createdTime + '}'; } }
package com.cy.pj.goods.dao; import com.cy.pj.goods.pojo.Goods; import org.apache.ibatis.annotations.*; import java.util.List; /** * @Mapper是由Mybatis框架中定義的一個描述數據層接口對象的註解(全部的註解起到一個描述性的做用) * 系統底層啓動mybatis框架會基於@Mapper註解的描述,建立其接口的實現類,並將其實現類對象交給spring管理 */ @Mapper public interface GoodsDao { /** * 查找全部商品信息 */ @Select("SELECT id,name,remark,createdTime FROM tb_goods") List<Goods> findObjects(); }
GoodsService
package com.cy.pj.goods.service; import com.cy.pj.goods.pojo.Goods; import java.util.List; public interface GoodsService { List<Goods> findGoods(); }
GoodsServiceImpl
package com.cy.pj.goods.service.impl; import com.cy.pj.goods.dao.GoodsDao; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 商品業務層對象,負責業務邏輯處理 */ @Service public class GoodsServiceImpl implements GoodsService { @Autowired private GoodsDao goodsDao; @Override public List<Goods> findGoods() { Long start=System.currentTimeMillis(); List<Goods> list=goodsDao.findObjects(); long end=System.currentTimeMillis(); System.out.println("query time:"+(end-start)); return list; } }
package com.cy.pj.goods.controller; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/goods/") public class GoodsController { @Autowired private GoodsService goodsService; //http:localhost:8080/goods/doGoodsUI //此訪問路徑會傳遞到DispatcherServlet對象 //DispatcherServlet對象會基於用戶輸入的url找到對應的controller及方法 //DispatcherServlet底層會根據反射技術調用對應的控制層方法 @RequestMapping("doGoodsUI") public String doGoodsUI(Model model) { //獲取業務數據 List<Goods> list = goodsService.findGoods(); //將數據存儲到做用域對象 model.addAttribute("list", list); //將頁面響應到客戶端 return "goods";//view name //將此view返回給前端控制器DispatcherServlet //前端控制器會調用視圖解析器對view進行解析,添加前綴和後綴 //templates/pages/goods.html //最後由DispatcherServlet將頁面響應給客戶端 } }
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table> <thead> <th>id</th> <th>name</th> <th>remark</th> <th>createdTime</th> </thead> <tbody> <tr th:each="g:${list}" > <td th:text="${g.id}"></td> <td th:text="${g.name}"></td> <td th:text="${g.remark}"></td> <td th:text="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td> </tr> </tbody> </table> </body> </html>
啓動服務器:
在網頁中輸入url地址:http://localhost:8080/goods/doGoodsUI
查詢結果以下:
第一步:GoodsDao中定義基於id刪除記錄的方法 deleteById(Integer id);
package com.cy.pj.goods.dao; import com.cy.pj.goods.pojo.Goods; import org.apache.ibatis.annotations.*; import java.util.List; /** * @Mapper是由Mybatis框架中定義的一個描述數據層接口對象的註解(全部的註解起到一個描述性的做用) * 系統底層啓動mybatis框架會基於@Mapper註解的描述,建立其接口的實現類,並將其實現類對象交給spring管理 */ @Mapper public interface GoodsDao { /** * 基於id刪除數據庫中商品信息 * @param id * @return */ @Delete("delete from tb_goods where id=#{id}") int deleteById(Integer id); /** * 查找全部商品信息 * @return */ @Select("SELECT id,name,remark,createdTime FROM tb_goods") List<Goods> findObjects(); }
第二步:GoodsService及實現類中定義deleteById(Integer id)方法用於執行記錄刪除
GoodsService
package com.cy.pj.goods.service; import com.cy.pj.goods.pojo.Goods; import java.util.List; public interface GoodsService { List<Goods> findGoods(); void deleteById(Integer id); }
GoodsServiceImpl
package com.cy.pj.goods.service.impl; import com.cy.pj.goods.dao.GoodsDao; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 商品業務層對象,負責業務邏輯處理 */ @Service public class GoodsServiceImpl implements GoodsService { @Autowired private GoodsDao goodsDao; @Override public List<Goods> findGoods() { Long start=System.currentTimeMillis(); List<Goods> list=goodsDao.findObjects(); long end=System.currentTimeMillis(); System.out.println("query time:"+(end-start)); return list; } @Override public void deleteById(Integer id) { int rows=goodsDao.deleteById(id); } }
package com.cy.pj.goods.controller; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/goods/") public class GoodsController { @Autowired private GoodsService goodsService; //http://localhost:8080/goods/doDeleteById @RequestMapping("doDeleteById") public String doDeleteById(Integer id){ //調用業務層對象執行刪除操做 goodsService.deleteById(id); //思考:刪除之後要作什麼? //在當前業務中咱們能夠重定向到查詢頁面 return "redirect:doGoodsUI"; } //http:localhost:8080/goods/doGoodsUI //此訪問路徑會傳遞到DispatcherServlet對象 //DispatcherServlet對象會基於用戶輸入的url找到對應的controller及方法 //DispatcherServlet底層會根據反射技術調用對應的控制層方法 @RequestMapping("doGoodsUI") public String doGoodsUI(Model model) { //獲取業務數據 List<Goods> list = goodsService.findGoods(); //將數據存儲到做用域對象 model.addAttribute("list", list); //將頁面響應到客戶端 return "goods";//view name //將此view返回給前端控制器DispatcherServlet //前端控制器會調用視圖解析器對view進行解析,添加前綴和後綴 //templates/pages/goods.html //最後由DispatcherServlet將頁面響應給客戶端 } }
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table> <thead> <th>id</th> <th>name</th> <th>remark</th> <th>createdTime</th> </thead> <tbody> <tr th:each="g:${list}" > <td th:text="${g.id}"></td> <td th:text="${g.name}"></td> <td th:text="${g.remark}"></td> <td th:text="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td> <td><a th:href="@{/goods/doDeleteById(id=${g.id})}">delete</a></td> </tr> </tbody> </table> </body> </html>
啓動服務器:
在網頁中輸入url地址:http://localhost:8080/goods/doGoodsUI
點擊delete
package com.cy.pj.goods.dao; import com.cy.pj.goods.pojo.Goods; import org.apache.ibatis.annotations.*; import java.util.List; /** * @Mapper是由Mybatis框架中定義的一個描述數據層接口對象的註解(全部的註解起到一個描述性的做用) * 系統底層啓動mybatis框架會基於@Mapper註解的描述,建立其接口的實現類,並將其實現類對象交給spring管理 */ @Mapper public interface GoodsDao { /** * 基於id刪除數據庫中商品信息 * @param id * @return */ @Delete("delete from tb_goods where id=#{id}") int deleteById(Integer id); /** * 基於id進行批量刪除操做 * @param ids * @return */ //int deleteObjects(@Param("ids")Integer...ids);早期版本須要基於@Param註解 int deleteObjects(Integer...ids);//sql映射中可以使用array,ids參數名來接收方法參數 /** * 查找全部商品信息 * @return */ @Select("SELECT id,name,remark,createdTime FROM tb_goods") List<Goods> findObjects(); @Insert("insert into tb_goods (name,remark,createdTime) values(#{name},#{remark},now())") int insert(Goods entity); }
GoodsService
package com.cy.pj.goods.service; import com.cy.pj.goods.pojo.Goods; import java.util.List; public interface GoodsService { List<Goods> findGoods(); void deleteById(Integer id); int insert(Goods entity); }
GoodsServiceImpl
package com.cy.pj.goods.service.impl; import com.cy.pj.goods.dao.GoodsDao; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 商品業務層對象,負責業務邏輯處理 */ @Service public class GoodsServiceImpl implements GoodsService { @Autowired private GoodsDao goodsDao; @Override public List<Goods> findGoods() { Long start=System.currentTimeMillis(); List<Goods> list=goodsDao.findObjects(); long end=System.currentTimeMillis(); System.out.println("query time:"+(end-start)); return list; } @Override public void deleteById(Integer id) { int rows=goodsDao.deleteById(id); } @Override public int insert(Goods entity) { int rows=goodsDao.insert(entity); return rows; } }
package com.cy.pj.goods.controller; import com.cy.pj.goods.pojo.Goods; import com.cy.pj.goods.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/goods/") public class GoodsController { @Autowired private GoodsService goodsService; //http://localhost:8080/goods/doDeleteById @RequestMapping("doDeleteById") public String doDeleteById(Integer id){ //調用業務層對象執行刪除操做 goodsService.deleteById(id); //思考:刪除之後要作什麼? //在當前業務中咱們能夠重定向到查詢頁面 return "redirect:doGoodsUI"; } @RequestMapping("doSaveGoods") public String doSaveGoods(Goods entity){ goodsService.insert(entity); return "redirect:doGoodsUI"; } //http:localhost:8080/goods/doGoodsUI //此訪問路徑會傳遞到DispatcherServlet對象 //DispatcherServlet對象會基於用戶輸入的url找到對應的controller及方法 //DispatcherServlet底層會根據反射技術調用對應的控制層方法 @RequestMapping("doGoodsUI") public String doGoodsUI(Model model) { //獲取業務數據 List<Goods> list = goodsService.findGoods(); //將數據存儲到做用域對象 model.addAttribute("list", list); //將頁面響應到客戶端 return "goods";//view name //將此view返回給前端控制器DispatcherServlet //前端控制器會調用視圖解析器對view進行解析,添加前綴和後綴 //templates/pages/goods.html //最後由DispatcherServlet將頁面響應給客戶端 } }
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/goods/doSaveGoods" method="post"> <ul> <li>name: <li><input type="text" name="name"> <li>remark: <li><textarea rows="5" cols=""50 name="remark"></textarea> <li><input type="submit" value="save"></li> </ul> </form> <fieldset> <legend>商品列表</legend> <table width="50%"> <table> <thead> <th>id</th> <th>name</th> <th>remark</th> <th>createdTime</th> </thead> <tbody> <tr th:each="g:${list}" > <td th:text="${g.id}"></td> <td th:text="${g.name}"></td> <td th:text="${g.remark}"></td> <td th:text="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td> <td><a th:href="@{/goods/doDeleteById(id=${g.id})}">delete</a></td> </tr> </tbody> </table> </body> </html>
第五步:在表單中輸入數據,而後點擊保存按鈕,將數據傳遞到服務端
有什麼不懂的歡迎在下方留言討論,也能夠選擇私信問我,私信我通常看到以後都會回的,固然特別忙的時候沒看到的話也請見諒!