1. 程式人生 > 其它 >教育後臺管理系統:後臺系統搭建

教育後臺管理系統:後臺系統搭建

1 課程管理模組功能分析

  在本次的專案中, 主要完成拉鉤教育後臺管理系統的 課程管理模組,

  課程管理模組包含了:

    新增課程,配置課程相關資訊, 以及管理課程章節等功能,

  我們來一起看一下產品的原型圖

課程管理

  實現以下功能:  

    展示課程列表

    根據課程名和狀態進行查詢

    新建課程

    課程上架與下架

營銷資訊

  營銷資訊,其實就是設定課程的詳細資訊

    回顯課程資訊

    修改課程資訊,包含了圖片上傳

配置課時

  配置課時指的是對課程下所屬的章節與課時進行配置(一個課程對應多個章節,一個章節有多個課時)

    以樹形結構的下拉框形式, 展示課程對應的章節與課時資訊

    新增章節功能

    修改章節功能

    修改章節狀態功能

2 課程管理模組表設計

建立資料庫及表

在資料中找到 lagou_edu.sql,使用SQLYog 執行SQL指令碼 ,匯入資料庫及表

表關係介紹

3 環境搭建

建立專案

使用Maven快速構建工程, 專案名為: lagou_edu_home

  

  1. 選擇maven ,直接next

  

  1. 填寫專案相關資訊,建立maven專案

  1. 當前maven專案還不是 一個web專案,進行一下改造

      詳見上一篇中的 "Maven工程改造"

專案目錄

匯入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.lagou</groupId>
    <artifactId>lagou_edu_home</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- properties 是全域性設定,可以設定整個maven專案的編譯器 JDK版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

        <!--    Beanutils    -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>

        <!--   DBUtils    -->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>


        <!-- 資料庫相關 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!--fastjson工具包 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>com.colobu</groupId>
            <artifactId>fastjson-jaxrs-json-provider</artifactId>
            <version>0.3.1</version>
        </dependency>

        <!--  檔案上傳 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!--   Lombok  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <!--  maven編譯外掛 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

匯入工具類及配置檔案

  匯入連線池工具類以及資料庫配置檔案

匯入實體類

1) Lombok介紹

  在專案中使用Lombok可以減少很多重複程式碼的書寫。比如說getter/setter/toString等方法的編寫。

2) IDEA中安裝 lombok外掛

  開啟IDEA的Setting –> 選擇Plugins選項 –> 搜尋lombok –> 點選安裝 –> 安裝完成重啟IDEA

3) 新增依賴

  在專案中新增Lombok依賴jar,在pom檔案中新增如下部分

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
    <scope>provided</scope>
</dependency>

4) Lombok常用註解

  @Getter/@Setter: 作用類上,生成所有成員變數的getter/setter方法

  @ToString : 作用於類,覆蓋預設的toString()方法 ,可以通過of屬性限定顯示某些欄位,通過exclude屬性排除某些欄位

  @AllArgsConstructor:生成全參構造器

  @NoArgsConstructor:生成無參構造器

  @Data: 該註解使用在上,該註解會提供 gettersetterequalshashCodetoString 方法。

5) 匯入表對應的實體類

4 通用Servlet

需求分析

  • 課程模組下有兩個子模組:

    • 課程模組

      • 營銷資訊

      • 配置課時(課程內容管理)

  每個模組下都有很多的功能, 比如課程模組 的 新建課程, 上架課程,下架課程,根據課程名查詢等等功能 , 每一個功能都是一個Servlet.

  • 問題: 一個功能就是一個Servlet, 那麼一個專案下有海量的Servlet, 這種方式好嗎 ?

    • Servlet太多了,不好管理, 而且Servlet越多 伺服器執行就越慢,資源消耗就越多.

Servlet對應模組

我們使用一個Servlet對應一個模組的方式進行開發

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <%--  一個模組對應一個Servlet  --%>
    <a href="${pageContext.request.contextPath}/test?methodName=addCourse">新建課程</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByName">根據課程名查詢</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByStatus">根據狀態查詢</a>
  </body>
</html>

TestServlet

/**
 *  模擬課程模組 ,模組中有很多功能
 * */
@WebServlet("/test")
public class TestServlet extends HttpServlet {

    /**
     *  doGet()方法作為排程器 控制器,根據請求的功能不同,呼叫對應的方法
     *
     * */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //1.獲取引數
        //獲取要呼叫的方法名
        String methodName = req.getParameter("methodName");

        //2.業務處理
        //判斷 執行對應的方法
        if("addCourse".equals(methodName)){
            addCourse(req,resp);

        }else if("findByStatus".equals(methodName)){
            findByName(req,resp);

        }else if("findByStatus".equals(methodName)){
            findByStatus(req,resp);

        }else{
            System.out.println("訪問的功能不存在!");
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }


    /**
     *  2.模組對應的功能部分
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("新建課程");
    }

    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據狀態查詢");
    }

    public void findByName(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據課程名稱查詢");
    }

}

提高程式碼的可維護行

我們可以使用反射去對程式碼進行優化, 提升程式碼的可維護性/可擴充套件性

反射的知識回顧:

  第一步:先獲取請求攜帶的方法引數值

  第二步:獲取指定類的位元組碼物件

  第三步:根據請求攜帶的方法引數值,再通過位元組碼物件獲取指定的方法

  第四步:最後執行指定的方法

/**
 *  模擬課程模組 ,模組中有很多功能
 * */
@WebServlet("/test")
public class TestServlet extends HttpServlet {

    /**
     *  doGet()方法作為排程器 控制器,根據請求的功能不同,呼叫對應的方法
     *
     * */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        try {
            //1.獲取引數
            //獲取要呼叫的方法名
            String methodName = req.getParameter("methodName");

            //2.業務處理
            if(methodName != null){
                //通過反射優化程式碼,提升程式碼的可維護性
                //1.獲取位元組碼物件  this = TestServlet物件
                Class c = this.getClass();

                //2.根據傳入的方法名, 獲取對應方法物件,執行方法即可
                Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

                //3.呼叫Method物件的 invoke()方法,執行對應的功能
                method.invoke(this,req,resp);
            }
        } catch (Exception e) {
            System.out.println("請求的功能不存在! !");
            e.printStackTrace();
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }


    /**
     *  2.模組對應的功能部分
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("新建課程");
    }

    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據狀態查詢");
    }

    public void findByName(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據課程名稱查詢");
    }
}

抽取通用的BaseServlet

當前程式碼依然存在問題:

每個Servlet都需要寫一份相同的反射程式碼

解決方案:

將反射相關的程式碼抽取到一個類中 BaseServlet, 讓BaseServlet去繼承HTTPServlet

  • BaseServlet

public class BaseServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        try {
            //1.獲取引數
            //獲取要呼叫的方法名
            String methodName = req.getParameter("methodName");

            //2.業務處理
            if(methodName != null){
                //通過反射優化程式碼,提升程式碼的可維護性
                //1.獲取位元組碼物件  this = TestServlet物件
                Class c = this.getClass();

                //2.根據傳入的方法名, 獲取對應方法物件,執行方法即可
                Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

                //3.呼叫Method物件的 invoke()方法,執行對應的功能
                method.invoke(this,req,resp);
            }
        } catch (Exception e) {
            System.out.println("請求的功能不存在! !");
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
  • 修改 TestServlet,繼承 BaseServlet
@WebServlet("/test")
public class TestServlet extends BaseServlet {

    /**
     *  在模組對應的Servlet中只保留 業務相關程式碼
     *  當有請求訪問到 TestServlet時, 發現沒有doGet和doPost方法,就回去父類中找,從而執行BaseServlet中的
     *  doGet方法
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("新建課程");
    }

    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據狀態查詢");
    }

    public void findByName(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("根據課程名稱查詢");
    }
}