SpringBoot後臺代碼生成系統

@TOCcss

1、項目背景

做爲技術人員的你,你可能遇到頻繁的小項目不斷的在建立(包括生產或技術語言),基礎功能代碼類似度達到90%,系統的基礎接口、流程、參數等幾近類似。每次新建項目就算你在熟悉,你也得花很大部分的時間(從數據庫層到服務層到應用層到基礎配置,我相信你在這裏起碼要花差很少半天的時間),不過你仍是不斷的建立相似項目、不斷的添加數據庫操做層、不斷的服務接口和實現層,最後還要爲外部提供API接口,其實當你項目作多了你就知道你一直在乾重復的工做,在吸食沒有養分的垃圾實物。你把大量的時間浪費在基礎項目框架搭建、基礎代碼的編寫。html

一、手動建立項目型問題

你花了不少的時間僅僅是在作以下的工做:java

  • 建立WEB系統後臺框架

你須要新建符合本身的項目,添加Spring工具、數據庫工具、JSon處理、Redis處理、日誌處理等,每次須要根據本身的需求去添加劇復的maven依賴;mysql

  • 數據庫MyBatis接口實現及映射配置

咱們在後臺常用MyBtis或JPA去作數據訪問層,你須要編寫對應的接口,還須要編寫接口對應的SQL語句和映射關係,你須要對你設計的全部的table逐個一字不差的編寫以便能順利調試經過DAO接口,甚至你要添加不少個經過任意字段的組合均可以查詢的通用接口,甚是吃力、費勁還不必定準確。git

  • 建立系統的實體模型

要實現與數據庫的數據面向對象交互,咱們必須提供與表相對應的PO對象,也就是咱們系統中必須用到的entity,不一樣的系統雖然對應的model不太同樣,但也就是model的名稱和字段不同而已,不過相同的是有一個名字、有n個不一樣名稱的字段!爲何不能從數據中將錶轉換爲實體,這樣不就大大減小了代碼量?github

  • 建立面向業務的服務接口

DAO是面向數據庫層的,可是業務通常是變化的,因此咱們通常系統中咱們要抽離一層service接口出來面向系統業務實現事務操做,因此爲了通常狀況下針對業務層咱們要實現業務接口層、業務接口實現層的全部代碼,業務層在經過DAO層來實現數據庫的CURD操做,其實你會發現這層的業務基礎的邏輯幾乎與DAO層徹底類似(僅僅是個別的面向系統業務的接口須要個性化增長)。web

  • 建立面嚮應用的控制層接口

爲了能提供對外接口,在MVC模式中咱們還必需要提供對外的Controller層,也就是咱們所說的API層,咱們須要將對應的業務暴露給外部或第三方平臺,要求規範外部請求參數、請求方式、請求接口地址等,因此不得已咱們還必須實現一層業務控制層代碼,經過調用業務服務層代碼實現系統的業務功能。redis

  • 建立系統配置

因此的應用啓動都必須經過啓動配置進行啓動,能夠包括開發環境配置、生產環境配置、測試環境配置等,其實這一類的配置也幾近是相同的,能夠統一塊兒來配置,個性化的配置才須要用戶本身添加。spring

  • 建立日誌配置

日誌是系統必不可少的組件,咱們的系統必需要配置對應的日誌信息,包括保存目錄、存儲方式、日誌級別等。不過這一部分基本上咱們能夠約定,差別性的才須要用戶去更新,因此這部分的工做也能夠統籌起來,使用代碼生成。sql

  • 工具集成配置

項目開發過程當中咱們須要藉助不少工具來保證系統的穩定運行,包括分佈式日誌、SQL性能監控、跨域訪問、JSON轉換、文本轉換、日期轉換、加解密、文件操做、HTTP調用等等等,不過你會發現沒新建一個項目你都會火燒眉毛的將你封裝的、感受很好用的工具通通都打包進去,由於你知道這個工具是很經常使用也基本上用的到,因此你每次都會拷貝它,我就想問,你每次這麼作是否是感受好累,導出查找位置、拷貝粘貼、修改包名!(固然,最好的方法不是拷貝進去二十封裝層本身的一個jar包庫到系統中)。

二、項目複製型新建項目問題

若是你發現這個多東西都是可複製的,只須要做爲模板,而後按照模板修改就能夠新建成另外一個項目,不過你會發現即便你拷貝成另一個項目你也會面對以下問題:

  • 刪除太多沒必要要的東西

被複制的項目通常包含了大量的與該系統業務相關的代碼,因此你拿過去以後你須要刪除全部與業務相關的代碼;

  • 接口實現大量改動

由於業務不一樣致使數據庫設計不一樣所帶來的問題就是基本上全部重要的代碼都要刪除或重構,包括系統實體模型、數據mapper層、業務service層、service實現層、控制層。你會發現你基本上還不如重建一個新項目還來得乾脆!

  • 環境兼容性

開發環境中,不是你改一個名字就能夠處處運行,由於不少時候你修改的並不完全,改完以後一直到其餘地方或環境發現是錯誤、紅點,不熟悉的開發人員根本沒法解決對應的紅色問題。

既然以上兩種方案有如此多的問題,既然代碼工做重複性如此之大,爲什麼你依然執拗於重建重加劇改?那倒不如將重複的工做集成到一個項目中,之後建立項目的時候只須要專一於寫好本身的SQL腳本,而後經過web網頁或swagger輸入本身的項目信息一鍵生成本身的項目,一鼓作氣,何樂而不爲?這也是本人的初衷,也算是爲公司爲各位網友節省大量的開發時間和人力成本。

2、項目成果

對技術人員來講,技術都不是問題,缺的就是想法,基本上沒有實現不了的事,剩下的就是時間的問題了,通過2-3天的開發,基本上成型,實現了自動生成SpringBoot後臺代碼的初衷。

一、代碼生成服務

我將實現了代碼生成的服務代碼成了安裝包,以下所示:
在這裏插入圖片描述
啓動後以下所示(確保運行機器安裝JDK而且80端口未被佔用且按安裝了mysql):
在這裏插入圖片描述
啓動後遠程機器監聽的80端口,咱們直接經過瀏覽器訪問對應機器ip便可:
http://192.168.8.18進入登陸頁面
在這裏插入圖片描述
經過用戶名admin,密碼:123456進入系統便可(注意session在30分鐘內過時從新登陸)

二、項目建立

一、設計數據庫

正如我說的,有了框架生成服務咱們只須要專一於本身的數據庫設計便可,這裏個人業務是在音視頻這塊的應用,我設計了2個表,數據庫腳本以下所示:

-- ------------------------------------------------------
-- 建立並使用數據庫
-- ------------------------------------------------------
set charset utf8;
create database if not exists mclz character set UTF8;
use mclz;

--
-- 客戶端連接信息表
--
create table if not exists t_connection
(
    clientId bigint(20) NOT NULL,                /*     客戶端標識                       */
    ip varchar(16) default NULL,                /*     srs訪問的地址                */
    vhost varchar(64) default NULL,                /*     虛擬主機                    */
    app varchar(64) default NULL,                /*     應用名稱                    */
    tcUrl varchar(256) default NULL,            /*     訪問地址                    */
    pageUrl varchar(256) default NULL,            /*     訪問頁面                      */
    reserver1 varchar(128) default NULL,        /*     保留字段                    */
    reserver2 varchar(128) default NULL,        /*     保留字段                       */
    primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client connection information';

--
-- 視頻發佈信息表
--
create table if not exists t_publish
(
    clientId bigint(20) NOT NULL,                /*     客戶端標識                       */
    ip varchar(16) default NULL,                /*     srs訪問的地址                */
    vhost varchar(64) default NULL,                /*     虛擬主機                    */
    app varchar(64) default NULL,                /*     應用名稱                    */
    tcUrl varchar(256) default NULL,            /*     訪問地址                    */
    stream varchar(64) default NULL,            /*     流名稱                        */
    param varchar(128) default NULL,            /*     攜帶參數                    */
    reserver1 varchar(128) default NULL,        /*     保留字段                    */
    reserver2 varchar(128) default NULL,        /*     保留字段                       */
    primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client publish stream';

--
-- 視頻播放信息表
--
create table if not exists t_play
(
    clientId bigint(20) NOT NULL,                /*     客戶端標識                       */
    ip varchar(16) default NULL,                /*     srs訪問的地址                */
    vhost varchar(64) default NULL,                /*     虛擬主機                    */
    app varchar(64) default NULL,                /*     應用名稱                    */
    stream varchar(64) default NULL,            /*     流名稱                        */
    param varchar(128) default NULL,            /*     攜帶參數                    */
    reserver1 varchar(128) default NULL,        /*     保留字段                    */
    reserver2 varchar(128) default NULL,        /*     保留字段                       */
    primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client play stream';

個人業務中簡單的就三個表,客戶端鏈接表、視頻發佈表、視頻播放表,設計完成個人業務以後咱們就能夠經過上傳該腳本生成本身的web後臺系統,該系統包括了全部操做這3個表的DAO層、mybatis的XML配置、service層、service實現層、controller層以及如下靜態網頁。

二、建立項目

經過上面的步驟咱們登錄到框架生成系統中,以下所示
在這裏插入圖片描述

這裏的項目建立界面比較簡潔,我算是偷個懶,有空的時候在爲你們優化一下界面。須要注意些的都已經註明:

  • 使用流程:設計數據庫腳本=>填寫項目信息=>上傳數據庫腳本=>建立項目
  • 後續開發中,用戶只須要關注數據庫設計便可一鍵生成,不須要浪費大量時間構建後臺系統代碼
  • 系統生成的後臺使用的技術框架: SpringBoot+MyBtis+MySql的三層MVC服務架構
  • 系統提供瞭如系統配置、日誌配置、數據庫配置、攔截器配置、轉換器配置、Druid配置等相關配置代碼的生成
  • 系統提供瞭如控制層、服務接口層、服務實現層、數據訪問層、Mybatis映射XML腳本等基礎服務代碼的生成
  • 數據庫表不支持聯合主鍵類型的處理

個人sql腳本中建立的數據庫名稱爲"mclz",因此我填入的項目信息以下所示:

項目包名:com.easystudy    #該項做爲全部包的基礎包名應用到項目中
應用名稱:hello                    #項目名稱也是應用名稱對應項目Context名
應用端口:6666                    #項目對應的服務端口,http訪問需明確指定
數據庫地址:127.0.0.1          #部署機器必須安裝mysql用戶sql執行轉化
數據庫端口:3306                #服務暫時僅支持mysql數據庫操做
數據庫名稱:mclz                 #設計的SQL中建立並使用的數據庫名稱
數據庫用戶:root                  #運行腳本的mysql鏈接用戶名
數據庫密碼:root                  #運行腳本的mysql鏈接密碼
數據庫腳本:經過選擇sql腳本文件上傳後返回的sql臨時文件名

在這裏插入圖片描述
點擊「提交併建立項目」按鈕新建項目,成功後自動下載新建完成後的項目!在這裏插入圖片描述
咱們直接下載項目並導入到eclipse中便可,最後直接運行
在這裏插入圖片描述

根據咱們建立的項目名爲hello,項目監聽端口6666,咱們直接瀏覽器訪問:
http://localhost:6666/hello/
在這裏插入圖片描述
能夠看到後臺框架系統已經生成,接口也已經生成提供(後面一塊兒看看),你只須要實現你的UI界面開發便可!

數據庫性能監控頁面:
http://localhost:6666/hello/druid
在這裏插入圖片描述

三、項目結構

生成好後臺項目以後,咱們一塊兒來看看生成的項目的目錄結構,以下所示:在這裏插入圖片描述
能夠看到生成的可運行系統基本囊括了後臺SpringBoot後臺應用框架的全部的代碼,包括:

  • controller層代碼實現

在這裏插入圖片描述
部分代碼以下:

package com.easystudy.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PathVariable;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.easystudy.error.ErrorCode;
import com.easystudy.error.ReturnValue;
import com.easystudy.error.IOException;
import com.easystudy.model.Connection;
import com.easystudy.service.ConnectionService;

/**
 * @文件名稱: ConnectionController.java
 * @功能描述: 控制層對外接口
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息: 
 */
@Slf4j
@RestController
@RequestMapping("/tconnection")
@Api(tags = "Connection管理接口文檔", value = "提供Connection管理相關接口")
public class ConnectionController {
    @Autowired
    private ConnectionService connectionService;

    @PostMapping("/add")
    @ApiOperation(value="添加Connection信息", notes="添加Connection信息")
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "body", dataType = "Connection", name = "connection", value = "Connection信息", required = true) })
    public ReturnValue<String> add(@RequestBody() Connection connection){
        try {
            connectionService.add(connection);
            return new ReturnValue<String>();
        } catch (IOException e) {
            log.error("添加信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "添加信息異常!");
    }

    @DeleteMapping("/delete/{clientId}")
    @ApiOperation(value="刪除Connection信息", notes="經過主鍵刪除Connection信息")
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "path", dataType = "Long", name = "clientId", value = "主鍵標識", required = true)})
    public ReturnValue<String> delete(@PathVariable(name="clientId", required=true) Long clientId){
        try {
            Connection temp = new Connection();
            temp.setClientId(clientId);
            connectionService.delete(temp);
            return new ReturnValue<String>();
        } catch (IOException e) {
            log.error("刪除信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "刪除信息異常!");
    }

    @PutMapping("/update")
    @ApiOperation(value="更新Connection信息", notes="更新Connection信息")
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "body", dataType = "Connection", name = "connection", value = "Connection信息", required = true) })
    public ReturnValue<String> update(@RequestBody Connection connection) {
        try {
            connectionService.update(connection);
            return new ReturnValue<String>();
        } catch (IOException e) {
            log.error("更新信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "刪除信息異常!");
    }

    @GetMapping("/findById/{clientId}")
    @ApiOperation(value="經過主鍵查找Connection信息", notes="經過主鍵查找Connection信息")
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "path", dataType = "Long", name = "clientId", value = "主鍵標識", required = true)})
    public ReturnValue<Connection> findById(@PathVariable(name="clientId", required=true) Long clientId){
        try {
            Connection connection = connectionService.findById(clientId);
            if(null == connection) {
                return new ReturnValue<Connection>(ErrorCode.ERROR_NOT_FOUND);
            }
            return new ReturnValue<Connection>(connection);
        } catch (IOException e) {
            log.error("查詢信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<Connection>(ErrorCode.ERROR_SERVER_ERROR, "查詢信息異常!");
    }

    @GetMapping("/findMaxByAttributes")
    @ApiOperation(value="經過屬性查找Connection總數", notes="經過屬性查找Connection總數")
    @ApiImplicitParams({ 
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "ip", value = "ip", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "vhost", value = "vhost", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "app", value = "app", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "tcUrl", value = "tcUrl", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "pageUrl", value = "pageUrl", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver1", value = "reserver1", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver2", value = "reserver2", required = false)
                         })
    public ReturnValue<Long> findMaxByAttributes(
                                                 @RequestParam(name="ip",required=false) String ip,
                                                 @RequestParam(name="vhost",required=false) String vhost,
                                                 @RequestParam(name="app",required=false) String app,
                                                 @RequestParam(name="tcUrl",required=false) String tcUrl,
                                                 @RequestParam(name="pageUrl",required=false) String pageUrl,
                                                 @RequestParam(name="reserver1",required=false) String reserver1,
                                                 @RequestParam(name="reserver2",required=false) String reserver2
            ) {
        try {
            Long count = connectionService.findMaxByAttributes(ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
            return new ReturnValue<Long>(count);
        } catch (IOException e) {
            log.error("查詢信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<Long>(ErrorCode.ERROR_SERVER_ERROR, "查詢信息異常!");
    }

    @GetMapping("/findByAttributes")
    @ApiOperation(value="查找Connection信息列表", notes="查找Connection信息列表")
    @ApiImplicitParams({ 
                        @ApiImplicitParam(paramType = "query", dataType = "Long", name = "pageIndex", value = "頁索引", required = true),
                        @ApiImplicitParam(paramType = "query", dataType = "Long", name = "pageSize", value = "頁大小", required = true),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "orderProp", value = "排序字段", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "order", value = "排序方式(asc、desc)", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "ip", value = "ip", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "vhost", value = "vhost", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "app", value = "app", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "tcUrl", value = "tcUrl", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "pageUrl", value = "pageUrl", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver1", value = "reserver1", required = false),
                        @ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver2", value = "reserver2", required = false)
                         })
    public ReturnValue<List<Connection>> findByAttributes(
                                                 @RequestParam(name="pageIndex",required=true) Long pageIndex,
                                                 @RequestParam(name="pageSize",required=true) Long pageSize,
                                                 @RequestParam(name="orderProp",required=false) String orderProp,
                                                 @RequestParam(name="order",required=false) String order,
                                                 @RequestParam(name="ip",required=false) String ip,
                                                 @RequestParam(name="vhost",required=false) String vhost,
                                                 @RequestParam(name="app",required=false) String app,
                                                 @RequestParam(name="tcUrl",required=false) String tcUrl,
                                                 @RequestParam(name="pageUrl",required=false) String pageUrl,
                                                 @RequestParam(name="reserver1",required=false) String reserver1,
                                                 @RequestParam(name="reserver2",required=false) String reserver2
            ) {
        try {
            List<Connection> list = connectionService.findByAttributes(pageIndex,pageSize,orderProp,order,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
            return new ReturnValue<List<Connection>>(list);
        } catch (IOException e) {
            log.error("經過屬性查詢信息異常:{}", e.getMessage());
            e.printStackTrace();
        }
        return new ReturnValue<List<Connection>>(ErrorCode.ERROR_SERVER_ERROR, "經過屬性查詢信息異常!");
    }

}
  • service接口層代碼

在這裏插入圖片描述
部分代碼實例:

package com.easystudy.service;

import com.easystudy.model.Connection;
import com.easystudy.error.IOException;
import java.util.List;

/**
 * @文件名稱: ConnectionService.java
 * @功能描述: 業務服務層接口
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息: 
 */
public interface ConnectionService extends BaseService<Connection> {

    Long findMaxByAttributes(String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException;

    List<Connection> findByAttributes(Long pageIndex,Long pageSize,String orderProp,String order,String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException;

}
  • service接口實現層

在這裏插入圖片描述
部分代碼示例:

package com.easystudy.service.impl;

import com.easystudy.model.Connection;
import com.easystudy.error.IOException;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.easystudy.mapper.ConnectionMapper;
import com.easystudy.service.ConnectionService;

/**
 * @文件名稱: ConnectionServiceImpl.java
 * @功能描述: 業務服務實現類
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息: 
 */
@Service
public class ConnectionServiceImpl implements ConnectionService {
    @Autowired
    private ConnectionMapper mapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public void add(Connection o) throws IOException {
        mapper.insertSelective(o);
    }
    @Override
    public void delete(Connection o) throws IOException {
        mapper.deleteByPrimaryKey(o.getClientId());
    }
    @Override
    public void update(Connection o) throws IOException {
        mapper.updateByPrimaryKeySelective(o);
    }
    @Override
    public Connection findById(Object id) throws IOException {
        return mapper.selectByPrimaryKey((Long)id);
    }
    @Override
    public List<Connection> findByAttributes(Long pageIndex,Long pageSize,String orderProp,String order,String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException {
        return mapper.selectByAttributes(pageIndex,pageSize,orderProp,order,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
    }
    @Override
    public Long findMaxByAttributes(String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException {
        return mapper.selectMaxByAttributes(ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
    }

}
  • DAO接口層

在這裏插入圖片描述
部分實現代碼:

package com.easystudy.mapper;

import com.easystudy.model.Connection;
import java.util.List;
import org.apache.ibatis.annotations.Param;

/**
 * @文件名稱: ConnectionMapper.java
 * @功能描述: Dao層數據操做接口
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息: 
 */
public interface ConnectionMapper {
    int deleteByPrimaryKey(Long clientId);

    int insert(Connection connection);

    int insertSelective(Connection connection);

    Connection selectByPrimaryKey(Long clientId);

    int updateByPrimaryKeySelective(Connection connection);

    int updateByPrimaryKey(Connection connection);

    Long selectMaxByAttributes(@Param("ip")String ip,@Param("vhost")String vhost,@Param("app")String app,@Param("tcUrl")String tcUrl,@Param("pageUrl")String pageUrl,@Param("reserver1")String reserver1,@Param("reserver2")String reserver2);

    List<Connection> selectByAttributes(@Param("pageIndex")Long pageIndex,@Param("pageSize")Long pageSize,@Param("orderProp")String orderProp,@Param("order")String order,@Param("ip")String ip,@Param("vhost")String vhost,@Param("app")String app,@Param("tcUrl")String tcUrl,@Param("pageUrl")String pageUrl,@Param("reserver1")String reserver1,@Param("reserver2")String reserver2);
}
  • mybatis腳本層

在這裏插入圖片描述
部分代碼示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.easystudy.mapper.ConnectionMapper" >
  <resultMap id="BaseResultMap" type="com.easystudy.model.Connection" >
    <id column="clientId" property="clientId" jdbcType="BIGINT" />
    <result column="ip" property="ip" jdbcType="VARCHAR" />
    <result column="vhost" property="vhost" jdbcType="VARCHAR" />
    <result column="app" property="app" jdbcType="VARCHAR" />
    <result column="tcUrl" property="tcUrl" jdbcType="VARCHAR" />
    <result column="pageUrl" property="pageUrl" jdbcType="VARCHAR" />
    <result column="reserver1" property="reserver1" jdbcType="VARCHAR" />
    <result column="reserver2" property="reserver2" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Base_Column_List" >
    clientId,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
    select <include refid="Base_Column_List" />from t_connection where clientId = #{clientId,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
    delete from t_connection where clientId = #{clientId,jdbcType=BIGINT}
  </delete>
  <select id="selectMaxByAttributes" resultType="long">
      select count(clientId) from t_connection
      <where>
          <if test="ip != null and ip.length() > 0">
              ip like CONCAT('%',#{ip},'%')
          </if>
          <if test="vhost != null and vhost.length() > 0">
              and vhost like CONCAT('%',#{vhost},'%')
          </if>
          <if test="app != null and app.length() > 0">
              and app like CONCAT('%',#{app},'%')
          </if>
          <if test="tcUrl != null and tcUrl.length() > 0">
              and tcUrl like CONCAT('%',#{tcUrl},'%')
          </if>
          <if test="pageUrl != null and pageUrl.length() > 0">
              and pageUrl like CONCAT('%',#{pageUrl},'%')
          </if>
          <if test="reserver1 != null and reserver1.length() > 0">
              and reserver1 like CONCAT('%',#{reserver1},'%')
          </if>
          <if test="reserver2 != null and reserver2.length() > 0">
              and reserver2 like CONCAT('%',#{reserver2},'%')
          </if>
      </where>
  </select>
  <select id="selectByAttributes" resultMap="BaseResultMap">
      select <include refid="Base_Column_List" /> from t_connection
      <where>
          <if test="ip != null and ip.length() > 0">
              ip like CONCAT('%',#{ip},'%')
          </if>
          <if test="vhost != null and vhost.length() > 0">
              and vhost like CONCAT('%',#{vhost},'%')
          </if>
          <if test="app != null and app.length() > 0">
              and app like CONCAT('%',#{app},'%')
          </if>
          <if test="tcUrl != null and tcUrl.length() > 0">
              and tcUrl like CONCAT('%',#{tcUrl},'%')
          </if>
          <if test="pageUrl != null and pageUrl.length() > 0">
              and pageUrl like CONCAT('%',#{pageUrl},'%')
          </if>
          <if test="reserver1 != null and reserver1.length() > 0">
              and reserver1 like CONCAT('%',#{reserver1},'%')
          </if>
          <if test="reserver2 != null and reserver2.length() > 0">
              and reserver2 like CONCAT('%',#{reserver2},'%')
          </if>
      </where>
      <if test="orderProp != null and orderProp.length() > 0">
        order by
        <choose>
            <when test="order != null and order != 'desc' and order != 'asc'">
                ${orderProp} asc
            </when>
            <when test="order == null">
                ${orderProp}
            </when>
            <otherwise>
                ${orderProp} ${order}
            </otherwise>
        </choose>
    </if>
      limit #{pageIndex}, #{pageSize}
  </select>
  <insert id="insert" parameterType="com.easystudy.model.Connection" >
    insert into t_connection(clientId,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2) values(#{clientId,jdbcType=BIGINT},#{ip,jdbcType=VARCHAR},#{vhost,jdbcType=VARCHAR},#{app,jdbcType=VARCHAR},#{tcUrl,jdbcType=VARCHAR},#{pageUrl,jdbcType=VARCHAR},#{reserver1,jdbcType=VARCHAR},#{reserver2,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.easystudy.model.Connection" >
    insert into t_connection
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="clientId != null" >
        clientId,
      </if>
      <if test="ip != null" >
        ip,
      </if>
      <if test="vhost != null" >
        vhost,
      </if>
      <if test="app != null" >
        app,
      </if>
      <if test="tcUrl != null" >
        tcUrl,
      </if>
      <if test="pageUrl != null" >
        pageUrl,
      </if>
      <if test="reserver1 != null" >
        reserver1,
      </if>
      <if test="reserver2 != null" >
        reserver2,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="clientId != null" >
        #{clientId,jdbcType=BIGINT},
      </if>
      <if test="ip != null" >
        #{ip,jdbcType=VARCHAR},
      </if>
      <if test="vhost != null" >
        #{vhost,jdbcType=VARCHAR},
      </if>
      <if test="app != null" >
        #{app,jdbcType=VARCHAR},
      </if>
      <if test="tcUrl != null" >
        #{tcUrl,jdbcType=VARCHAR},
      </if>
      <if test="pageUrl != null" >
        #{pageUrl,jdbcType=VARCHAR},
      </if>
      <if test="reserver1 != null" >
        #{reserver1,jdbcType=VARCHAR},
      </if>
      <if test="reserver2 != null" >
        #{reserver2,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.easystudy.model.Connection" >
    update t_connection
    <set>
      <if test="clientId != null" >
        clientId = #{clientId,jdbcType=BIGINT},
      </if>
      <if test="ip != null" >
        ip = #{ip,jdbcType=VARCHAR},
      </if>
      <if test="vhost != null" >
        vhost = #{vhost,jdbcType=VARCHAR},
      </if>
      <if test="app != null" >
        app = #{app,jdbcType=VARCHAR},
      </if>
      <if test="tcUrl != null" >
        tcUrl = #{tcUrl,jdbcType=VARCHAR},
      </if>
      <if test="pageUrl != null" >
        pageUrl = #{pageUrl,jdbcType=VARCHAR},
      </if>
      <if test="reserver1 != null" >
        reserver1 = #{reserver1,jdbcType=VARCHAR},
      </if>
      <if test="reserver2 != null" >
        reserver2 = #{reserver2,jdbcType=VARCHAR},
      </if>
    </set>
    where clientId = #{clientId,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.easystudy.model.Connection" >
    update t_connection
        clientId = #{clientId,jdbcType=BIGINT},
        ip = #{ip,jdbcType=VARCHAR},
        vhost = #{vhost,jdbcType=VARCHAR},
        app = #{app,jdbcType=VARCHAR},
        tcUrl = #{tcUrl,jdbcType=VARCHAR},
        pageUrl = #{pageUrl,jdbcType=VARCHAR},
        reserver1 = #{reserver1,jdbcType=VARCHAR},
        reserver2 = #{reserver2,jdbcType=VARCHAR}
    where clientId = #{clientId,jdbcType=BIGINT}
  </update>
</mapper>
  • 系統model層

3個表生成對應3個實體類-持久化對象(PO)
在這裏插入圖片描述
部分代碼示例:

package com.easystudy.model;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

/**
 * @文件名稱: Connection.java
 * @功能描述: 系統實體類
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息: 
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Connection {
    private Long clientId;
    private String ip;
    private String vhost;
    private String app;
    private String tcUrl;
    private String pageUrl;
    private String reserver1;
    private String reserver2;
}
  • 系統配置

包括跨域訪問配置、Swagger配置以及MVC配置類
在這裏插入圖片描述

部分示例代碼:

package com.easystudy.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @文件名稱: CORSConfig.java
 * @功能描述: 跨域訪問配置
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0
 * @備註信息:
 */
@Configuration
public class CORSConfig {

    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        // 容許cookies跨域
        config.setAllowCredentials(true);
        // #容許向該服務器提交請求的URI,*表示所有容許,在SpringMVC中,若是設成*,會自動轉成當前請求頭中的Origin
        config.addAllowedOrigin("*");
        // #容許訪問的頭信息,*表示所有
        config.addAllowedHeader("*");
        // 預檢請求的緩存時間(秒),即在這個時間段裏,對於相同的跨域請求不會再預檢了
        config.setMaxAge(18000L);
        // 容許提交請求的方法,*表示所有容許
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

}

swagger訪問地址:
http://localhost:6666/hello/druid/datasource.html
swagger接口文檔:
在這裏插入圖片描述

  • 系統使用錯誤碼

後臺系統錯誤碼VO值對象類,提供json與實體的轉化,支持攜帶錯誤碼和錯誤描述
在這裏插入圖片描述
部分示例代碼:

package com.easystudy.error;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

/**
 * @文件名稱: ReturnValue.java
 * @功能描述: 系統返回值dto定義
 * @版權信息: www.easystudy.com
 * @技術交流: 961179337(QQ羣)
 * @編寫做者: lixx2048@163.com
 * @聯繫方式: 941415509(QQ)
 * @開發日期: 2020年10月19日
 * @歷史版本: V1.0 
 * @備註信息:
 */
@JsonInclude(Include.NON_NULL) 
public class ReturnValue<T> {
    private Integer error = 0;                // 錯誤
    private String description = "";        // 錯誤描述
    private T value;                        // 返回值【當error爲ERROR_NO_SUCCESS纔有可能返回值-判斷值是否爲空】
    
    // 成功不帶返回值
    public ReturnValue(){
        this.error = ErrorCode.ERROR_SUCCESS.getError();
        this.description = "成功";
    }
    
    // 成功帶返回值
    public ReturnValue(T value){
        if(null == value){
            this.error = ErrorCode.ERROR_NOT_FOUND.getError();
            this.description = "沒有找到你須要的資源";
        } else {
            this.error = ErrorCode.ERROR_SUCCESS.getError();
            this.description = "成功";
            this.value = value;
        }        
    }
    
    // 返回錯誤
    public ReturnValue(ErrorCode error){
        this.error = error.getError();
        this.description = error.getDescription();
    }
    
    // 返回錯誤--對錯誤描述進行更改
    public ReturnValue(ErrorCode error, String description){
        this.error = error.getError();
        this.description = description;
    }
    
    // 返回錯誤
    public ReturnValue(Integer error){
        this.error = error;
        this.description = ErrorCode.getDescription(error);
    }
    
    public ReturnValue(Integer error, String description){
        this.error = error;
        this.description = description;
    }
    
    public Integer getError() {
        return error;
    }
    
    public boolean success(){
        return error == ErrorCode.ERROR_SUCCESS.getError();
    }

    public void setError(Integer error) {
        this.error = error;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }
}
  • 系統配置

自動生成系統配置文件
在這裏插入圖片描述
系統配置文件以下所示:

server:
  port: 6666
  servlet: 
    context-path: /hello
  #nio的web服務配置
  undertow:
    #爲工做者建立的I/O線程數
    io-threads: 20
    #工做者線程數量
    worker-threads: 50
    #訪問日誌
    accesslog: 
      enabled: false
spring:
  application:
    name: hello
  #NOSQL
  redis:
    host: localhost
    port: 6379
    password: 
    timeout: 6000
    pool: 
      max-active: 20   #鏈接池最大鏈接數(使用負值表示沒有限制)
      max-wait: -1
      max-idle: 8
      min-idle: 0
  #數據源
  datasource:
    name: mclz
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/mclz?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
      username: root
      password: root
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 'x'
      validation-query-timeout: 6
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: false
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
logging:
  config: classpath:logback.xml
mybatis:
  mapper-locations: classpath:mapping/*.xml
  type-aliases-package: com.easystudy.model
  • 靜態網頁

示例代碼:

<!DOCTYPE html>  
<html lang="en">  
    <head>
        <meta charset="UTF-8">
        <title>歡迎登陸hello系統</title>
        <link rel="stylesheet" type="text/css" href="../css/login.css"/>
    </head>
    <body>
        <h1>Hello World!</h1>
    </body>  
</html>
  • 系統POM配置
<?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.easystudy</groupId>
    <artifactId>hello</artifactId>
    <version>1.0.1.1</version>

    <!-- spring boot項目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!-- 項目屬性:子模塊不能引用父項目的properties變量 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        <lombok.version>1.16.20</lombok.version>
    </properties>

    <!-- 項目依賴管理聲明,統一管理項目依賴的版本信息,繼承項目無需聲明版本 -->
    <dependencyManagement>
        <!-- 依賴管理  -->
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- jdbc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- hystrix儀表盤 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
                <version>${hystrix.dashboard}</version>
            </dependency>
            <!-- Spring-Mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
            <!-- 阿里巴巴druid數據庫鏈接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.9</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!-- 阿里巴巴json序列化反序列化 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.46</version>
            </dependency>
            <!-- 分頁插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.5</version>
            </dependency>
            <!--
                RESTFul接口文檔:經過接口訪問文檔:http://localhost:8762/swagger-ui.html,8762爲服務配置的監聽端口,默認8080
                feign Finchley.RELEASE 2.0.3 版本與feign版本衝突,使用feign必需要配置2.5.0以上版本
            -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.8.0</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.8.0</version>
            </dependency>
            <!-- feign:自己支持Hystrix的
              <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
                <version>1.4.4.RELEASE</version>
            </dependency>-->
            <!-- 遠程調用:2.0.0.RELEASE版本會致使服務註冊到nacos上 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
            <!-- reids做爲緩存 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>2.1.4.RELEASE</version>
            </dependency>
            <!-- 文件上傳 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.4</version>
            </dependency>
            <!-- httpclient -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
                <version>4.4.1</version>
            </dependency>
            <!-- junit測試 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- SpringMVC -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- RESTFul接口文檔:經過接口訪問文檔:http://localhost:8762/swagger-ui.html,8762爲服務配置的監聽端口,默認8080 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
        <!-- 配置文件讀取 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <!--Lombok:消除模板代碼-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- logback日誌包 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- Spring-Mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- 阿里巴巴druid數據庫鏈接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
    </dependencies>

    <!-- 編譯插件 -->
    <build>
        <plugins>
            <!--spring boot maven插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- 包含本地jar包 -->
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  • 系統日誌配置

系統配置以下:

<configuration>
    <!-- 每一個logger都關聯到logger上下文,默認上下文名稱爲「default」,用於區分不一樣應用程序的記錄。一旦設置,不能修該 -->
    <contextName>hello</contextName>
    <!--配置常量,在後面的配置中使用 -->
    <property name="PROJECT_NAME" value="hello" />
    <!--配置常量,在後面的配置中使用 -->
    <property name="COMPANY_NAME" value="hello" />
    <!--定義日誌文件的存儲地址 勿在 LogBack 的配置中使用相對路徑 -->
    <property name="LOG_HOME" value="/home/${COMPANY_NAME}/logs/${PROJECT_NAME}" />
    <!--定義日誌輸出格式:左對齊級別 -日期 -消息 換行-->
    <property name="LOG_PATTERN" value="[%-5p] - %d{yyyy-MM-dd HH:mm:ss} - %msg%n" />
    <!-- 定義日誌輸出字符集 -->
    <property name="LOG_CHARSET" value="UTF-8" />

    <!-- 調試日誌:輸出控制檯 -->
    <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <!--定義輸出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${LOG_CHARSET}</charset>
        </encoder>
        <!-- 比INFO小的日誌級別不會被打印出來:打印全部級別  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>

    <!-- 正常INFO級別日誌:輸出文件-->
    <appender name="INFO-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定義輸出文件名-->
        <file>${LOG_HOME}/info/${PROJECT_NAME}.log</file>
        <!--定義輸出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${LOG_CHARSET}</charset>
        </encoder>
        <!-- 比該配置的小的日誌級別不會被打印出來  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!--定義日誌滾動的策略-->
        <!-- TimeBasedRollingPolicy和SizeBasedTriggeringPolicy衝突,使用SizeAndTimeBasedRollingPolicy -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--定義文件滾動時的文件名的格式:dys-warn_2019-01-10-%i.log-->
            <fileNamePattern>${LOG_HOME}/info/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!-- 每一個文件大小最大200M -->
            <maxFileSize>200MB</maxFileSize>
            <!-- 最大保存n天 -->
            <maxHistory>7</maxHistory>
            <!-- 日誌總保存量爲2G:該屬性在 1.1.6版本後 纔開始支持-->
            <totalSizeCap>2GB</totalSizeCap>
            <!-- 啓動時清除無效歷史數據 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
    </appender>

    <!-- 警告日誌:輸出文件-->
    <appender name="WARN-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定義輸出文件名-->
        <file>${LOG_HOME}/warn/${PROJECT_NAME}.log</file>
        <!--定義輸出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${LOG_CHARSET}</charset>
        </encoder>
        <!-- 比該配置的小的日誌級別不會被打印出來  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>
        <!--定義日誌滾動的策略-->
        <!-- TimeBasedRollingPolicy和SizeBasedTriggeringPolicy衝突,使用SizeAndTimeBasedRollingPolicy -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--定義文件滾動時的文件名的格式:dys-warn_2019-01-10-%i.log-->
            <fileNamePattern>${LOG_HOME}/warn/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!-- 每一個文件大小最大200M -->
            <maxFileSize>200MB</maxFileSize>
            <!-- 最大保存n天 -->
            <maxHistory>7</maxHistory>
            <!-- 日誌總保存量爲2G:該屬性在 1.1.6版本後 纔開始支持-->
            <totalSizeCap>2GB</totalSizeCap>
            <!-- 啓動時清除無效歷史數據 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
    </appender>
    
    <!-- 錯誤日誌:輸出文件-->
    <appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定義輸出文件名-->
        <file>${LOG_HOME}/error/${PROJECT_NAME}.log</file>
        <!--定義輸出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${LOG_CHARSET}</charset>
        </encoder>
        <!-- 比該配置的小的日誌級別不會被打印出來  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <!--定義日誌滾動的策略-->
        <!-- TimeBasedRollingPolicy和SizeBasedTriggeringPolicy衝突,使用SizeAndTimeBasedRollingPolicy -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--定義文件滾動時的文件名的格式:dys-warn_2019-01-10.log-->
            <fileNamePattern>${LOG_HOME}/error/${PROJECT_NAME}_%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!-- 每一個文件大小最大500M -->
            <maxFileSize>500MB</maxFileSize>
            <!-- 最大保存n天 -->
            <maxHistory>15</maxHistory>
            <!-- 日誌總保存量爲2G:該屬性在 1.1.6版本後 纔開始支持-->
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 根日誌輸出:root爲默認日誌輸出INFO或以上級別(additivity=true時被繼承,或name類沒法找到時被繼承-->
    <root level="INFO">
        <!-- 輸出到控制檯 -->
        <appender-ref ref="CONSOLE-LOG" />
        <!-- 輸出到各個類型日誌文件 -->
        <appender-ref ref="INFO-LOG" />
        <appender-ref ref="WARN-LOG" />
        <appender-ref ref="ERROR-LOG" />
    </root>
    
    <!-- 調試日誌:輸出控制檯 -->
    <appender name="CONSOLE-LOG2" class="ch.qos.logback.core.ConsoleAppender">
        <!--定義輸出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>${LOG_CHARSET}</charset>
        </encoder>
        <!-- 比DEBUG小的日誌級別不會被打印出來:打印全部級別  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    
    <!-- mybatis輸出:不繼承根配置 -->
    <logger name="com.easystudy.mapper" level="DEBUG" additivity="false">
        <!-- 輸出到控制檯 -->
        <appender-ref ref="CONSOLE-LOG2" />
    </logger>

</configuration>

以上就是完整的、最基礎的項目的代碼生成介紹,該項目主要經過以下方式實現:

  • 約定的名稱、路徑等

系統生成代碼經過約定的值進行的,包括日誌存儲位置、名稱、默認依賴。

  • 默認的代碼風格樣式

代碼風格使用比較規範的樣式進行生成

  • 默認的模板

全部的代碼是依賴模板生成的,有模板的拷貝替換、模板依葫蘆畫瓢,這裏可能有做者代碼的身影在裏面,見諒!

2、合做使用

源碼獲取、合做、技術交流請獲取以下聯繫方式:
QQ交流羣:961179337
在這裏插入圖片描述

微信帳號:lixiang6153 公衆號:IT技術快餐 電子郵箱:lixx2048@163.com

相關文章
相關標籤/搜索