1. 程式人生 > >Mybatis與miniui的分頁結合,Mybatis排序、miniui分頁查詢、miniui載入等問題

Mybatis與miniui的分頁結合,Mybatis排序、miniui分頁查詢、miniui載入等問題

場景描述

        在專案使用miniui查詢資料展示的時候,進行分頁展示。但是在分頁查詢的過程中,發現miniui的ajax傳到後臺的引數有pageIndex、pageSize、sortField、sortOrder引數,而在每次查詢的時候,資料總數是該次分頁查詢的總數,資料量少的時候完全沒什麼壓力,但是當資料量很多的時候會很卡,完全違背了分頁查詢提高查詢效率的出發點。

        我的場景是使用@ResponseBody將查詢出的list自動給我轉換好格式傳給前端,雖然很省事自動的把我分頁查詢的資料進行展示,但是隻能處理一次分頁查詢出的所有資料。在查閱很多文章後(特別是有問題多在miniui官方的論壇查詢),發現官方給出的資料格式格式是一個大的JSON中有兩個元素,一個是total,一個是data,我就想自己設定一個跟官方文件的樣式的JSON資料傳給前臺。在傳給前臺展示的時候,是隻有兩條資料而且是空白的,這也很好理解,miniui是把我給他的資料,total和data一起拿出來進行新增到介面上了。所以,再檢視miniui的官方API發現,data後面有set、get等方法,就抱著試試看的態度,取出data使用setData方法設定資料,發現可行。既然data可以,那總數也可以,就使用setTotalCount設定總數。

        我覺得miniui的官方文件裡說的非常的不詳細,所以需要自己去了解並熟悉這些方法什麼的。

Mapper部分:

  <!--所有欄位對映-->
  <resultMap id="BaseResultMap" type="xxx.xxx.xxx.WdVisitorhistory">
    <id column="CODE" jdbcType="DECIMAL" property="code" />
    <result column="IP" jdbcType="VARCHAR" property="ip" />
    <result column="LOGIN_TIME" jdbcType="DATE" property="loginTime" />
  </resultMap>
<select id="visitorHistoryCount"  resultType="String">
    select count(*) from WD_VISITORHISTORY
</select>
<select id="findAllVisitorhistory"  resultMap="BaseResultMap" parameterType="Object">
      SELECT *
      FROM (
              SELECT r.*,ROWNUM rowno
              FROM(
                      select CODE,ip,TO_CHAR(LOGIN_TIME,'yyyy-mm-dd hh24:mi:ss')LOGIN_TIME  from WD_VISITORHISTORY
                      <choose>
                          <when test="sortField!=null and sortField!=''">
                              ORDER BY ${sortField} ${sortOrder}
                          </when>
                          <otherwise>
                              ORDER BY LOGIN_TIME desc
                          </otherwise>
                      </choose>
                      )r
               WHERE ROWNUM <= (#{pageIndex}+1)*#{pageSize}
            )
      WHERE rowno > (#{pageIndex})*#{pageSize}
  </select>

這裡需要說明的是Mybatis的排序與“$”和“#”的關係。

“ORDER BY #{sortField} #{sortOrder}”等同於“ORDER BY  'xxx' 'xxx'”

解釋:MyBatis會自動將排序欄位當成一個字串,可以通過執行,但無效,查出的內容為空。

“ORDER BY ${sortField} ${sortOrder}”等同於“ORDER BY  xxx xxx”

解釋:Mybatis會將其視作直接變數,變數替換成功後,不會再加上引號成為字串。

“#”能防止SQL注入 
“$”無法防止SQL注入

JAVA部分:

    @RequestMapping("findVisitorHistory.do")
    @ResponseBody
    public JSONArray findVisitorHistory(String pageIndex,String pageSize,String sortField,String sortOrder) {
        if("loginTime".equals(sortField)){
            sortField="LOGIN_TIME";
        }
        // 返回的Json陣列,格式為{{total:...},{data:...}}
        JSONArray jsonArray=new JSONArray();
        // 存放json陣列中的具體內容,格式為total:...}、data:...}
        JSONObject jsonObject=new JSONObject();
        //總數
        jsonObject.put("total",visitorhistoryDAO.visitorHistoryCount());
        jsonArray.add(jsonObject);
        // 清空資料總數,用於存放下面的資料
        jsonObject.clear();
        //資料
        jsonObject.put("data",
                JSONArray.fromObject(visitorhistoryDAO.findAllVisitorhistory(pageIndex,pageSize,sortField,sortOrder)));
        jsonArray.add(jsonObject);
        return jsonArray;
    }

JSP部分:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title></title>
		<!-- 公共部分 -->
		<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
		<jsp:include page="/WEB-INF/views/include/common.jsp" flush="true" />
		<link rel="stylesheet" href="${ctxStatic}/miniui/themes/default/miniui.css" />
		<link rel="stylesheet" href="${ctxStatic}/miniui/themes/icons.css" />
		<link rel="stylesheet" href="${ctxStatic}/common/css/bootstrap/bootstrap.css" />
		<link rel="stylesheet" href="${ctxStatic}/pat_view/css/pat_view.css" />
		<script src="${ctxStatic}/miniui/miniui.js"></script>
	</head>
	<body>
		<jsp:include page="../../include/head.jsp" flush="true" />
		<div id="datagrid1" class="mini-datagrid" style="width:80%;height:420px;" allowResize="true"
             sizeList="[10,30,50,100]" pageSize="10" showEmptyText="true" emptyText="未查到資料"
			 url="findVisitorHistory.do"
		>
			<div property="columns">
				<div type="indexcolumn"></div>
				<div field="code" width="120" headerAlign="center" allowSort="true">使用者code</div>
				<div field="ip" width="120" headerAlign="center" >ip</div>
                <div field="loginTime" width="100" headerAlign="center" dateFormat="yyyy-MM-dd HH:mm:ss" allowSort="true">訪問時間</div>
			</div>
		</div>

        <script type="text/javascript">
            mini.parse();
            var grid = mini.get("datagrid1");
            // 第一次載入時
            grid.load();
            // 監測每一次載入,每一次載入,載入自定義內容
            grid.on("load",function(){
                var data=grid.getData();
                console.log(data);
                grid.setTotalCount(data[0].total);
                grid.setData(data[1].data);
            })
        </script>
	</body>
</html>
JSP頁面中可以通過開發者模式檢視返回的資料格式與內容。我的場景是剛進入頁面則進行首頁的ajax查詢,之後點選下一頁還是排序等,都進行一個查詢,每次的查詢結果都按照監測的回撥函式來展示我的資料。