在项目中用到datatables比较多,但是当datatables加载超过1000多的时候就会出现有点缓慢的的样子,这个时候如果继续增加数据量让datatables去处理,那会是一个让人抓狂的事情,幸好datatables也提供了大数据量的解决办法,下面我结合我的项目,来讲讲怎么用datatables加载大数据量问题。
js代码:
struts配置:
action代码:首先要定义这么几个参数,因为你开启了datatables的服务器模式,你对datatables的每个操作,他都会想服务器发送一个请求
service层方法:由于这里是用的mybatis,我直接贴sql语句
首先看html代码:
<table id="meterDataExp" width="100%" class="display">
<thead>
<tr>
<th>宿舍信息</th>
<th>表记编码</th>
<th>上次读数</th>
<th>本次读数</th>
<th>实际用量</th>
<th>月补用量</th>
<th>缴费状态</th>
<th>抄表日期</th>
<th>手动/自动</th>
</tr>
</thead>
<tbody></tbody>
</table>
js代码:
//初始化所有用户数据
oTable = $('#meterDataExp').dataTable({
"bProcessing": true, //显示是否加载
"sScrollX": "100%",
"bJQueryUI": true,
"sScrollY": 230,
"bDestroy": true,
"iDisplayLength": 10,
//"aaSorting": [[ 2, "desc" ]],//给列表排序 ,第一个参数表示数组 。4 就是css grade那列。第二个参数为 desc或是asc
"sScrollXInner": "100%",
"sPaginationType": "full_numbers",
"sAjaxSource": "getAllMeterDataInfo.action",
"bSort": false, //关闭排序
"bServerSide": true, //打开服务器模式,这个是最重要的
"bLengthChange": false, //关闭每页显示多少条数据
"fnServerData": retrieveData, //自定义数据获取函数
"aoColumns": [{
"mDataProp": "name"
}, {
"mDataProp": "meterNo"
}, {
"mDataProp": "startedNum"
}, {
"mDataProp": "endedNum"
}, {
"mDataProp": "amount"
}, {
"mDataProp": "limitAmount"
}, {
"mDataProp": "state"
}, {
"mDataProp": "readingDate"
}, {
"mDataProp": "dataType"
}]
});
struts配置:
<action name="getAllMeterDataInfo"
class="com.daja.paymp.presentation.action.meter.MeterDataAction" method="findAllMeterData">
<result name="success" type="json"></result>
</action>
action代码:首先要定义这么几个参数,因为你开启了datatables的服务器模式,你对datatables的每个操作,他都会想服务器发送一个请求
//datatables服务器分页
private String sEcho; //包含表格的一些信息,需要不变的传回去
private String iDisplayStart; //当你点击下一页或者页数的时候会传到后台的值
private String iDisplayLength; //默认是传10
private String returnMessage; //这个是我定义的一个json 字符串 传回给datatables用来显示
private String sSearch; //这个是datatables表头上的搜索框传来的值
public String findAllMeterData() throws Exception {
//从后台获取该表总共有多少条记录
String iTotalRecords = meterPageService.getResultNum("PT0000", "").toString();
//
String iTotalDisplayRecords = "0";
//定义一个json格式的数据
JSONObject Alltempobj = JSONObject.fromObject("{}");
JSONObject tempobj = JSONObject.fromObject("{}");
JSONArray tempArray = JSONArray.fromObject("[]");
meterDataList = new ArrayList < MeterData > ();
meterDataDtoList = new ArrayList < MeterDataDTO > ();
//从前台接受搜索框里的值
if (sSearch != null && !sSearch.trim().equals("")) {
iTotalDisplayRecords = meterPageService.getResultNum("PT0000", sSearch).toString();
meterDataList = meterPageService.selectMeterDataForPage("PT0000", sSearch, iDisplayStart, iDisplayLength);
} else {
iTotalDisplayRecords = iTotalRecords;
meterDataList = meterPageService.selectMeterDataForPage("PT0000", "", iDisplayStart, iDisplayLength);
}
Alltempobj.put("aaData",
meterDataList);
Alltempobj.put("iTotalRecords", iTotalRecords);
Alltempobj.put("iTotalDisplayRecords", iTotalDisplayRecords);
Alltempobj.put("sEcho", sEcho);
returnMessage = JSONObject.fromObject(Alltempobj).toString();
return SUCCESS;
}
service层方法:由于这里是用的mybatis,我直接贴sql语句
<!-- 根据条件或者条件为空获取过滤的记录数 -->
<select id="getResultNum" resultType="map" parameterType="string">
select count(*) as resultNum from payment_log
where customer_no||meter_no||customer_name||operator like CONCAT(CONCAT('%',#{search}),'%')
order by accdate desc
</select>
<select id="selectMeterDataForPage" parameterType="map" resultType="com.daja.paymp.domain.model.meter.MeterData">
<![CDATA[
select tt."positionBuild.name",tt."positionDorm.name",tt.id,tt.meterNo,tt.customerNo,tt.readingDate,tt.startedNum,tt.endedNum,
tt.consNum,tt.limitNum,tt.state,tt.dataType from
(SELECT
PB.NAME as "positionBuild.name",
PD.NAME as "positionDorm.name",
T.ID as id,
T.METER_NO as meterNo,
T.CUSTOMER_NO as customerNo,
T.READING_DATE as readingDate,
T.STARTED_NUM as startedNum,
T.ENDED_NUM as endedNum,
T.CONS_NUM as consNum,
T.LIMIT_NUM as limitNum,
T.STATE as state,
ROWNUM as rum,
(case when T.DATA_TYPE='1' then '自动' when T.DATA_TYPE='2' then '手动' end)as dataType
FROM METER_DATAT ,METER M,PAYMENT_TYPE P,DORM_METER DM, POSITION_DORM PD,POSITION_BUILD PB
where T.METER_NO = M.NO
and M.TYPE = P.ID
and M.NO = DM.METERID
and DM.DORMID = PD.ID
and PD.BUILDID = PB.ID
and P.CODE=#{code}
and pd.name||T.METER_NO||T.READING_DATE||(case when T.DATA_TYPE='1' then '自动' when T.DATA_TYPE='2' then '手动' end)like CONCAT(CONCAT('%',#{search}),'%')
and rownum <= #{end}) tt
where tt.rum > #{start}
]]>
</select>
虽然到这里解决了大数据量,但是这个大数据量也是有上限的,现在我的数据库里有170万条数据,比起我以前一次性加载那效率是提高了很多,但是问题还是有点点,毕竟数据量还是比较大的,点下一页的响应时间大概在3秒左右(局域网),如果直接点末页再点首页,这个时间又会长点。
总的来说 如果数据超过了1000 但是有没有上万 ,那么这个解决办法已经够用了,现在要做的就是对百万级,千万级数据的优化,如果有朋友也是在犯愁,希望我们一起交流交流
原文地址:http://smotive.iteye.com/blog/1689485