天天看點

Guns V2.5

Guns V2.5

新版Guns基于SpringBoot全面更新,完美整合springmvc + shiro + MyBatis 通用 Mapper + 分頁插件 PageHelper + beetl!

說明

本項目 fork 自 stylefeng 的 Guns!

經過對 Guns 項目的修改,使得該項目成為一個通用 Mapper 和 分頁插件使用的示例。

項目引入了下面兩個依賴:

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>${mapper-starter.version}</version>
</dependency>
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>${pagehelper-starter.version}</version>
</dependency>      

完全使用 MyBatis 官方的 Starter.

一個最簡單的 Spring Boot 內建項目:

https://github.com/abel533/MyBatis-Spring-Boot

修改說明

本項目對 Guns 的改動為:

  1. 将 mybatis-plus 改成了通用 Mapper.
  2. 增加分頁插件 PageHelper.
  3. 去掉

    com.stylefeng.guns.modular.system.dao

    包中的所有DAO,将方法放到對應的Mapper接口中.
  4. 将 Mapper.xml 移動到 resources 中

關于兩者的對比,可以通過 commit 資訊檢視。

更多 MyBatis 相關工具可以通路: http://mybatis.tk

V2.5更新日志

  1. 新增資料範圍功能(例如兩個角色都有使用者管理權限,但是下級部門不能看到上級部門的資料)
  2. 代碼生成的bug修複,現在相容windows和linux
  3. shiro的過濾器鍊改為LinkedHashMap
  4. 修複添加頂級部門添加不了的bug
  5. 解決日期格式化工具類線程安全的問題
  6. 修複日志記錄會出現多個重複檔案的bug

功能簡介

  1. 使用者管理
  2. 角色管理
  3. 部門管理
  4. 菜單管理
  5. 字典管理
  6. 業務日志
  7. 登入日志
  8. 監控管理
  9. 通知管理
  10. 代碼生成

使用說明

  1. 導入sql/guns.sql檔案到mysql資料庫
  2. 修改application.yml中的資料庫使用者名和密碼
  3. 以maven方式導入項目到ide
  4. 修改application.yml中的資料庫相關的配置,改為您本機的資料庫配置
  5. 啟動項目,管理者***賬号admin/密碼111111***

如何啟動項目

Guns目前支援三種啟動方式:

  1. 在IDE裡運作GunsApplication類中的main方法啟動
  2. 執行如下maven指令
clean package -Dmaven.test.skip=true
           

并從target目錄中找到guns-1.0.0-SNAPSHOT.jar,并在jar包的目錄下執行如下java指令

java -jar guns-1.0.0-SNAPSHOT.jar
           
  1. 修改pom.xml中如下片段
<packaging>jar</packaging>
           

改為

<packaging>war</packaging>
           

并打包放入到tomcat中執行

注意

最新版項目最低支援jdk1.7

所用架構

前端

  1. Bootstrap v3.3.6
  2. jQuery v2.1.4
  3. bootstrap-table v1.11.1
  4. layer v2.1
  5. zTree core v3.5.28
  6. WebUploader 0.1.5

後端

  1. SpringBoot 1.5.3.RELEASE
  2. MyBatis-通用Mapper-starter 1.1.3
  3. MyBats-PageHelper-starter 1.1.2
  4. MyBatis 3.4.4
  5. Spring 4.3.8.RELEASE
  6. Beetl 2.7.15
  7. hibernate-validator 5.3.5.Final
  8. Ehcache 3.3.1
  9. Kaptcha 2.3.2
  10. Fastjson 1.2.31
  11. Shiro 1.4.0
  12. Druid 1.0.31

項目包結構說明

├─main
│  │  
│  ├─java
│  │   │
│  │   ├─com.stylefeng.guns----------------項目主代碼
│  │   │          │
│  │   │          ├─common----------------項目公用的部分(業務中經常調用的類,例如常量,異常,實體,注解,分頁類,節點類)
│  │   │          │
│  │   │          ├─config----------------項目配置代碼(例如mybtais-plus配置,ehcache配置等)
│  │   │          │
│  │   │          ├─core----------------項目運作的核心依靠(例如aop日志記錄,攔截器,監聽器,guns模闆引擎,shiro權限檢查等)
│  │   │          │
│  │   │          ├─modular----------------項目業務代碼
│  │   │          │
│  │   │          ├─GunsApplication類----------------以main方法啟動springboot的類
│  │   │          │
│  │   │          └─GunsServletInitializer類----------------用servlet容器啟動springboot的核心類
│  │   │
│  │   └─generator----------------mybatis-plus Entity生成器
│  │
│  ├─resources----------------項目資源檔案
│  │     │
│  │     ├─gunsTemplate----------------guns代碼生成模闆
│  │     │ 
│  │     ├─application.yml----------------springboot項目配置
│  │     │ 
│  │     └─ehcache.xml----------------ehcache緩存配置
│  │
│  └─webapp----------------web頁面和靜态資源存放的目錄
│  
           

注:SpringBoot項目預設不支援将靜态資源和模闆(web頁面)放到webapp目錄,但是個人感覺resources目錄隻放項目的配置更加簡潔,是以就将web頁面繼續放到webapp目錄了.

項目特點

  1. 基于SpringBoot,簡化了大量項目配置和maven依賴,讓您更專注于業務開發,獨特的分包方式,代碼多而不亂。
  2. 完善的日志記錄體系,可記錄登入日志,業務記錄檔(可記錄操作前和操作後的資料),異常日志到資料庫,通過@BussinessLog注解和LogObjectHolder.me().set()方法,業務記錄檔可具體記錄哪個使用者,執行了哪些業務,修改了哪些資料,并且日志記錄為異步執行,詳情請見@BussinessLog注解和LogObjectHolder,LogManager,LogAop類。
  3. 利用beetl模闆引擎對前台頁面進行封裝和拆分,使臃腫的html代碼變得簡潔,更加易維護。
  4. 對常用js插件進行二次封裝,使js代碼變得簡潔,更加易維護,具體請見webapp/static/js/common檔案夾内js代碼。
  5. 利用ehcache架構對經常調用的查詢進行緩存,提升運作速度,具體請見ConstantFactory類中@Cacheable标記的方法。
  6. controller層采用map + warpper方式的傳回結果,傳回給前端更為靈活的資料,具體參見com.stylefeng.guns.modular.system.warpper包中具體類。
  7. 防止XSS攻擊,通過XssFilter類對所有的輸入的非法字元串進行過濾以及替換。
  8. 簡單可用的代碼生成體系,通過SimpleTemplateEngine可生成帶有首頁跳轉和增删改查的通用控制器、html頁面以及相關的js,還可以生成Service和Dao,并且這些生成項都為可選的,通過ContextConfig下的一些列xxxSwitch開關,可靈活控制生成模闆代碼,讓您把時間放在真正的業務上。
  9. 控制器層統一的異常攔截機制,利用@ControllerAdvice統一對異常攔截,具體見com.stylefeng.guns.core.aop.GlobalExceptionHandler類。
  10. 頁面統一的js key-value單例模式寫法,每個頁面生成一個唯一的全局變量,提高js的利用效率,并且有效防止多個人員開發引起的函數名/類名沖突,并且可以更好地去維護代碼。

基于javabean方式的spring配置

Guns以簡潔為核心,抛棄了傳統的易錯,臃腫xml配置,采用javabean的方式配置spring,簡化了項目的配置,如下示例為配置mybatis-plus和資料源:

@Configuration
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao", "com.stylefeng.guns.common.persistence.dao"})
public class MybatisPlusConfig {

    @Autowired
    DruidProperties druidProperties;

    /**
     * mybatis-plus分頁插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType(DBType.MYSQL.getDb());
        return paginationInterceptor;
    }

    /**
     * druid資料庫連接配接池
     */
    @Bean(initMethod = "init")
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.coinfig(dataSource);
        return dataSource;
    }
}
           

業務日志記錄原理

日志記錄采用aop(LogAop類)方式對所有包含@BussinessLog注解的方法進行aop切入,會記錄下目前使用者執行了哪些操作(即@BussinessLog value屬性的内容),如果涉及到資料修改,會取目前http請求的所有requestParameters與LogObjectHolder類中緩存的Object對象的所有字段作比較(是以在編輯之前的擷取詳情接口中需要緩存被修改對象之前的字段資訊),日志内容會異步存入資料庫中(通過ScheduledThreadPoolExecutor類)。

beetl對前台頁面的拆分與包裝

例如,把首頁拆分成三部分,每個部分單獨一個頁面,更加便于維護

<!--左側導航開始-->
    @include("/common/_tab.html"){}
<!--左側導航結束-->

<!--右側部分開始-->
    @include("/common/_right.html"){}
<!--右側部分結束-->

<!--右側邊欄開始-->
    @include("/common/_theme.html"){}
<!--右側邊欄結束-->
           

以及對重複的html進行包裝,使前端頁面更加專注于業務實作,例如,把所有頁面引用包進行提取

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit" /><!-- 讓360浏覽器預設選擇webkit核心 -->

<!-- 全局css -->
<link rel="shortcut icon" href="${ctxPath}/static/favicon.ico">
<!-- 全局js -->
<script src="${ctxPath}/static/js/jquery.min.js?v=2.1.4"></script>
<body class="gray-bg">
	<div class="wrapper wrapper-content animated fadeInRight">
		${layoutContent}
	</div>
	<script src="${ctxPath}/static/js/content.js?v=1.0.0"></script>
</body>
</html>
           

開發頁面時,隻需編寫如下代碼即可

@layout("/common/_container.html"){
<div class="row">
    <div class="col-sm-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>部門管理</h5>
            </div>
            <div class="ibox-content">
               //自定義内容
            </div>
        </div>
    </div>
</div>
<script src="${ctxPath}/static/modular/system/dept/dept.js"></script>
@}
           

以上beetl的用法請參考beetl說明文檔。

對js常用代碼的封裝

在webapp/static/js/common目錄中,有對常用js代碼的封裝,例如Feng.js,其中Feng.info(),Feng.success(),Feng.error()三個方法,分别封裝了普通提示,成功提示,錯誤提示的代碼,簡化了layer提示層插件的使用。

極簡的圖檔上傳方法

guns對web-upload進行二次封裝,讓圖檔的上傳功能呢隻用2行代碼即可實作,如下

var avatarUp = new $WebUpload("avatar");
avatarUp.init();
           

具體實作請參考static/js/common/web-upload-object.js

獨創controller層,map+warpper傳回方式

map+warpper方式即為把controller層的傳回結果使用BeanKit工具類把原有bean轉化為Map的的形式(或者原有bean直接是map的形式),再用單獨寫的一個包裝類再包裝一次這個map,使裡面的參數更加具體,更加有含義,下面舉一個例子,例如,在傳回給前台一個性别時,資料庫查出來1是男2是女,假如直接傳回給前台,那麼前台顯示的時候還需要增加一次判斷,并且前後端分離開發時又增加了一次交流和文檔的成本,但是采用warpper包裝的形式,可以直接把傳回結果包裝一下,例如動态增加一個字段sexName直接傳回給前台性别的中文名稱即可。

獨創mybatis資料範圍攔截器,實作對資料權限的過濾

Guns的資料範圍控制是指,對擁有相同角色的使用者,根據部門的不同進行相應的資料篩選,如果部門不相同,那麼有可能展示出的具體資料是不一緻的.是以說Guns對資料範圍控制是以部門id為機關來辨別的,如何增加資料範圍攔截呢?隻需在相關的mapper接口的參數中增加一個DataScope對象即可,DataScope中有兩個字段,scopeName用來辨別sql語句中部門id的字段名稱,例如deptiid或者id,另一個字段deptIds就是具體需要過濾的部門id的集合.攔截器原理如下:攔截mapper中包含DataScope對象的方法,擷取其原始sql,并做一個包裝限制部門id在deptIds範圍内的資料進行展示.

swagger api管理使用說明

swagger會管理所有包含@ApiOperation注解的控制器方法,同時,可利用@ApiImplicitParams注解标記接口中的參數,具體用法請參考CodeController類中的用法。

@ApiOperation("生成代碼")
 @ApiImplicitParams({
         @ApiImplicitParam(name = "moduleName", value = "子產品名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "bizChName", value = "業務名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "bizEnName", value = "業務英文名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "path", value = "項目生成類路徑", required = true, dataType = "String")
 })
 @RequestMapping(value = "/generate", method = RequestMethod.POST)
           

效果圖

Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5
Guns V2.5