在大型軟件系統設計時,業務通常會相對複雜,假如全部業務實現的代碼都糾纏在一塊兒,會出現邏輯不清晰、可讀性差,維護困難,改動一處就牽一髮而動全身等問題。爲了更好解決這個問題就有了咱們如今常說的分層架構設計。html
MVC是一種軟件架構設計思想,基於MVC架構將咱們的應用軟件進行分層設計和實現,例如能夠分爲視圖層(View),控制層(Controller),模型層(Model),經過這樣的分層設計讓咱們程序具有更好的靈活性和可可擴展性.由於這樣能夠將一個複雜應用程序進行簡化,實現各司其職,各盡所能.比較適合一個大型應用的開發.java
Spring MVC是MVC設計思想在Spring框架中的一種實現,基於這樣的思想spring框架設計了一些相關對象,用於更好的基於MVC架構處理請求和響應,其簡易架構如圖所示:mysql
其中:
1)DispatcherServlet是客戶端全部請求處理的入口,負責請求轉發。
2)RequestMapping負責存儲請求url到後端handler對象之間的映射。
3)Handler 用於處理DispatcherServlet對象轉發過來的請求數據。
4)ViewResolver負責處理全部Handler對象響應結果中的view。web
第一步:建立springboot項目10-springboot-goods
第二步:添加依賴
第三步:配置文件初始化spring
#server server.port=1314 #spring datasource spring.datasource.url=jdbc:mysql:///dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=1234 #spring mybatis mybatis.mapper-locations=classpath:/mapper/*/*.xml #spring thymeleaf spring.thymeleaf.prefix=classpath:/templates/pages/ spring.thymeleaf.suffix=.html spring.thymeleaf.cache=false #spring logging #logging.file.path=d:/logs/ logging.level.com.cy=debug management.endpoints.web.exposure.include=*
其API架構設計,如圖所示:sql
查詢全部商品信息,其業務時序分析,如圖所示:
第一步:定義Goods對象,封裝查詢到的對象apache
package com.cy.pj.goods.pojo; import java.util.Date; /** * 用來封裝商品 */ 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() { return createdTime; } @Override public String toString() { return "Goods{" + "id=" + id + ", name='" + name + ''' + ", remark='" + remark + ''' + ", createdTime=" + createdTime + '}'; } }
第二步:Dao接口方法及映射定義segmentfault
package com.cy.pj.goods.dao; import java.util.List; import org.apache.ibatis.annotations.*; import com.cy.pj.goods.pojo.Goods; /** * 商品數據邏輯對象,負責商品模塊的數據訪問邏輯的實現 */ @Mapper public interface GoodsDao { @Update("update tb_goods set name=#{name},remark=#{remark} where id=#{id}") int updateGoods(Goods entity); @Select("select * from tb_goods where id=#{id}") Goods findById(Integer id); @Insert("insert into tb_goods(name,remark,createdTime) values(#{name},#{remark},now())") int insertGoods(Goods entity); /** * 基於id進行刪除 * @param id * @return */ @Delete("delete from tb_goods where id=#{id}") int deleteById(Integer id); /** * 查詢全部的商品信息 * @return 全部的商品 * mybatis框架中定義sql映射有兩種方式: * 1,註解方式(實現簡單的sql映射) * 2,使用XML方式(實現複雜的sql映射) */ @Select("select * from tb_goods") List<Goods> findGoods(); }
第三步:Service接口方法定義及實現後端
GoodsService接口springboot
package com.cy.pj.goods.service; import com.cy.pj.goods.pojo.Goods; import java.util.List; /** * 用來定義商品業務邏輯操做的接口 */ public interface GoodsService { int updateGoods(Goods entity); Goods findById(Integer id); int saveGoods(Goods entity); int deleteById(Integer id); List<Goods> findGoods(); }
GoodsService接口實現類GoodsServiceImpl定義及方法實現
package com.cy.pj.goods.service; import com.cy.pj.goods.dao.GoodsDao; import com.cy.pj.goods.pojo.Goods; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class GoodsServiceImpl implements GoodsService { private static final Logger log=LoggerFactory.getLogger(GoodsServiceImpl.class); @Autowired private GoodsDao goodsDao; @Override public int updateGoods(Goods entity) {//對於update操做,參數entity中須要有一個id值 return goodsDao.updateGoods(entity); } @Override public Goods findById(Integer id) { return goodsDao.findById(id);//未來還能夠將查詢到的結果在業務邏輯層存儲到cache } @Override public int saveGoods(Goods entity) { return goodsDao.insertGoods(entity); } @Override public int deleteById(Integer id) { int rows=goodsDao.deleteById(id); return rows; } @Override public List<Goods> findGoods() { long t1=System.currentTimeMillis(); List<Goods> list=goodsDao.findGoods(); long t2=System.currentTimeMillis(); log.info("findGoods time-> {}", t2-t1);//{}爲佔位符好 return list; } }
第四步:Controller對象方法定義及實現
定義GoodsController類,
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.*; import java.util.List; @Controller @RequestMapping("/goods/") public class GoodsController { @Autowired private GoodsService goodsService; @PostMapping("doUpdateGoods") public String doUpdateGoods(Goods entity){//用pojo對象接收客戶端參數 goodsService.updateGoods(entity); return "redirect:/goods/doGoodsUI"; } @RequestMapping("doFindById/{id}") public String doFindById(@PathVariable Integer id,Model model){ Goods goods=goodsService.findById(id); model.addAttribute("g", goods); return "goods-update"; } @RequestMapping("doSaveGoods") public String doSaveGoods(Goods entity){//用pojo對象接收客戶端參數 goodsService.saveGoods(entity); return "redirect:/goods/doGoodsUI"; } /** * 返回商品添加頁面 * @return */ @RequestMapping("doGoodsAddUI") public String doGoodsAddUI(){ return "goods-add"; } @RequestMapping("doDeleteById/{id}")//rest風格(軟件架構編碼風格)url public String doDeleteById(@PathVariable Integer id){//@PathVariable 描述參數時表示參數的值來自url goodsService.deleteById(id); return "redirect:/goods/doGoodsUI";//redirect 表示重定向(客戶端再次向服務端發請求) } // @RequestMapping("doDeleteById") // public String doDeleteById(Integer id){ // goodsService.deleteById(id); // return "redirect:/goods/doGoodsUI";//redirct 表示重定向(客戶端再次向服務端發請求) // } @RequestMapping("doGoodsUI") public String doGoodsUI(Model model){ List<Goods> goodsList=goodsService.findGoods(); model.addAttribute("goodsList", goodsList); return "goods";//Viewname //返回值會交給DispatcherServ // let進行處理 //DispatcherServlet會調用ViewResolver進行視圖解析(view+model) //最後DispatcherServlet將解析結果響應到頁面上 } }
第五步:Goods商品列表頁面設計及實現
在templates/pages目錄中添加goods.html頁面,並在body中添加html元素,在運行內部使用thymeleaf標籤屬性獲取數據,代碼以下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table width="50%"> <a th:href="@{/goods/doGoodsAddUI}">添加商品</a> <thead> <th>id</th> <th>name</th> <th>remark</th> <th>createdTime</th> <th colspan="2">operation</th> </thead> <tbody> <tr th:each="g:${goodsList}"> <td th:text="${g.id}">1</td> <td th:text="${g.name}">MySQL</td> <td th:text="${g.remark}">DBMS</td> <td th:text="${#dates.format(g.createdTime, 'yyyy/MM/dd HH:mm')}">2020/07/03</td> <td><a th:href="@{/goods/doDeleteById/{id}(id=${g.id})}">delete</a></td> <td><a th:href="@{/goods/doFindById/{id}(id=${g.id})}">update</a></td> </tr> </tbody></table> </body> </html>
goods-adds.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- ul li :後代選擇器,ul 裏全部的 li 元素,包括 ol 裏的 li ; ul>li :子代選擇器,下一級的DOM節點,不包括 ol 裏的 li 。 ul>ol>li :子代選擇器必須一代接一代。--> <style> ul>li{ list-style-type: none; } </style> </head> <body> <div> <h1>the goods add pages</h1> <form th:action="@{/goods/doSaveGoods}" method="post"> <ul> <li>name</li> <li><input type="text" name="name"></li> <li>remark</li> <li><textarea rows="3" cols="50" name="remark"></textarea></li> <li><input type="submit" value="Save Goods"></li> </ul> </form> </div> </body> </html>
goods-update.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- ul li :後代選擇器,ul 裏全部的 li 元素,包括 ol 裏的 li ; ul>li :子代選擇器,下一級的DOM節點,不包括 ol 裏的 li 。 ul>ol>li :子代選擇器必須一代接一代。--> <style> ul>li{ list-style-type: none; } </style> </head> <body> <div> <h1>the goods update pages</h1> <form th:action="@{/goods/doUpdateGoods}" method="post"> <ul> <li><input type="hidden" name="id" th:value="${g.id}"></li> <li>name</li> <li><input type="text" name="name" th:value="${g.name}"></li> <li>remark</li> <li><textarea rows="3" cols="50" name="remark" th:text="${g.remark}"></textarea></li> <li><input type="submit" value="Update Goods"></li> </ul> </form> </div> </body> </html>
thymeleaf 是一種模板引擎,此引擎以html爲模板,能夠添加自定義標籤屬性,能夠將服務端model中數據填充在頁面上,而後實現與用於交互。其官網爲thymeleaf.org
Goods頁面上數據呈現分析:
第六步:啓動服務器進行測試
http://localhost:1314/goods/doGoodsUI