權限管理系統之項目框架搭建並集成日誌、mybatis和分頁

前一篇博客中使用LayUI實現了列表頁面和編輯頁面的顯示交互,但列表頁面table渲染的數據是固定數據,本篇博客主要是將固定數據變成數據庫數據。

一、項目框架

首先要解決的是項目框架問題,搭建什麼樣的框架比較合適,優缺點是什麼,擴展性、可讀性等方面都要考慮,本項目的框架也是百度參考借鑑網友的,不管是Java還是C#的項目思想都差不多也都是可以互相借鑑的,下圖是項目結構圖,可能後面還會根據需要再進一步的修改完善。

上面目錄結構中主要包含8個包,下面對這幾個包進行簡單介紹。

com.example:存在main函數類

com.example.config:配置類包,例如druid多數據源配置類

com.example.controller:存放controller

com.example.dao:與數據庫交互層,存放mapper接口

com.example.entity:實體層,這個與com.example.pojo有點類似,不過兩個還是有區別的,pojo層主要是與數據庫單個數據表對應,entity可能是其他對象的抽象,比如多個表聯合查詢組成的行對應的類、或者前端頁面顯示對應的類、一對多、多對多關係。

com.example.pojo:數據庫表的對應類

com.example.service:業務服務接口層,定義服務接口,優勢是什麼呢,這樣在Controller中注入的是service接口,是面向接口的編程,如果服務的具體實現改變了也不影響其他注入類。

com.example.service.impl:實現服務接口,業務邏輯的具體實現

com.example.utils:基礎類、工具類層

二、集成日誌

項目使用的log4j2日誌框架,由於SpringBoot自帶的有日誌框架,所以需要先排除掉,然後在引入log4j2日誌。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
               <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

可以在application.properties中設置log4j2的相關配置或者創建log4j2.xml放在application.properties同目錄下。這裏在創建的log4j2.xml中設置日誌存放位置在D:\log\logs,在該目錄下可以看下日誌文件。

二、集成mybatis

集成mybatis主要是引入兩個依賴,一個是mysql的,一個是mybatis的。

        <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
View Code

項目是使用的xml方式管理sql,所以在該項目的resource目錄下創建了mybatis目錄,子目錄mapper存放sql映射文件,mybatis-config.xml放mybatis的配置,同時還需要在application.properties設置數據庫信息、mybatis文件目錄信息。

#mysql
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
#spring.datasource.url = jdbc:mysql://localhost:3306/mybatis
spring.datasource.url =jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456

#mybatis
mybatis.type-aliases-package=com.example.model
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

三、集成分頁pagehelper

集成pagehelper這裏有兩種方式,一是spring集成方式,二是SpringBoot集成方式,可參考:https://www.cnblogs.com/1315925303zxz/p/7364552.html 。這裏使用的是第一種,另外在這裏遇到了一個問題,就是分頁操作之後能查出數據但PageInfo的total值一直是0,原來是忘記在mybatis-config.xml配置pagehelper插件並要設置rowBoundsWithCount=true。

        <dependency>  
            <groupId>com.github.pagehelper</groupId>  
            <artifactId>pagehelper</artifactId>  
            <version>3.4.2</version>  
        </dependency>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
        <plugins>  
    <!-- com.github.pagehelper爲PageHelper類所在包名 -->  
    <plugin interceptor="com.github.pagehelper.PageHelper">  
        <!-- 方言 -->  
        <property name="dialect" value="mysql"/>  
        <!-- 該參數默認爲false -->  
        <!-- 設置爲true時,使用RowBounds分頁會進行count查詢 -->  
        <property name="rowBoundsWithCount" value="true"/>  
    </plugin>  
    </plugins> 
</configuration>
View Code

四、數據分頁實現

1.首先數據庫準備數據

這裏在數據表中插入了12條數據。

2.分頁

layui的table填充的數據有4個字段,code、msg、count、data,所以在PageDataResult中定義也定義了4個屬性。

package com.example.utils;

import java.util.List;

public class PageDataResult {
        //總記錄數量
        private Integer totals;
        //當前頁數據列表
        private List<?> list;

        private Integer code=200;
        
        private String msg="";

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public PageDataResult() {
        }

        public PageDataResult( Integer totals,
                List<?> list) {
            this.totals = totals;
            this.list = list;
        }

        public Integer getTotals() {
            return totals;
        }

        public void setTotals(Integer totals) {
            this.totals = totals;
        }

        public List<?> getList() {
            return list;
        }

        public void setList(List<?> list) {
            this.list = list;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }

        @Override public String toString() {
            return "PageDataResult{" + "totals=" + totals + ", list=" + list
                    + ", code=" + code + '}';
        }
}
View Code

3.分頁實現

主要實現方法也比較簡單,使用pagehelper進行分頁,然後將結果設置到PageDataResult。

    @Override
    public PageDataResult getUsers(UserSearchDTO userSearch) {

                PageDataResult pdr = new PageDataResult();
                PageHelper.startPage(userSearch.getPage(), userSearch.getLimit(),true);
                List<User> urList = userMapper.getUsers(userSearch);
                logger.debug("urList:"+urList.size());    
                // 獲取分頁查詢後的數據
                PageInfo<User> pageInfo = new PageInfo<>(urList);
                // 設置獲取到的總記錄數total:
                logger.debug("page:"+userSearch.getPage()+"limit:"+userSearch.getLimit()+"總行數:"+pageInfo.getTotal());
                pdr.setTotals(Long.valueOf(pageInfo.getTotal()).intValue());
                pdr.setList(urList);
                return pdr;
                
    }
View Code

4.替換固定數據

上一博客是將列表數據寫成固定的,這裏進行了替換,分頁之後返回PageDataResult。

    @RequestMapping(value = "/getUsers", method = RequestMethod.GET)
    @ResponseBody
    public PageDataResult getUsers(@RequestParam("page") Integer page,
            @RequestParam("limit") Integer limit,@RequestParam(value="keyword",required=false) String keyword) {
        logger.debug("分頁查詢用戶列表!,查詢條件keyword:"+keyword+"page:" + page+",每頁記錄數量limit:" + limit);
        
        PageDataResult pdr = new PageDataResult();
        try {
            if (null == page) {
                page = 1;
            }
            if (null == limit) {
                limit = 10;
            }
            UserSearchDTO userSearch=new UserSearchDTO(page,limit,keyword);
            // 獲取用戶和角色列表
            pdr = userService.getUsers(userSearch);
            logger.debug("用戶列表查詢=pdr:" + pdr);
            logger.debug("用戶列表查詢數量:" + pdr.getList().size());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("用戶列表查詢異常!", e);
        }
        return pdr;
    }
View Code

五、優化

由於從數據庫返回的user表的sex數據是0、1,所以需要轉成男、女,使用了table列的templet,同時id列通過hide=true進行了隱藏,又由於PageDataResult返回結果的key的名字與table所要求的不一致,又使用了response進行映射。下面代碼是目前最新的user.js代碼,後續可能還會更新。

var table;
var layer;
layui.use([ 'layer', 'table', 'element' ], function() {
    table = layui.table;
    layer = layui.layer;
    // 執行一個 table 實例
    table.render({
        elem : '#user',
        height:350,
        url : '/user/getUsers',
        method: 'get', //默認:get請求
        page :true, // 開啓分頁
        request: {
            pageName: 'page' //頁碼的參數名稱,默認:page
            ,limitName: 'limit' //每頁數據量的參數名,默認:limit
        },response:{
            statusName: 'code' //數據狀態的字段名稱,默認:code
            ,statusCode: 200 //成功的狀態碼,默認:0
            ,countName: 'totals' //數據總數的字段名稱,默認:count
            ,dataName: 'list' //數據列表的字段名稱,默認:data         
        },
        cols : [ [ // 表頭
            {
                fixed : 'left',
                type : 'checkbox'
            }, {
                field : 'id',
                title : 'ID',
                width : 80,
                fixed : 'left',
                hide:true
            }, {
                field : 'name',
                title : '姓名',
                width : 80
            },
            {
                field : 'age',
                title : '年齡',
                width : 80
            },
            {
                field : 'sex',
                title : '性別',
                width : 80,
                templet : function(d) {
                    if (d.sex == 1) {
                        return '男';
                    } else if (d.sex == 0) {
                        return '女';
                    }
                }
            },{
                title : '操作',
                width : 200,
                align : 'center',
                toolbar : '#tools'
            } ] ]

    });

// 監聽工具條
    table.on('tool(tools)', function(obj) { // 注:tool是工具條事件名,test是table原始容器的屬性
        var data = obj.data // 獲得當前行數據
            , layEvent = obj.event; // 獲得 lay-event 對應的值
        if ('edit' == layEvent) {
            addUser(data.id)
        } else if ('del' == layEvent) {
            del(data.id);
        }
    });
});

function queryUser(){
    var keyword = $("#keyword").val();
    table.reload('user', {
        where : {
            keyword : keyword
        },
        page : {
            curr : 1
        }
    });
    }

var index;
function addUser(id) {
    index = parent.layer.open({
        type : 2,
        title : "用戶信息",
        area: ['550px', '400px'],
        content : '/user/edit?id=' + id
    });
    layer.full(index);
}

function del(id) {
    parent.layer.open({
            type : 1,
            content : '<div style="padding: 20px 80px;">確定刪除記錄?</div>',
            btn : [ '確定', '取消' ],
            yes : function(index, layero) {
                $.ajax({
                    url : "/user/delete",
                    data : {
                        "id" : id
                    },
                    dataType : "text",
                    success : function(data) {
                        if(data==0){
                            layer.msg("刪除成功!");
                            layer.close(index);
                            queryUser();
                        }else{
                            layer.msg("刪除失敗!");
                        }
                    },
                    error : function() {
                    }
                });
            }
        });

}

/**
 * 獲取選中數據
 */
function getDatas(){
    var checkStatus = table.checkStatus('user');
    var data = checkStatus.data;
    var id = "";
    for(var i=0;i<data.length;i++){
        id += data[i].id;
        if(i<data.length-1){
            id += ",";
        }
    }
    if(data.length != 0){
        alert(id);
//        del(id);
    }
}
View Code

六.小結

目前把java部分的項目框架搭建了起來,也集成了日誌、mybatis、分頁插件pagehelper,實現了table頁面動態數據分頁顯示,後續就是將新增、編輯、刪除幾個功能實現,同時還要注意刪除功能,刪除用戶後可能還要刪除用戶與角色關聯表,會涉及到事務操作,後續也會加進來。

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