基於springboot+Mybatis+MySQL的作業管理系統搭建總結

需求分析

用例分析

在這裏插入圖片描述

數據庫設計

一共設計了3張表

s_user: 存儲用戶信息

s_homework: 存儲教師發佈的作業

s_student_homework: 存儲學生提交的作業

爲了查詢方便,沒有設置外鍵約束

在這裏插入圖片描述

開發技術

開發平臺:windows 10
開發工具:Intellij IDEA 2019.3.3
JDK:Java 8
Maven:maven-3.6.3
服務器:tomcat 7.0
數據庫:MySQL 8.0
數據源:Druid1.1.6
Spring Boot:1.5.6.RELEASE

ORM框架:MyBatis+通用Mapper

實現過程

  • 項目目錄

搭建IDEA+springboot項目

  • File --> New --> Project
    在這裏插入圖片描述

  • Spring Initializer --> 選擇SDK–>Next
    在這裏插入圖片描述

  • 創建項目的文件結構以及jdk的版本 --> Next
    在這裏插入圖片描述

  • 選擇項目所需要的依賴

這裏寫圖片描述

這裏寫圖片描述

使用mysql創建數據庫

sql語句如下:

CREATE DATABASE `school` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;

CREATE TABLE `s_user` (
  `account` char(8) NOT NULL,
  `password` char(18) NOT NULL,
  `name` varchar(20) NOT NULL,
  `type` int NOT NULL,
  PRIMARY KEY (`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `s_homework` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `title` varchar(20) DEFAULT NULL,
  `content` text,
  `score` int NOT NULL,
  `techerid` char(8) NOT NULL,
  `create_time` timestamp NOT NULL,
  `update_time` timestamp NULL DEFAULT NULL,
  `teacher_name` char(8) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `s_student_homework` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `student_id` char(8) DEFAULT NULL,
  `homework_id` bigint NOT NULL,
  `homework_title` varchar(45) NOT NULL,
  `homework_content` text,
  `score` int DEFAULT NULL,
  `comment` char(150) DEFAULT NULL,
  `create_time` timestamp NOT NULL,
  `update_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

使用mybatis generator 自動生成代碼:

  • 創建application.yml配置文件,配置datasource和mybatis

server:
  port: 8080

spring:
  datasource:
    name: test
    url: jdbc:mysql://127.0.0.1:3306/school
    #serverTimezone: UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: 123456
    # 使用druid數據源
    #type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    filters: stat
    maxActive: 20
    initialSize: 1
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20

## 該配置節點爲獨立的節點,有很多同學容易將這個配置放在spring的節點下,導致配置無法被識別
mybatis:
  mapper-locations: classpath:mapping/*.xml  #注意:一定要對應mapper映射xml文件的所在路徑
  type-aliases-package: com.winter.model  # 注意:對應實體類的路徑

  • 在pom.xml中添加generator 插件
<!-- mybatis generator 自動生成代碼插件 -->
			<plugin>
				<groupId>org.mybatis.generator</groupId>
				<artifactId>mybatis-generator-maven-plugin</artifactId>
				<version>1.3.2</version>
				<configuration>
					<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
					<overwrite>true</overwrite>
					<verbose>true</verbose>
				</configuration>
			</plugin>
  • 創建pom.xml中generator 插件所對應的配置文件 generatorConfig.xml

    設置數據庫驅動

    設置數據庫連接

    設置生成模型的包名和位置

    設置生成映射文件的包名和位置

    設置DAO的包名和位置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- 數據庫驅動:選擇你的本地硬盤上面的數據庫驅動包-->
    <classPathEntry  location="E:\developer\mybatis-generator-core-1.3.2\lib\mysql-connector-java-5.1.25-bin.jar"/>
    <context id="DB2Tables"  targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--數據庫鏈接URL,用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/mytest" userId="root" password="root">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 生成模型的包名和位置-->
        <javaModelGenerator targetPackage="com.winter.model" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- 生成映射文件的包名和位置-->
        <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- 生成DAO的包名和位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.winter.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 要生成的表 tableName是數據庫中的表名或視圖名 domainObjectName是實體類名-->
   <table tableName="s_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>

<table tableName="s_student_homework" domainObjectName="StudentHomework" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="s_homework" domainObjectName="Homework" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>
  • 點擊run-Edit Configurations
    在這裏插入圖片描述

  • 添加配置
    在這裏插入圖片描述

  • 運行generator
    在這裏插入圖片描述
    對應generatorConfig.xml中的配置,每張表對應生成模型、映射文件、DAO
    在這裏插入圖片描述

  • 在springboot啓動類中吧mapper的路徑加進來
    在這裏插入圖片描述

@MapperScan : mapper接口掃描註解

重複運行時模型和DAO文件會重寫,映射文件文件不會,將導致項目運行時會出錯
解決辦法:重新運行之前先刪除mapper.xml文件

我們還需要一些特殊的sql語句,可以自己添加

比如實現:select * from s_homework

HomeworkMapper.java 中添加如下代碼

List<Homework> selectAll();

HomeworkMapper.xml


  <select id="selectAll" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Long" >
    select
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from s_homework
      order by create_time DESC
  </select>

編寫Service

遵循單一責任原則和接口分離原則

在這裏插入圖片描述

  • UserService

    package com.winter.service;
    import com.winter.model.User;
    /**
     * Created by wjq
     */
    public interface UserService {
        int addUser(User user);
        User selectUser(String account);
    
    }
    
  • UserHomeworkServiceImpl

    package com.winter.service;
    
    import com.winter.mapper.UserMapper;
    import com.winter.model.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service(value = "userService")
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;//這裏會報錯,但是並不會影響
    
        @Override
        public User selectUser(String account) {
            return userMapper.selectByPrimaryKey(account);
        }
    
        @Override
        public int addUser(User user) {
    
            return userMapper.insertSelective(user);
        }
    
    }
    
  • HomeworkService

    package com.winter.service;
    
    import com.winter.model.Homework;
    
    import java.util.List;
    
    /**
     * @author:Jingqi Wu
     * @date: 2020/4/23
     */
    public interface HomeworkService {
    
    
        /**
         * 老師發佈作業
         * @param homework
         * @return
         */
        int addHomework(Homework homework);
        /**
         *  This is the method to be used to list down all homework
         * @return
         */
        List<Homework> selectAll();
        List<Homework> selectByTeacherId(String teacherId);
        List<Homework> selectByTeacherName(String teacherName);
        Homework selectByPK(Long id);
    }
    
  • HomeworkServiceImpl

    package com.winter.service;
    
    import com.winter.mapper.HomeworkMapper;
    import com.winter.model.Homework;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @author:Jingqi Wu
     * @date: 2020/6/16
     */
    @Service(value = "homeworkService")
    public class HomeworkServiceImpl implements HomeworkService {
        @Autowired
        HomeworkMapper homeworkMapper;
    
        /**
         * 老師發佈作業
         *
         * @param homework
         * @return
         */
        @Override
        public int addHomework(Homework homework) {
            return homeworkMapper.insert(homework);
        }
    
        /**
         * This is the method to be used to list down all homework
         *
         * @return
         */
        @Override
        public List<Homework> selectAll() {
            return homeworkMapper.selectAll();
        }
    
        @Override
        public List<Homework> selectByTeacherId(String teacherId) {
    
            return homeworkMapper.selectByTeacherId(teacherId);
        }
    
        @Override
        public List<Homework> selectByTeacherName(String teacherName) {
            return homeworkMapper.selectByTeacherName(teacherName);
        }
    
        @Override
        public Homework selectByPK(Long id) {
            return homeworkMapper.selectByPrimaryKey(id);
        }
    }
    
  • StudentHomeworkService

    package com.winter.service;
    import com.winter.model.StudentHomework;
    
    import java.util.List;
    
    
    /**
     * @author:Jingqi Wu
     * @date: 2020/6/16
     */
    public interface StudentHomeworkService {
    
    
        /**
         * 學生提交作業
         * @param studentHomework
         * @return
         */
        int addStudentHomework(StudentHomework studentHomework);
    
        /**
         * @return
         */
        int updateStudentHomework(StudentHomework studentHomework);
        /**
         *  This is the method to be used to list down all
         *  students' homework
         * @param homeworkId
         * @return
         */
        List<StudentHomework> selectByHomeworkId(Long homeworkId);
    
        /**
         * This is the method to be used to search the student's homework
         *
         * @param id
         * @return
         */
        StudentHomework selectByP(Long id);
    
        /**
         * 目前是通過studentid,homeworkid查詢
         * @param studentHomework
         * @return
         */
        StudentHomework selectByDoublekey(StudentHomework studentHomework);
    }
    
    
  • StudentHomeworkServiceImpl

    package com.winter.service;
    
    import com.winter.mapper.StudentHomeworkMapper;
    import com.winter.model.StudentHomework;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @author:Jingqi Wu
     * @date: 2020/6/16
     */
    @Service(value = "studentHomeworkService")
    public class StudentHomeworkServiceImpl implements StudentHomeworkService {
    
        @Autowired
        private StudentHomeworkMapper studentHomeworkMapper;
    
        /**
         * 學生提交作業
         *
         * @param studentHomework
         * @return
         */
        @Override
        public int addStudentHomework(StudentHomework studentHomework) {
            return studentHomeworkMapper.insert(studentHomework);
        }
    
        /**
         * This is the method to be used to list down all
         * students' homework
         *
         * @param homeworkId
         * @return
         */
        @Override
        public List<StudentHomework> selectByHomeworkId(Long homeworkId) {
            return studentHomeworkMapper.selectByHomeworkId(homeworkId) ;
        }
    
        /**
         * 目前是通過studentid,homeworkid查詢
         *
         * @param studentHomework
         * @return
         */
        @Override
        public StudentHomework  selectByDoublekey(StudentHomework studentHomework) {
            return studentHomeworkMapper.selectByDoublekey(studentHomework);
        }
    
        /**
         * This is the method to be used to search the student's homework
         *
         * @return
         */
        @Override
        public  StudentHomework selectByP(Long id) {
            return studentHomeworkMapper.selectByPrimaryKey(id);
        }
    
        /**
         * @param studentHomework
         * @return
         */
        @Override
        public int updateStudentHomework(StudentHomework studentHomework) {
            return studentHomeworkMapper.updateByPrimaryKeySelective(studentHomework);
        }
    }
    

編寫Controller

在這裏插入圖片描述

UserController

package com.winter.controller;

import com.winter.model.Homework;
import com.winter.model.StudentHomework;
import com.winter.model.User;
import com.winter.service.HomeworkService;
import com.winter.service.StudentHomeworkService;
import com.winter.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Controller
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private HomeworkService homeworkService;
    @Autowired
    private StudentHomeworkService studentHomeworkService;

    private User user;
    private ModelAndView mv = new ModelAndView();
    private Date date = new Date();

    /**
     * 用戶註冊
     * @return
     */
    @RequestMapping(value = "/register", produces = {"application/json;charset=UTF-8"})
    public String register() {
        return "register";
    }

    /**
     * 用戶登錄
     * @return
     */
    @RequestMapping(value = "/login", produces = {"application/json;charset=UTF-8"})
    public String login() {
        return "login";
    }

    /**
     * 添加用戶
     * @param user
     * @return
     */
    //@ResponseBody
    @RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})
    public String addUser(User user) {
        userService.addUser(user);
        return "redirect:/user/login";
    }

    /**
     * 登錄驗證
     * @param account
     * @param password
     * @return
     */
    @RequestMapping(value = "/verify", produces = {"application/json;charset=UTF-8"})
    public String selectUser(@RequestParam("account") String account,
                             @RequestParam("password") String password) {
        user = userService.selectUser(account);
        System.out.println(user.getPassword().equals(password));
        if (user.getPassword().equals(password)) {
            if (user.getType() == 0) {
                mv.setViewName("student");
                return "redirect:student";
            } else if (user.getType() == 1) {
                return "redirect:teacher";
            }
        }
        return "redirect:login";

    }

    /**
     * 教師版首頁顯示教師發佈的作業
     * @return
     */
    @RequestMapping(value = "/teacher", produces = {"application/json;charset=UTF-8"})
    public ModelAndView teacher() {
        List<Homework> list = new ArrayList<>();
        list = homeworkService.selectByTeacherId(user.getAccount());
        mv.setViewName("teacher");
        mv.addObject("name",user.getName());
        mv.addObject("list", list);
        return mv;
    }

    /**
     * 學生版首頁顯示所有教師發佈的作業
     * @return
     */
    @RequestMapping(value = "/student", produces = {"application/json;charset=UTF-8"})
    public ModelAndView student() {
        List<Homework> list = new ArrayList<>();
        list = homeworkService.selectAll();
        mv.setViewName("student");
        mv.addObject("name",user.getName());
        mv.addObject("list", list);
        return mv;
    }

    /**
     * 教師查看學生提交的作業列表
     * @param hid
     * @return
     */
    @RequestMapping(value = "/selectsh", produces = {"application/json;charset=UTF-8"})
    public ModelAndView selectsh(@RequestParam("homeworkId") Long hid) {
        List<StudentHomework> list = new ArrayList<>();
        list = studentHomeworkService.selectByHomeworkId(hid);
        mv.setViewName("studentHomeworks");
        mv.addObject("name",user.getName());
        mv.addObject("homeworkId",hid);
        mv.addObject("list", list);
        return mv;
    }

    /**
     * 學生選擇作業
     * @param studentHomework
     * @return
     */
    @RequestMapping(value = "/selectmh", produces = {"application/json;charset=UTF-8"})
    public ModelAndView selectmh(StudentHomework studentHomework) {
        studentHomework.setStudentId(user.getAccount());
        System.out.println(studentHomework.getStudentId());
        StudentHomework sh = studentHomeworkService.selectByDoublekey(studentHomework);

        Homework homework = homeworkService.selectByPK(studentHomework.getHomeworkId());
        List<StudentHomework> list = new ArrayList<>();
        if(sh != null) {
            list.add(sh);
        }
        mv.addObject("homework",homework);
        mv.setViewName("addStudentHomework");
        mv.addObject("studentId", user.getAccount());
        mv.addObject("name",user.getName());
        mv.addObject("homeworkId", studentHomework.getHomeworkId());

        mv.addObject("list", list);
        return mv;
    }
    /**
     * 根據教師姓名查詢作業
     * @param teacherName
     * @return
     */
    @RequestMapping(value = "/searchHomework", produces = {"application/json;charset=UTF-8"})
    public ModelAndView searchHomework(@RequestParam("teacherName") String teacherName) {
        List<Homework> list = new ArrayList<>();
        list = homeworkService.selectByTeacherName(teacherName);
        mv.setViewName("student");
        mv.addObject("list", list);
        mv.addObject("name",user.getName());
        return mv;
    }
    /**
     * 跳轉到學生修改作業頁
     * @param id
     * @return
     */
    @RequestMapping(value = "/modify", produces = {"application/json;charset=UTF-8"})
    public ModelAndView modify_mh(@RequestParam("id") Long id) {

        StudentHomework studentHomework = studentHomeworkService.selectByP(id);

        mv.setViewName("modify");
        mv.addObject("studentHomework", studentHomework);
        mv.addObject("name",user.getName());


        return mv;
    }

    /**
     * 學生提交作業
     * @param studentHomework
     * @return
     */
    @RequestMapping(value = "/addStudentHomework", produces = {"application/json;charset=UTF-8"})
    public String addStudentHomework(StudentHomework studentHomework) {
        studentHomework.setCreateTime(date);
        studentHomeworkService.addStudentHomework(studentHomework);
        return "redirect:student";
    }

    /**
     * 學生修改已提交的作業
     * @param studentHomework
     * @return
     */
    @RequestMapping(value = "/updateStudentHomework", produces = {"application/json;charset=UTF-8"})
    public String updateStudentHomework(StudentHomework studentHomework) {
        studentHomework.setUpdateTime(date);
        studentHomeworkService.updateStudentHomework(studentHomework);
        return "redirect:student";
    }

    /**
     * 教師發佈作業
     * @param homework
     * @return
     */
    @RequestMapping(value = "/addHomework", produces = {"application/json;charset=UTF-8"})
    public String addHomework(Homework homework) {
        homework.setTecherid(user.getAccount());
        homework.setTeacherName(user.getName());
        homework.setCreateTime(date);
        homeworkService.addHomework(homework);
        return "redirect:teacher";
    }


    /**
     * 教師根據studentId和homeworkId查詢學生作業
     * @param studentHomework
     * @return
     */
    @RequestMapping(value = "/searchStudentHomework", produces = {"application/json;charset=UTF-8"})
    public ModelAndView searchsh(StudentHomework studentHomework) {
        StudentHomework list = studentHomeworkService.selectByDoublekey(studentHomework);
        mv.setViewName("studentHomeworks");

        mv.addObject("list", list);
        mv.addObject("name",user.getName());
        return mv;
    }

    /**
     * 跳轉到教師批改業,顯示學生作業詳情
     * @param id
     * @return
     */
    @RequestMapping(value = "/review", produces = {"application/json;charset=UTF-8"})
    public ModelAndView review(@RequestParam("id") Long id) {
        StudentHomework list = studentHomeworkService.selectByP(id);
        mv.setViewName("review");
        mv.addObject("studentHomework", list);
        mv.addObject("name",user.getName());
        return mv;
    }
    /**
     * 教師提交評價
     * @param studentHomework
     * @return
     */
    @RequestMapping(value = "/addreview", produces = {"application/json;charset=UTF-8"})
    public String addReview(StudentHomework studentHomework) {
        studentHomeworkService.updateStudentHomework(studentHomework);
        return "redirect:selectsh?homeworkId="+studentHomework.getHomeworkId();
    }
}

源碼

https://github.com/BeJane/ssm-demo-homeworkMIS

交互設計及運行截圖

  • 教師/學生註冊:http://localhost:8080/user/register
    老師進行註冊
    在這裏插入圖片描述
    同學進行註冊
    在這裏插入圖片描述
  • 教師/學生登錄: http://localhost:8080/user/login
    註冊成功跳轉到登錄頁面,李四老師使用剛註冊的賬號進行登錄
    在這裏插入圖片描述
    學生進行登錄
    在這裏插入圖片描述
  • 教師發佈作業:http://localhost:8080/user/teacher
    登錄成功後進入教師首頁,可以看到教師自己以往發佈的作業,也可以發佈新的作業,發佈新 作業可以設置作業題目、作業內容、作業分值
    在這裏插入圖片描述
    發佈成功後可以在已發佈作業列表的第一行找到新發布的作業
    在這裏插入圖片描述
    點擊列表最後一列的查看,可以看到學生提交作業情況
  • 老師查看/查找學生作業:http://localhost:8080/user/selectsh?homeworkId=1
    在這裏插入圖片描述
    在輸入框輸入學號後點擊查詢,可以查找特定學生的學號
    比如:輸入12345
    在這裏插入圖片描述在這裏插入圖片描述
    點擊查看可以進行作業批改
  • 教師批改作業:http://localhost:8080/user/review?id=1
    在這裏插入圖片描述
  • 點擊每個頁面左上角的“註銷”退出登錄
  • 學生查看/查找教師發佈的作業:http://localhost:8080/user/student
    學生登錄成功進入學生版首頁,可以看到所有教師發佈的作業,越晚發佈排在前面
    在這裏插入圖片描述
    在輸入框輸入教師姓名,然後點擊查詢可以查找該老師發佈的作業
    比如輸入李德之
    在這裏插入圖片描述
  • 學生提交作業
    點擊查看,如果學生未提交該作業,則可進行提交
    在這裏插入圖片描述
    如果學生已提交過該作業,則可以查看相應作業的提交情況以及老師的評分和評語
    在這裏插入圖片描述
    點擊修改可以修改作業內容,修改時間會被記錄
  • 學生修改作業:http://localhost:8080/user/modify?id=1
    在這裏插入圖片描述

知識點總結

Spring的3個階段

第一階段:XML配置,在Spring1.x時代,使用Spring開發滿眼都是xml配置的Bean,隨着項目的擴大,我們需要把xml配置文件分放到不同的配置文件裏,那時候需要頻繁的在開發的類和配置文件之間切換。

第二階段:註解配置,在Spring2.x時代,Spring提供聲明Bean的註解,大大減少了配置量。應用的基本配置用xml,業務配置用註解。

第三階段:Java配置,從Spring3.x到現在,Spring提供了Java配置,使用Java配置可以讓你更理解你所配置的Bean。

Spring Boot:使用“習慣優於配置”的理念讓你的項目快速運行起來。使用Spring Boot很容易創建一個獨立運行、準生產級別的基於Spring框架的項目,使用Spring Boot你可以不用或者只需要很少的Spring配置。

下面就來使用Spring Boot一步步搭建一個前後端分離的應用開發框架,並且以後不斷的去完善這個框架,往裏面添加功能。後面以實戰爲主,不會介紹太多概念,取而代之的是詳細的操作。

springboot工作原理

在這裏插入圖片描述

一個典型的springboot應用

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
}

@SpringBootApplication

@SpringBootApplication是一個複合annotation。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    ...
}

其中最重要的三個annotation是@SpringBootConfiguration,@EnableAutoConfiguration和@ComponentScan。
所以以下 的springboot啓動類也可以啓動。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

@SpringBootConfiguration和@Configuration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration 

@SpringBootConfiguration本質上是一個@Configuration。
啓動類標註了@SpringBootConfiguration之後,本身其實也是一個ioc容器的配置類。

@EnableAutoConfiguration

spring框架提供了各種名字以@Enable開頭的annotation定義,比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration就是藉助@Import的支持,收集和註冊特定場景相關的bean定義:
@EnableScheduling是通過@Import將spring調度框架相關的bean定義都加載到ioc容器。
@EnableMBeanExport是通過@Import將JMX相關的bean定義都加載到ioc容器

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration 

@EnableAutoConfiguration作爲一個複合annotation,其中最關鍵的要屬@Import(AutoConfigurationImportSelector.class),藉助AutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助springboot應用將所有符合條件的@Configuration配置都加載到當前springboot創建並使用的ioc容器,就跟一隻八爪魚一樣。

AutoConfigurationImportSelector藉助spring框架原有的一個工具類SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能地完成自動配置。

SpringFactoriesLoader主要功能是從指定的配置文件META-INF/spring.factories加載配置,spring.factories是一個典型的Java properties文件,配置的格式爲key=value形式,只不過key和value都是Java類型的完整類型。

SpringFactoriesLoader在@EnableAutoConfiguration的場景中,更多的是提供了一種配置查找的功能支持,即根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration作爲查找的key,獲取對應的一組@Configuration類:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

所以,@EnableAutoConfiguration的自動配置就是從classpath中搜尋所有META-INF/spring.factories配置文件,並將其中org.springframework.boot.autoconfigure.EnableAutoConfiguration對應的配置項通過反射實例化爲對應的標註了@Configuration的JavaConfig形式的ioc容器配置類,然後彙總爲一個並加載到ioc容器。

@ComponentScan

@ComponentScan的功能其實就是自動掃描並加載符合條件的組件或bean定義,最終將這些bean定義加載到容器中。

Mybatis工作原理

img

mybatis應用程序通過SqlSessionFactoryBuilder從mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)來構建SqlSessionFactory(SqlSessionFactory是線程安全的);

然後,SqlSessionFactory的實例直接開啓一個SqlSession,再通過SqlSession實例獲得Mapper對象並運行Mapper映射的SQL語句,完成對數據庫的CRUD和事務提交,之後關閉SqlSession。

說明:SqlSession是單線程對象,因爲它是非線程安全的,是持久化操作的獨享對象,類似jdbc中的Connection,底層就封裝了jdbc連接。

詳細流程如下:

1、加載mybatis全局配置文件(數據源、mapper映射文件等),解析配置文件,MyBatis基於XML配置文件生成Configuration,和一個個MappedStatement(包括了參數映射配置、動態SQL語句、結果映射配置),其對應着<select | update | delete | insert>標籤項。

2、SqlSessionFactoryBuilder通過Configuration對象生成SqlSessionFactory,用來開啓SqlSession。

3、SqlSession對象完成和數據庫的交互:
a、用戶程序調用mybatis接口層api(即Mapper接口中的方法)
b、SqlSession通過調用api的Statement ID找到對應的MappedStatement對象
c、通過Executor(負責動態SQL的生成和查詢緩存的維護)將MappedStatement對象進行解析,sql參數轉化、動態sql拼接,生成jdbc Statement對象
d、JDBC執行sql。

​ e、藉助MappedStatement中的結果映射關係,將返回結果轉化成HashMap、JavaBean等存儲結構並返回。

Thymeleaf

Thymeleaf是一種用於Web和獨立環境的現代服務器端的Java模板引擎

常見用法

  • herf

    <a th:href="@{'review?id='+${entries['id']}}" >查看</a>
    
  • value

    <input type="hidden" name="homeworkId"  value="" th:value="*{homeworkId}">
    
  • 列表遍歷

     <tr th:each="entries:${list}" th:style="'background-color:'+'#F2F2F2'" >
            <td th:text="${entries['id']}"></td>
            <td th:text="${entries['studentId']}"></td>
    
     </tr>
    
  • 格式化日期時間

 <td th:text="${#dates.format(studentHomework['updateTime'], 'yyyy-MM-dd HH:mm')}"></td>
  • 判斷列表是否爲空
<div th:if="${#lists.isEmpty(list)}">
</div>
<div th:if="${not #lists.isEmpty(list)}">
</div>

參考資料

spring boot整合mybatis: https://blog.csdn.net/Winter_chen001/article/details/77249029

springboot工作原理:https://blog.csdn.net/Chen_Victor/article/details/81262233

Mybatis工作原理:https://blog.csdn.net/u014745069/article/details/80788127

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章