应用ibatis实现动态分页查询
使用ibatis实现动态分页查询一.实现分页之前可以做的:优化SQL本来的查询语句为下面的,可以进行多种优化SEL
使用ibatis实现动态分页查询
一.实现分页之前可以做的:优化SQL
本来的查询语句为下面的,可以进行多种优化
- SELECT?o.*,?r.name
- FROM?PLACED_ORDER?o,?RESTAURANT?r
- WHERE?o.RESTAURANT_ID?=?r.RESTAURANT_ID
- ??AND?o.DELIVERY_TIME?>?(SYSDATE?-?30)
- ORDER?BY?o.ORDER_EXT_ID?DESC
1.使用优化hints
- SELECT?/*+?FIRST_ROWS(20)?*/?o.*,?r.name
- FROM?PLACED_ORDER?o,?RESTAURANT?r
- WHERE?o.RESTAURANT_ID?=?r.RESTAURANT_ID
- AND?o.DELIVERY_TIME?>?(SYSDATE?-?30)
- ORDER?BY?o.ORDER_EXT_ID?DESC
????2. Denormalizing the schema
? 可以用数据的冗余来避免join表,比如把restaurant’s name放到PLACED_ORDER表中
- SELECT?o.order_id,?o.restaurant_name,?…
- FROM?PLACED_ORDER?o
- WHERE?o.DELIVERY_TIME?>?(SYSDATE?-?30)
- ORDER?BY?o.ORDER_EXT_ID?DESC
????3.?使用rownum
- SELECT?*
- FROM
- ???(SELECT?ROWNUM?AS?RN,?XX.*
- ????FROM
- ???(SELECT?O.ORDER_ID,?R.NAME,?…
- ??????FROM?PLACED_ORDER?O,?RESTAURANT?R
- ??????WHERE?O.RESTAURANT_ID?=?R.RESTAURANT_ID
- ??????ORDER?BY?O.ORDER_EXT_ID
- ???)?XX
- ???WHERE?ROWNUM?<?21)
- WHERE?RN?>?10
- public?class?OrderDAOIBatisImpl?extends?SqlMapClientDaoSupport?implements?OrderDAO?{
- ????public?PagedQueryResult?findOrders(int?startingIndex,
- ????????????int?pageSize,?OrderSearchCriteria?criteria)?{
- ????????Map?map?=?new?HashMap();
- ????????map.put("pageSize",
- ????????????????new?Integer(pageSize?+?startingIndex?+?1));
- ????????map.put("criteria",?criteria);
- ????????Implementing?dynamic?paged?queries?with?iBATIS?421
- ????????List?result?=?getSqlMapClientTemplate().queryForList(
- ????????????????"findOrders",?map,?startingIndex,?pageSize);
- ????????boolean?more?=?result.size()?>?pageSize;
- ????????if?(more)?{
- ????????????result.remove(pageSize);
- ????????}
- ????????return?new?PagedQueryResult(result,?more);
- ????}
Ibatis的配置:
- <sqlMap>
- ????…
- ????<select?id="findOrders"?resultMap="OrderResultMap"
- ????????resultSetType="SCROLL_INSENSITIVE">
- ????????SELECT?/*+?FIRST_ROWS($pageSize$)?*/?O.ORDER_ID,?R.NAME?AS
- ????????RESTAURANT_NAME?FROM?FTGO_ORDER?O,?FTGO_RESTAURANT?R?WHERE
- ????????O.RESTAURANT_ID?=?R.RESTAURANT_ID
- ????????<isNotEmpty?property="criteria.restaurantName">
- ????????????AND?r.name?=?#criteria.restaurantName#
- ????????</isNotEmpty>
- ????????<isNotEmpty?property="criteria.deliveryCity">
- ????????????AND?o.delivery_city?=?#criteria.deliveryCity#
- ????????</isNotEmpty>
- ????????<isNotEmpty?property="criteria.state">
- ????????????AND?o.status?=?#criteria.state#
- ????????</isNotEmpty>
- ????????ORDER?BY?o.ORDER_ID?ASC
- ????</select>
- ????<resultMap?id="OrderResultMap"
- ????????class="net.chrisrichardson.foodToGo.
- ????????????bbbbbbbbbbb??placeOrderTransactionScripts.details.
- ????????????bbbbbbbbbb??OrderSummaryDTO">
- ????????<result?property="orderId"?column="ORDER_ID"?/>
- ????????<result?property="restaurantName"?column="RESTAURANT_NAME"?/>
- ????????…
- ????</resultMap>
- ????…
- </sqlMap>
2.使用rownum
?
java代码:
- public?PagedQueryResult?findOrders?(int?startingIndex,
- ????????int?pageSize,?OrderSearchCriteria?criteria)?{
- ????Map?map?=?new?HashMap();
- ????map.put("startingIndex",?new?Integer(startingIndex));
- ????map.put("maxRows",?new?Integer(pageSize?+?startingIndex
- ????????????+?2));
- ????map.put("criteria",?criteria);
- ????List?result?=?getSqlMapClientTemplate().queryForList(
- ????????????Implementing?dynamic?paged?queries?with?iBATIS?423
- ????????????"findOrders",?map);
- ????boolean?more?=?result.size()?>?pageSize;
- ????if?(more)?{
- ????????result.remove(pageSize);
- ????}
- ????return?new?PagedQueryResult(result,?more);
- }
?
Ibatis配置: 注意:只有start大于0,才会编译某些段
?
- <sqlMap>
- ????<select?id="findOrders"?resultMap="OrderResultMap"
- ????????resultSetType="SCROLL_INSENSITIVE">
- ????????<isGreaterThan?property="?startingIndex"?compareValue="0">
- ????????????SELECT?*?FROM?(SELECT?XX.*,?ROWNUM?RNXX?FROM?(
- ????????</isGreaterThan>
- ????????SELECT?*?FROM?(?SELECT?O.ORDER_ID,?R.NAME?AS?RESTAURANT_NAME
- ????????FROM?FTGO_ORDER?O,?FTGO_RESTAURANT?R?WHERE?O.RESTAURANT_ID?=
- ????????R.RESTAURANT_ID
- ????????<isNotEmpty?property="criteria.restaurantName">
- ????????????AND?r.name?=?#criteria.restaurantName#
- ????????</isNotEmpty>
- ????????<isNotEmpty?property="criteria.deliveryCity">
- ????????????AND?o.delivery_city?=?#criteria.deliveryCity#
- ????????</isNotEmpty>
- ????????<isNotEmpty?property="criteria.state">
- ????????????AND?o.status?=?#criteria.state#
- ????????</isNotEmpty>
- ????????ORDER?BY?o.ORDER_ID?ASC?)?WHERE?ROWNUM?<?#maxRows#
- ????????<isGreaterThan?property="start"?compareValue="0">
- ????????????)?XX?)?WHERE?RNXX?>?#startingIndex#
- ????????</isGreaterThan>
- ????</select>
- ????…
- </sqlMap>
- PaginatedList?paginatedList=sqlMap.queryForPaginatedList(statementName,?parameterObject,?pageSize);???
这个是基于内存的分页,就是已经把所有数据load到内存了,才实现的伪分页。不会减少load的负荷。
?
?五。补充
? 有人自己hack了ibatis的分页api,然后实现物理的分页,一般不提倡。
?
【参考】
1. 《POJO in action》 Implementing dynamic paged queries
2. yangtingkun ,http://yangtingkun.itpub.net/post/468/100278?,Oracle分页查询语句
?
3. IBATIS document