【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

Java學習總結 SpringBoot整合Spring MVC

1.SpringMVC概述

MVC(Model–view–controller)是軟件工程中的一種軟件架構模式,基於此模式把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。目的是經過這樣的設計使程序結構更加簡潔、直觀,下降問題的複雜度。其中各個組成部分的職責爲:
視圖(View) - UI設計人員進行圖形界面設計,負責實現與用戶交互。
控制器(Controller)- 負責獲取請求,處理請求,響應結果。
模型(Model) - 實現業務邏輯,數據邏輯實現。html

咱們在軟件設計時,一般要遵循必定的設計原則。MVC架構模式的設計中,首先基於單一職責原則(SRP-Single responsibility principle)讓每一個對象各司其職,各盡所能。
而後再基於「高內聚,低耦合」的設計思想實現相關層對象之間的交互。這樣能夠更好提升程序的可維護性和可擴展性。
JavaEE技術體系中,MVC設計思想的實現,如圖-14所示:
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC前端

在上圖中,Servlet充當MVC中的Controller,負責調用model處理業務,負責轉發或重定向某個頁面,在頁面(view)上呈現數據。
模塊封裝了對Servlet的技術的應用,簡化了程序員對請求和響應過程當中數據的處理。Spring MVC 是Spring 框架中基於MVC設計思想實現的一個用於處理Web請求的模塊。其簡易架構分析,以下圖所示:
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVCjava

DispatcherServlet :前端控制器, 處理請求的入口。
HandlerMapping:映射器對象, 用於管理url與對應controller的映射關係。
Interceptors:攔截器,實現請求響應的共性處理。
Controller:後端控制器-handler, 負責處理請求的控制邏輯。
ViewResolver:視圖解析器,解析對應的視圖關係(前綴+viewname+後綴)。
備註:假如但願瞭解Spring MVC的詳細處理流程能夠基於斷點調試法進行跟蹤。程序員

2.初始配置

1. 添加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

2. 配置Spring MVC 核心對象

在application.proper視ties文件中添加圖解析器配置(假如沒有配置也會默認配置,在默認配置中prefix默認值爲classpath:/templates/,後綴默認爲.html)。sql

spring.thymeleaf.prefix=classpath:/templates/pages/
spring.thymeleaf.suffix=.html

說明:要基於配置在src/main/resources目錄下建立templates/pages目錄數據庫

3.Spring MVC 進行入門實踐

第一步:編寫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應用設計,如圖所示:

【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

課堂練習1:將數據庫中的商品數據查詢出來更新到頁面上。

查詢時序分析:

【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

第一步:定義pojo對象(com.cy.pj.goods.pojo.Goods)

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 +
                '}';
    }
}

第二步:定義GoodsDao接口及方法

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接口及其實現類

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;
    }
}

第四步:定義GoodsController及其url映射

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將頁面響應給客戶端
    }
}

第五步:定義goods.html,經過Thymeleaf模板將活動數據呈如今頁面上

<!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>

第六步:運行Application啓動服務器,在網頁中輸入url地址

啓動服務器:
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

在網頁中輸入url地址:http://localhost:8080/goods/doGoodsUI
查詢結果以下:
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

課堂練習二:基於ID刪除商品庫中的商品信息

時序分析:

【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

第一步: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);
    }

}

第三步:ActivityController中定義doDeleteById(Integer 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將頁面響應給客戶端
    }
}

第四步:定義goods.html,經過Thymeleaf模板將活動數據呈如今頁面上

<!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>

第五步:運行Application啓動服務器,在網頁中輸入url地址

啓動服務器:
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

在網頁中輸入url地址:http://localhost:8080/goods/doGoodsUI
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

點擊delete
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

課堂練習三:將頁面用戶輸入的商品信息寫入到數據庫

時序分析

【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

第一步:在GoodsDao中定義insert(Goods entity)方法以及SQL映射

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接口及實現類中添加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;
    }
}

第三步:在GoodsController對象中添加doSaveGoods方法並定義url映射

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將頁面響應給客戶端
    }
}

第四步:在頁面中goods.html添加form表單(用戶填寫數據)並設置樣式

<!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>

第五步:在表單中輸入數據,而後點擊保存按鈕,將數據傳遞到服務端
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC
【深度分析】:阿里,騰訊面試題 SpringBoot整合Spring MVC

最後

有什麼不懂的歡迎在下方留言討論,也能夠選擇私信問我,私信我通常看到以後都會回的,固然特別忙的時候沒看到的話也請見諒!

相關文章
相關標籤/搜索