一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页
????????? mybatis 分頁(yè)詳解、mybatis分頁(yè)查詢,mybatis分頁(yè)攔截器使用、struts2下mybatis分頁(yè)
?
mybatis默認(rèn)是支持分頁(yè)的,內(nèi)部通過(guò)創(chuàng)建可滾動(dòng)的ResultSet(ResultSet.TYPE_FORWARD_ONLY)對(duì)結(jié)果集指針進(jìn)行跳轉(zhuǎn)以達(dá)到分頁(yè)控制的目的。實(shí)際使用,需要傳入RowBounds類型參數(shù)來(lái)告知mybatis做分頁(yè)控制,RowBounds構(gòu)造器有兩個(gè)參數(shù):
RowBounds(int offset, int limit), offset,從第offset條開(kāi)始查(起始于0),limit查詢個(gè)數(shù)。如:
RowBounds(0, 11):第一頁(yè),顯示十一條【0-10】、
RowBounds(11, 10):第二頁(yè),顯示十一條【11-21】
。。。。
不過(guò)mybatis默認(rèn)分頁(yè)存在兩個(gè)問(wèn)題:1.通過(guò)ResultSet控制指針進(jìn)行分頁(yè)與數(shù)據(jù)庫(kù)本身通過(guò)sql語(yǔ)句進(jìn)行分頁(yè)相比,查詢性能欠佳。2.無(wú)法返回總記錄數(shù),通常情況下前端表格除了要顯示第n頁(yè)數(shù)據(jù),也需要顯示總記錄數(shù),通過(guò)內(nèi)置RowBounds顯然不能滿足需求。
有些兄弟可能不知道怎么使用,沒(méi)關(guān)系,我先做一個(gè)簡(jiǎn)單的示例,供參考。
問(wèn)題:現(xiàn)有區(qū)號(hào)表一張,需要支持表分頁(yè)查詢:
1.定義區(qū)號(hào)javabean AreaCode.java:
AreaCode.java
public class AreaCode implements Serializable{//javabean與數(shù)據(jù)庫(kù)字段一致private String provId;private String description;public AreaCode() {super();}public String getProvId() {return provId;}public void setProvId(String provId) {this.provId = provId;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}}2.定義mapper接口AreaCodeMapper.java(為了簡(jiǎn)單只定義一個(gè)查詢接口):
public interface AreaCodeMapper {//這個(gè)方法不支持分頁(yè),是全查public List<AreaCode> list();//通過(guò)RowBounds參數(shù)告知mybatis此方法需要分頁(yè)查詢public List<AreaCode> list(RowBounds rowBounds);}3.定義配置文件AreaCodeMapper.xml(配置僅供參考):
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="AreaCodeMapper"><select id="list" resultType="AreaCode">select provId, description from areacodecfg</select> </mapper>4.定義配置文件configuration.xml(配置僅供參考):
<?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><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="UNPOOLED"><!-- ${driver}為實(shí)際的數(shù)據(jù)庫(kù)驅(qū)動(dòng)名 --><property name="driver" value="${driver}" /><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment></environments><mappers><!-- 添加mapper文件 --><mapper resource="AreaCodeMapper.xml" /></mappers> </configuration>5.測(cè)試:
public static void main(String[] args) throws SQLException {Reader reader = null;SqlSessionFactory sf;SqlSession session = null;try {SqlSessionFactoryBuilder build = new SqlSessionFactoryBuilder();//根據(jù)配置文件生成SqlSessionFactoryreader = Resources.getResourceAsReader("test/configuration.xml");sf = build.build(reader);session = sf.openSession();AreaCodeMapper mapper = session.getMapper(AreaCodeMapper.class);//查詢第一頁(yè),每頁(yè)十條記錄RowBounds rowBounds = new RowBounds(0, 10);List<AreaCode> list = mapper.list(rowBounds);} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e) {}}if (session != null) {session.close();}}}分頁(yè)查詢已搞定,但以上查詢并不包含總記錄數(shù),這個(gè)比較麻煩,如果你愿意,再添加一個(gè)總記錄數(shù)查詢的接口,不愿意接著往下看。
下面通過(guò)擴(kuò)展RowBounds,使其支持?jǐn)?shù)據(jù)庫(kù)分頁(yè)與總記錄數(shù)統(tǒng)計(jì)。
1.由于不同的數(shù)據(jù)庫(kù),分頁(yè)sql語(yǔ)句略有不同,我們通過(guò)一個(gè)枚舉類型DBType.java,用于區(qū)分不同數(shù)據(jù)庫(kù)類型。假設(shè)只支持mysql和oracle兩種數(shù)據(jù)庫(kù),要添加其他數(shù)據(jù)庫(kù),自己擴(kuò)展:
public enum DBType {MYSQL, ORACLE }2.創(chuàng)建用于sql轉(zhuǎn)換的接口IDialect.java。接口功能:可將普通查詢sql,轉(zhuǎn)換成與具體數(shù)據(jù)庫(kù)相關(guān)的分頁(yè)查詢sql,IDialect.java:
public interface IDialect {//支持根據(jù)字段進(jìn)行排序查詢,留給讀者實(shí)現(xiàn)吧String getSortSQL(String sql, List<String> sortFields, List<String> sortOrders);//根據(jù)原始查詢sql生成與數(shù)據(jù)庫(kù)相關(guān)的查詢sql//原始sql就是上文提到的:select provId, description from areacodecfgString getLimitSQL(String sql, int offset, int limit);//根據(jù)原始的sql生成查詢總記錄數(shù)的sqlString getTotalSQL(String sql); }3.定義IDialect的抽象實(shí)現(xiàn)ADialect.java:
?
public abstract class ADialect implements IDialect {@Overridepublic String getTotalSQL(String sql) {//基本所有數(shù)據(jù)庫(kù)通用StringBuffer totalSql = new StringBuffer(sql.length() + 100);totalSql.append("select count(0) from ( ").append(sql).append(" ) as _tmp_count");return totalSql.toString();} }4.定義mysql的實(shí)現(xiàn):
public class MySqlDialect extends ADialect {@Overridepublic String getLimitSQL(String sql, int offset, int limit) {sql = sql.trim();StringBuffer newSql = new StringBuffer(sql.length() + 100);newSql.append("select * from (").append(sql).append(") as _tmp_query limit ").append(offset).append(",").append(limit);return newSql.toString();} }5.定義oracle的實(shí)現(xiàn):
public class OracleDialect extends ADialect {@Overridepublic String getLimitSQL(String sql, int offset, int limit) {sql = sql.trim();StringBuffer pageSelect = new StringBuffer(sql.length() + 100);pageSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");pageSelect.append(sql);pageSelect.append(" ) row_ ) where rownum_ > ").append(offset).append(" and rownum_ <= ").append(offset + limit);return pageSelect.toString();} }5.創(chuàng)建IDialect的實(shí)例化工廠RoutingDialect.java:
public class RoutingDialect implements IDialect {//實(shí)際委托給delegateprivate IDialect delegate;//用于緩存實(shí)例private static Map<DBType, IDialect> dialectMap = new HashMap<DBType, IDialect>();private RoutingDialect(DBType dbType) {switch (dbType) {case MYSQL:delegate = new MySqlDialect();break;case ORACLE:delegate = new OracleDialect();break;default:delegate = new MySqlDialect();}}//工廠方法,根據(jù)數(shù)據(jù)庫(kù)類型返回相應(yīng)的Dialectpublic static IDialect getDialect(DBType dbType) {IDialect dialect = null;dialect = dialectMap.get(dbType);if (dialect == null) {synchronized (dialectMap) {dialect = dialectMap.get(dbType);if (dialect == null) {dialect = new RoutingDialect(dbType);dialectMap.put(dbType, dialect);}}}return dialect;}@Overridepublic String getLimitSQL(String sql, int offset, int limit) {return delegate.getLimitSQL(sql, offset, limit);}@Overridepublic String getTotalSQL(String sql) {return delegate.getTotalSQL(sql);}}6.創(chuàng)建SmartRowBounds擴(kuò)展自RowBounds,支持?jǐn)?shù)據(jù)庫(kù)分頁(yè),與總記錄數(shù)統(tǒng)計(jì):
public class SmartRowBounds extends RowBounds {//內(nèi)部參數(shù):當(dāng)前查詢記錄的偏移private int queryOffset = -1;//內(nèi)部參數(shù):當(dāng)前查詢記錄的條數(shù)private int queryLimit = -1;//內(nèi)部參數(shù):用于保存總記錄數(shù)private int totalCount;//是否使用數(shù)據(jù)庫(kù)分頁(yè),還是使用mybatis的默認(rèn)滾動(dòng)分頁(yè)private boolean isDbSupport = false;//內(nèi)部標(biāo)識(shí),是否阻止默認(rèn)分頁(yè),當(dāng)isDbSupport=true時(shí)此標(biāo)識(shí)必須設(shè)成trueprivate boolean preventDefaultRowBounds = false;public SmartRowBounds() {//無(wú)分頁(yè)參數(shù),不分頁(yè)super(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);}public SmartRowBounds(int queryOffset, int queryLimit) {//將分頁(yè)參數(shù)傳遞給父類,這一點(diǎn)很重要,可用于默認(rèn)分頁(yè)super(queryOffset, queryLimit);this.queryOffset = queryOffset;this.queryLimit = queryLimit;}public SmartRowBounds(int queryOffset, int queryLimit,boolean isDbSupport) {this(queryOffset, queryLimit);this.isDbSupport = isDbSupport;}//根據(jù)數(shù)據(jù)庫(kù)類型,即原始的查詢sql來(lái)生成數(shù)據(jù)庫(kù)相關(guān)的分頁(yè)sql,//委托IDialect進(jìn)行轉(zhuǎn)換public String getPageSql(DBType dbType, String rawSql) {IDialect dialet = RoutingDialect.getDialect(dbType);//只有使用數(shù)據(jù)庫(kù)分頁(yè)的情況下才會(huì)對(duì)sql進(jìn)行數(shù)據(jù)庫(kù)相關(guān)的轉(zhuǎn)換if (isDbSupport && queryOffset >= 0 && queryLimit >= 0) {rawSql = dialet.getLimitSQL(rawSql, queryOffset, queryLimit);//如果使用了數(shù)據(jù)庫(kù)分頁(yè),就必須阻止mybatis默認(rèn)分頁(yè)行為。//設(shè)置一個(gè)阻止默認(rèn)分頁(yè)的標(biāo)識(shí)preventDefaultRowBounds=tuepreventDefaultRowBounds = true;}return rawSql;}public String getTotalSQL(DBType dbType, String rawSql) {return RoutingDialect.getDialect(dbType).getTotalSQL(rawSql);}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public int getTotalCount() {return totalCount;}@Overridepublic int getLimit() {//mysql會(huì)調(diào)用RowBounds的getLimit方法計(jì)算查詢記錄條數(shù),//如果未使用數(shù)據(jù)庫(kù)分頁(yè),你需要告訴mybatis查詢的記錄長(zhǎng)度queryLimitif (!preventDefaultRowBounds) {return queryLimit;}//如果你使用了數(shù)據(jù)庫(kù)分頁(yè),那么mybatis內(nèi)部就不能再使用ResultSet滾動(dòng)分頁(yè)了//因此需要返回super.NO_ROW_LIMIT,告知mybatis不進(jìn)行分頁(yè)相關(guān)的結(jié)果集指針跳轉(zhuǎn)return super.NO_ROW_LIMIT;}@Overridepublic int getOffset() {//mysql會(huì)調(diào)用RowBounds的getOffset方法計(jì)算查詢偏移,if (!preventDefaultRowBounds) {return queryOffset;}//如果默認(rèn)使用了數(shù)據(jù)庫(kù)分頁(yè),那么mybatis內(nèi)部就不能再使用ResultSet滾動(dòng)分頁(yè)了//因此返回NO_ROW_OFFSETreturn super.NO_ROW_OFFSET;}public void reset() {totalCount = 0;preventDefaultRowBounds = false;}}7.創(chuàng)建mybatis分頁(yè)攔截器類:
//注意注解,這里只對(duì)Connection創(chuàng)建的的preparedStatement進(jìn)行攔截,固定寫(xiě)法,可以不深究 @Intercepts( { @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) }) public class PageStatementInterceptor implements Interceptor {private DBType dbType;public void setDBType(String dbTypeStr) {if (dbTypeStr != null && !"".equals(dbTypeStr.trim())) {try {this.dbType = DBType.valueOf(dbTypeStr.trim().toUpperCase());} catch (Exception e) {this.dbType = DBType.MYSQL;}}}//mybatis框架自動(dòng)調(diào)用@Overridepublic void setProperties(Properties properties) {setDBType(properties.getProperty("DBType"));}@Overridepublic Object intercept(Invocation invocation) throws Throwable {try {StatementHandler statementHandler = (StatementHandler) invocation.getTarget();StatementHandler deleStatementHandler = (StatementHandler) getFieldValue(statementHandler, "delegate");RowBounds rowBounds = (RowBounds) getFieldValue(deleStatementHandler, "rowBounds");MappedStatement mappedStatement = (MappedStatement)getFieldValue(deleStatementHandler, "mappedStatement");//只針對(duì)select類型切分頁(yè)參數(shù)是SmartRowBounds的查詢進(jìn)行sql改造if (rowBounds != null && mappedStatement != null && SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType()) && SmartRowBounds.class.isAssignableFrom(rowBounds.getClass())) {SmartRowBounds pageHandler = (SmartRowBounds) rowBounds;//獲取原始sqlBoundSql boundSql = statementHandler.getBoundSql();if (boundSql != null) {//進(jìn)行總記錄數(shù)查詢countTotal(pageHandler, (Connection) invocation.getArgs()[0], statementHandler.getParameterHandler(), boundSql.getSql());//將原始sql替換為支持分頁(yè)的sqlsetFieldValue(boundSql, "sql", pageHandler.getPageSql(dbType, boundSql.getSql()));}}} catch (Exception e) {e.printStackTrace();}return invocation.proceed();}private Field getField(Object target, String fieldName) {Field field = null;for (Class<?> clazz = target.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {try {field = clazz.getDeclaredField(fieldName);break;} catch (NoSuchFieldException e) {// ignore}}if (field != null) {if (!field.isAccessible()) {try {field.setAccessible(true);} catch (Exception e) {// ignore}}}return field;}private Object getFieldValue(Object target, String fieldName) {try {Field field = getField(target, fieldName);if (field != null) {return field.get(target);}} catch (Exception e) {e.printStackTrace();}return null;}private void setFieldValue(Object target, String fieldName, Object value) {try {Field field = getField(target, fieldName);if (field != null) {field.set(target, value);}} catch (Exception e) {e.printStackTrace();}}private void countTotal(SmartRowBounds pageHandler, Connection con, ParameterHandler paramHandler, String rawSql) {ResultSet rs = null;PreparedStatement stmt = null;try {String totalSql = pageHandler.getTotalSQL(dbType, rawSql);if (totalSql != null && !totalSql.isEmpty()) {stmt = con.prepareStatement(totalSql);paramHandler.setParameters(stmt);rs = stmt.executeQuery();if (rs.next()) {pageHandler.setTotalCount(rs.getInt(1));}}} catch (SQLException e) {e.printStackTrace();} finally {try {if (rs != null) {rs.close();}} catch (SQLException e1) {// ignore}try {if (stmt != null) {stmt.close();}} catch (Exception e) {// ignore}}}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}}8.configuration.xml添加攔截器配置:
<plugins><plugin interceptor="PageStatementInterceptor"><property name="DBType" value="mysql" /></plugin></plugins>9.測(cè)試:
public class Test {public static void main(String[] args) throws SQLException {Reader reader = null;SqlSessionFactory sf;SqlSession session = null;try {SqlSessionFactoryBuilder build = new SqlSessionFactoryBuilder();reader = Resources.getResourceAsReader("test/configuration.xml");sf = build.build(reader);session = sf.openSession();AreaCodeMapper mapper = session.getMapper(AreaCodeMapper.class);SmartRowBounds rowBounds = new SmartRowBounds(0, 10, true);//分頁(yè)記錄與記錄總數(shù),使用一次接口調(diào)用搞定List<AreaCode> list = mapper.list(rowBounds);int total = rowBounds.getTotalCount();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e) {}}if (session != null) {session.close();}}} }以上介紹了攔截器分頁(yè)的基本用法,下面簡(jiǎn)單介紹下,如果配合struts, spring進(jìn)行分頁(yè)查詢
1.創(chuàng)建業(yè)務(wù)類AreaCodeService.java,正常情況下應(yīng)該創(chuàng)建業(yè)務(wù)接口再創(chuàng)建實(shí)現(xiàn)類,為了簡(jiǎn)單起見(jiàn),跳過(guò)接口創(chuàng)建:
@Service public class AreaCodeService {//通過(guò)spring進(jìn)行自動(dòng)注入@Resourceprivate AreaCodeMapper mapper;public List<AreaCode> listAreaCode(RowBounds rowBounds) {//方法1return mapper.list(rowBounds));}public List<AreaCode> listAreaCode(int offset, int limit) {//方法2//直接創(chuàng)建SmartRowBounds//但是總記錄數(shù)如何傳遞出去?return mapper.list(new SmartRowBounds(offset, limit));} }AreaCodeService很簡(jiǎn)單,基本就是委托mapper查詢,唯一需要做的就是實(shí)例化RowBounds交給mapper。
上面代碼定義了兩個(gè)用于分頁(yè)查詢的方法,方法1:通過(guò)傳入RowBounds類型參數(shù),實(shí)現(xiàn)分頁(yè)控制,好處是簡(jiǎn)單,實(shí)際的rowbounds對(duì)象的創(chuàng)建代碼放到調(diào)用者(一般是structs的控制器對(duì)象)中,缺點(diǎn)是AreaCodeService與mybatis耦合太緊,如果以后使用其他orm框架如hibernate,那就需要修改service類。方法2:方法獨(dú)立性比較好,不與任何特定框架耦合,它只關(guān)心查詢偏移,與返回記錄數(shù),但問(wèn)題是,方法的返回類型是List<AreaCode>, 如何將SmartRowBounds的總記錄數(shù)返回給調(diào)用者對(duì)象?先不說(shuō),后面再談!
2.創(chuàng)建Struts控制器的抽象Action, AbstractAction.java:
public class AbstractAction extends ActionSupport{public static final String JSON = "json";//querOffset與queryLimit是通過(guò)前臺(tái)jsp傳過(guò)來(lái)的分頁(yè)相關(guān)參數(shù)//其實(shí)可以將這兩個(gè)參數(shù)封裝成Page對(duì)象,通過(guò)Page對(duì)象來(lái)取queryOffset與queryLimit//這里這樣操作是為了偷懶,展示用protected int queryOffset = -1;protected int queryLimit = -1;//前臺(tái)頁(yè)表格加載需要的數(shù)據(jù)對(duì)象protected Object gridDataList;//將分頁(yè)的查詢的結(jié)果存放到gridDataList//最終通過(guò)struts.xml配置文件將gridDataList轉(zhuǎn)換為json傳到前臺(tái)jsp//list為查詢的結(jié)果, total為總記錄數(shù)protected void setJsonGrid(List list, int total) {Map data = new HashMap();data.put("total", total);data.put("rows", list);this.gridDataList = data;}public int getQueryOffset() {return queryOffset;}public void setQueryOffset(int queryOffset) {this.queryOffset = queryOffset;}public int getGridDataList() {return gridDataList;}public void setGridDataList(Object gridDataList) {this.gridDataList= gridDataList;}public int getQueryLimit() {return queryLimit;}public void setQueryLimit(int queryLimit) {this.queryLimit = queryLimit;} }抽象action繼承自Struts的ActionSupport,方法功能看注釋,不廢話了。
2.創(chuàng)建具體控制器AreaCodeAction.java:
public class AreaCodeAction extends AbstractAction{//通過(guò)spring將AreaCodeService注入進(jìn)來(lái)@Resourceprivate AreaCodeService service;public String gridList() {SmartRowBounds rb = new SmartRowBounds(queryOffset, queryLimit, true);List<AreaCode> list = service.listAreaCode(rb);//使用AreaCodeService的方法1setJsonGrid(list, rb.getTotalCount());return JSON;} }只有一個(gè)gridList ()方法,通過(guò)前臺(tái)頁(yè)面?zhèn)鬟M(jìn)來(lái)的分頁(yè)參數(shù)創(chuàng)建SmartRowBounds交給service進(jìn)行分頁(yè)查詢,查詢完了會(huì)通過(guò)rb回取總記錄數(shù),一起交給父類的setJsonGrid()方法。
上文提到的,將控制器屬性gridDataList轉(zhuǎn)化為json對(duì)象傳到前臺(tái)jsp,需要在struct.xml中加一段配置,內(nèi)容片段如下:
<global-results><result name="json" type="json"><param name="root">gridDataList</param></result> </global-results>spring中mybatis攔截器配置片段:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="xx" /><property name="plugins"><array><!--攔截器類全稱--><bean class="PageStatementInterceptor"></bean></array></property> </bean>自此所有內(nèi)容已敘完,最后繼續(xù)探討下前面的遺留問(wèn)題,AreaCodeService的方法2,
如何將查詢總數(shù)返回到控制器?
其實(shí)至少有兩個(gè)方法:
1.List<AreaCode> listAreaCode(int offset, int limit)再增加第三個(gè)參數(shù),然后將SmartRowBounds的記錄總數(shù)放到第三個(gè)參數(shù)中,供控制器取,以下是模擬實(shí)現(xiàn):
public List<AreaCode> listAreaCode(int offset, int limit, ResultHook hook) {//方法2SmartRowBounds rb = new SmartRowBounds(offset, limit);try {return mapper.list(new SmartRowBounds(offset, limit,true));} catch (Exception e) {e.printStackTrace();} finally {//將記錄總數(shù)傳給hook,通知到控制器去取hook.setResult(rb.getTotalCount());}} }?2.借助線程本地上下文ThreadLocal,同一個(gè)線程總能共享相同的數(shù)據(jù)對(duì)象,創(chuàng)建RowBoundsHolder對(duì)象:
public class RowBoundsHolder {private static ThreadLocal<SmartRowBounds> rowBoundHolder = new ThreadLocal<SmartRowBounds>();public static SmartRowBoundsinstance(int offset, int limit) {SmartRowBounds rb = new SmartRowBounds(offset, limit);rowBoundHolder.set(rb);return rb;}public static SmartRowBounds instance(int offset, int limit, boolean supportDbPage) {SmartRowBounds rb = new SmartRowBounds(offset, limit, supportDbPage);rowBoundHolder.set(rb);return rb;}public static SmartRowBoundsget() {return rowBoundHolder.get();} }?RowBoundsHolder的instance方法創(chuàng)建一個(gè)SmartRowBounds rb并設(shè)置到線程本地山下文中,在同一個(gè)線程中,調(diào)用任意對(duì)象的任意方法,總能訪問(wèn)此rb對(duì)象的引用。
改造AreaCodeService的方法2:
@Service public class AreaCodeService {//通過(guò)spring進(jìn)行自動(dòng)注入@Resourceprivate AreaCodeMapper mapper;public List<AreaCode> listAreaCode(int offset, int limit) {//方法2return mapper.list(RowBoundsHolder.instance(offset, limit, true));} }?改造AbstractAction添加新方法:
protected void setJsonGrid(List list) {int total = list == null ? 0 : list.size();SmartRowBounds rb = RowBoundsHolder.get();if (rb != null) {//通線程上下文獲取總記錄數(shù)total = rb.getTotalCount();}Map data = new HashMap();data.put("total", total);data.put("rows", list);this.gridDataList = data;}修改AreaCodeAction.java:
public class AreaCodeAction extends AbstractAction{//通過(guò)spring將AreaCodeService注入進(jìn)來(lái)@Resourceprivate AreaCodeService service;public String gridList() {List<AreaCode> list = service.listAreaCode(queryOffset, queryLimit);//使用AreaCodeService的方法2setJsonGrid(list);return JSON;} }?All right,如果你覺(jué)得有“點(diǎn)”幫助,請(qǐng)點(diǎn)個(gè)“贊”哦,3q。
以上實(shí)現(xiàn)僅供參考,思路各異,滿意就行。
原創(chuàng)博文,轉(zhuǎn)載請(qǐng)注明出處。
總結(jié)
以上是生活随笔為你收集整理的一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql 创建外键约束以及注意事项
- 下一篇: js中颜色的判断和颜色表