Datatables结合struts2+spring+mybatis实现服务器分页,解决大数据量加载缓慢

更多datatables在http://dt.thxopen.com/ 欢迎大家来做客

在项目中用到datatables比较多,但是当datatables加载超过1000多的时候就会出现有点缓慢的的样子,这个时候如果继续增加数据量让datatables去处理,那会是一个让人抓狂的事情,幸好datatables也提供了大数据量的解决办法,下面我结合我的项目,来讲讲怎么用datatables加载大数据量问题。
首先看html代码:

  1. <table id="meterDataExp" width="100%" class="display">
  2. <thead>
  3. <tr>
  4. <th>
  5. 宿舍信息
  6. </th>
  7. <th>
  8. 表记编码
  9. </th>
  10. <th>
  11. 上次读数
  12. </th>
  13. <th>
  14. 本次读数
  15. </th>
  16. <th>
  17. 实际用量
  18. </th>
  19. <th>
  20. 月补用量
  21. </th>
  22. <th>
  23. 缴费状态
  24. </th>
  25. <th>
  26. 抄表日期
  27. </th>
  28. <th>
  29. 手动/自动
  30. </th>
  31. </tr>
  32. </thead>
  33. <tbody>
  34. </tbody>
  35. </table>
复制代码

js代码:

  1. //初始化所有用户数据
  2. oTable =$('#meterDataExp').dataTable({
  3. "bProcessing": true, //显示是否加载
  4. "sScrollX":"100%",
  5. "bJQueryUI": true,
  6. "sScrollY": 230,
  7. "bDestroy":true,
  8. "iDisplayLength":10,
  9. //"aaSorting": [[ 2, "desc" ]],//给列表排序 ,第一个参数表示数组 。4 就是css grade那列。第二个参数为 desc或是asc
  10. "sScrollXInner": "100%",
  11. "sPaginationType": "full_numbers",
  12. "sAjaxSource":"getAllMeterDataInfo.action",
  13. "bSort": false, //关闭排序
  14. <font color="#ff0000"> "bServerSide":true,//打开服务器模式,这个是最重要的</font>
  15. "bLengthChange":false, //关闭每页显示多少条数据
  16. "fnServerData":retrieveData,//自定义数据获取函数
  17. "aoColumns": [
  18. { "mDataProp": "name"},
  19. { "mDataProp": "meterNo"},
  20. { "mDataProp": "startedNum"},
  21. { "mDataProp": "endedNum" },
  22. { "mDataProp": "amount"},
  23. { "mDataProp": "limitAmount"},
  24. { "mDataProp": "state"},
  25. { "mDataProp": "readingDate"},
  26. { "mDataProp": "dataType"}
  27. ]
  28. });
复制代码

struts配置:

  1. <action name="getAllMeterDataInfo"
  2. class="com.daja.paymp.presentation.action.meter.MeterDataAction" method="findAllMeterData">
  3. <result name="success" type="json"></result>
  4. </action>
复制代码

action代码:首先要定义这么几个参数,因为你开启了datatables的服务器模式,你对datatables的每个操作,他都会想服务器发送一个请求

  1. //datatables服务器分页
  2. private String sEcho ; //包含表格的一些信息,需要不变的传回去
  3. private String iDisplayStart ; //当你点击下一页或者页数的时候会传到后台的值
  4. private String iDisplayLength ; //默认是传10
  5. private String returnMessage ; //这个是我定义的一个json 字符串 传回给datatables用来显示
  6. private String sSearch ; //这个是datatables表头上的搜索框传来的值
复制代码
  1. public String findAllMeterData() throws Exception {
  2. //从后台获取该表总共有多少条记录
  3. String iTotalRecords = meterPageService.getResultNum("PT0000","").toString();
  4. //
  5. String iTotalDisplayRecords = "0";
  6. //定义一个json格式的数据
  7. JSONObject Alltempobj =JSONObject.fromObject("{}");
  8. JSONObject tempobj = JSONObject.fromObject("{}");
  9. JSONArray tempArray = JSONArray.fromObject("[]");
  10. meterDataList = new ArrayList<MeterData>();
  11. meterDataDtoList = new ArrayList<MeterDataDTO>();
  12. //从前台接受搜索框里的值
  13. if(sSearch != null && !sSearch.trim().equals("")){
  14. iTotalDisplayRecords =meterPageService.getResultNum("PT0000",sSearch).toString();
  15. meterDataList = meterPageService.selectMeterDataForPage("PT0000",sSearch, iDisplayStart, iDisplayLength);
  16. }else{
  17. iTotalDisplayRecords = iTotalRecords;
  18. meterDataList = meterPageService.selectMeterDataForPage("PT0000","", iDisplayStart, iDisplayLength);
  19. }
  20. Alltempobj.put("aaData",
  21. meterDataList);
  22. Alltempobj.put("iTotalRecords",iTotalRecords);
  23. Alltempobj.put("iTotalDisplayRecords",iTotalDisplayRecords);
  24. Alltempobj.put("sEcho",sEcho);
  25. returnMessage = JSONObject.fromObject(Alltempobj).toString();
  26. return SUCCESS;
  27. }
复制代码

service层方法:由于这里是用的mybatis,我直接贴sql语句

  1. <!-- 根据条件或者条件为空获取过滤的记录数 -->
  2. <select id="getResultNum" resultType="map" parameterType="string">
  3. select count(*) as resultNum from payment_log
  4. where customer_no||meter_no||customer_name||operator like CONCAT(CONCAT('%',#{search}),'%')
  5. order by accdate desc
  6. </select>
复制代码
  1. <select id="selectMeterDataForPage" parameterType="map" resultType="com.daja.paymp.domain.model.meter.MeterData">
  2. <![CDATA[
  3. select tt."positionBuild.name",tt."positionDorm.name",tt.id,tt.meterNo,tt.customerNo,tt.readingDate,tt.startedNum,tt.endedNum,
  4. tt.consNum,tt.limitNum,tt.state,tt.dataType from
  5. (SELECT
  6. PB.NAME as "positionBuild.name",
  7. PD.NAME as "positionDorm.name",
  8. T.ID as id,
  9. T.METER_NO as meterNo,
  10. T.CUSTOMER_NO as customerNo,
  11. T.READING_DATE as readingDate,
  12. T.STARTED_NUM as startedNum,
  13. T.ENDED_NUM as endedNum,
  14. T.CONS_NUM as consNum,
  15. T.LIMIT_NUM as limitNum,
  16. T.STATE as state,
  17. ROWNUM as rum,
  18. (case when T.DATA_TYPE='1' then '自动' when T.DATA_TYPE='2' then '手动' end)as dataType
  19. FROM METER_DATAT ,METER M,PAYMENT_TYPE P,DORM_METER DM, POSITION_DORM PD,POSITION_BUILD PB
  20. where T.METER_NO = M.NO
  21. and M.TYPE = P.ID
  22. and M.NO = DM.METERID
  23. and DM.DORMID = PD.ID
  24. and PD.BUILDID = PB.ID
  25. and P.CODE=#{code}
  26. 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}),'%')
  27. and rownum <= #{end}) tt
  28. where tt.rum > #{start}
  29. ]]>
  30. </select>
复制代码

虽然到这里解决了大数据量,但是这个大数据量也是有上限的,现在我的数据库里有170万条数据,比起我以前一次性加载那效率是提高了很多,但是问题还是有点点,毕竟数据量还是比较大的,点下一页的响应时间大概在3秒左右(局域网),如果直接点末页再点首页,这个时间又会长点。

总的来说 如果数据超过了1000 但是有没有上万 ,那么这个解决办法已经够用了,现在要做的就是对百万级,千万级数据的优化,如果有朋友也是在犯愁,希望我们一起交流交流

 

更多datatables在http://bbs.sailit.cn 欢迎大家来做客

你可能感兴趣的:(datatables)