mybatis有两种分页方法(转自:http://blog.csdn.net/leozhou13/article/details/50394242)

1、内存分页,也就是假分页。本质是查出所有的数据然后根据游标的方式,截取需要的记录。如果数据量大,开销大和内存溢出。

使用方式:

利用自动生成的example类,加入mybatis的RowBounds类,在调用的接口中添加给类的参数

  1. @Override
  2. public List<UserVo> selectSelective(UserVo userVo) {
  3. List<UserVo> listVo = new ArrayList<UserVo>();
  4. UserPoExample example = new UserPoExample();
  5. /**
  6. * 使用mybatis的RowBounds类,该类构造方法中要设置两个int类型参数
  7. * 第一个是从该条记录开始,第二个是开始后查询的条数
  8. */
  9. <strong>RowBounds rowBounds = new RowBounds(0, 5);</strong>
  10. Criteria criteria = example.createCriteria();
  11. criteria.andUsernameEqualTo("123");
  12. criteria.andRoleEqualTo(userVo.getRole());
  13. example.setOrderByClause("userId desc");//设置排序方式
  14. example.setStart(10);
  15. example.setLimit(10);
  16. UserPo userPo = new UserPo();
  17. userPo.setUsername("123");
  18. userPo.setRole(1);
  19. Page<UserVo> page = new Page<UserVo>();
  20. List<UserPo> listPo =null;
  21. try {
  22. //int countByExample = userPoMapper.countByExample(example);//按照条件查询总数
  23. //listPo = userPoMapper.selectBySelective(userPo,page);
  24. listPo = userPoMapper.selectByExample(example,<strong>rowBounds</strong>);
  25. for(UserPo po:listPo){
  26. UserVo vo = new UserVo();
  27. BeanUtils.copyProperties(po, vo);
  28. listVo.add(vo);
  29. }
  30. } catch (Exception e) {
  31. logger.error(e);
  32. }
  33. return listVo;
  34. }

第二中是,真正的物理分页

在自动生成的example对象中,加入两个成员变量start、和limit

  1. public class UserPoExample {
  2. <strong>private int start;//设置分页开始
  3. private int limit;//设置分页的每页的数量</strong>
  4. public int getStart() {
  5. return start;
  6. }
  7. public void setStart(int start) {
  8. this.start = start;
  9. }
  10. public int getLimit() {
  11. return limit;
  12. }
  13. public void setLimit(int limit) {
  14. this.limit = limit;
  15. }

最后在对应的xml的方法中添加刚刚加入的条件,直接添加在自动生成的orderByClause后面

  1. <if test="orderByClause != null" >
  2. order by ${orderByClause}
  3. </if>
  4. <strong><if test="start !=0 or limit!=0">
  5. limit #{start},#{limit}</if><span style="font-family: Arial, Helvetica, sans-serif;">  </span></strong>

通过日志可以看到是真正的分页查询

还有一种是使用分页拦截器实现的

首先在spring-dao的sqlsession工厂里面配置拦截器

  1. <!-- sqlSessionFactory -->
  2. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  3. <!-- 数据库连接池 -->
  4. <property name="dataSource" ref="dataSource" />
  5. <!-- 批量扫描别名 -->
  6. <property name="typeAliasesPackage" value="ssm.po" />
  7. <!-- spring与mybatis整合不需要mybatis配置文件了,直接扫描mapper下的映射文件 -->
  8. <property name="mapperLocations" value="classpath:ssm/mapper/*.xml" />
  9. <!-- MybatisSpringPageInterceptor分页拦截器 -->
  10. <property name="plugins">
  11. <bean class="ssm.utils.MybatisSpringPageInterceptor"></bean>
  12. </property>
  13. </bean>

拦截器代码:

  1. package ssm.utils;
  2. import java.lang.reflect.Field;
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Properties;
  10. import org.apache.ibatis.executor.Executor;
  11. import org.apache.ibatis.executor.parameter.ParameterHandler;
  12. import org.apache.ibatis.executor.statement.RoutingStatementHandler;
  13. import org.apache.ibatis.executor.statement.StatementHandler;
  14. import org.apache.ibatis.mapping.BoundSql;
  15. import org.apache.ibatis.mapping.MappedStatement;
  16. import org.apache.ibatis.mapping.ParameterMapping;
  17. import org.apache.ibatis.plugin.Interceptor;
  18. import org.apache.ibatis.plugin.Intercepts;
  19. import org.apache.ibatis.plugin.Invocation;
  20. import org.apache.ibatis.plugin.Plugin;
  21. import org.apache.ibatis.plugin.Signature;
  22. import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
  23. import org.apache.ibatis.session.ResultHandler;
  24. import org.apache.ibatis.session.RowBounds;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. @Intercepts({ @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }),
  28. @Signature(method = "query", type = Executor.class, args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
  29. public class MybatisSpringPageInterceptor implements Interceptor {
  30. private static final Logger log = LoggerFactory.getLogger(MybatisSpringPageInterceptor.class);
  31. public static final String MYSQL = "mysql";
  32. public static final String ORACLE = "oracle";
  33. protected String databaseType;// 数据库类型,不同的数据库有不同的分页方法
  34. @SuppressWarnings("rawtypes")
  35. protected ThreadLocal<Page> pageThreadLocal = new ThreadLocal<Page>();
  36. public String getDatabaseType() {
  37. return databaseType;
  38. }
  39. public void setDatabaseType(String databaseType) {
  40. if (!databaseType.equalsIgnoreCase(MYSQL) && !databaseType.equalsIgnoreCase(ORACLE)) {
  41. throw new PageNotSupportException("Page not support for the type of database, database type [" + databaseType + "]");
  42. }
  43. this.databaseType = databaseType;
  44. }
  45. @Override
  46. public Object plugin(Object target) {
  47. return Plugin.wrap(target, this);
  48. }
  49. @Override
  50. public void setProperties(Properties properties) {
  51. String databaseType = properties.getProperty("databaseType");
  52. if (databaseType != null) {
  53. setDatabaseType(databaseType);
  54. }
  55. }
  56. @Override
  57. @SuppressWarnings({ "unchecked", "rawtypes" })
  58. public Object intercept(Invocation invocation) throws Throwable {
  59. if (invocation.getTarget() instanceof StatementHandler) { // 控制SQL和查询总数的地方
  60. Page page = pageThreadLocal.get();
  61. if (page == null) { //不是分页查询
  62. return invocation.proceed();
  63. }
  64. RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
  65. StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
  66. BoundSql boundSql = delegate.getBoundSql();
  67. Connection connection = (Connection) invocation.getArgs()[0];
  68. prepareAndCheckDatabaseType(connection); // 准备数据库类型
  69. if (page.getTotalPage() > -1) {
  70. if (log.isTraceEnabled()) {
  71. log.trace("已经设置了总页数, 不需要再查询总数.");
  72. }
  73. } else {
  74. Object parameterObj = boundSql.getParameterObject();
  75. MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
  76. queryTotalRecord(page, parameterObj, mappedStatement, connection);
  77. }
  78. String sql = boundSql.getSql();
  79. String pageSql = buildPageSql(page, sql);
  80. if (log.isDebugEnabled()) {
  81. log.debug("分页时, 生成分页pageSql: " + pageSql);
  82. }
  83. ReflectUtil.setFieldValue(boundSql, "sql", pageSql);
  84. return invocation.proceed();
  85. } else { // 查询结果的地方
  86. // 获取是否有分页Page对象
  87. Page<?> page = findPageObject(invocation.getArgs()[1]);
  88. if (page == null) {
  89. if (log.isTraceEnabled()) {
  90. log.trace("没有Page对象作为参数, 不是分页查询.");
  91. }
  92. return invocation.proceed();
  93. } else {
  94. if (log.isTraceEnabled()) {
  95. log.trace("检测到分页Page对象, 使用分页查询.");
  96. }
  97. }
  98. //设置真正的parameterObj
  99. invocation.getArgs()[1] = extractRealParameterObject(invocation.getArgs()[1]);
  100. pageThreadLocal.set(page);
  101. try {
  102. Object resultObj = invocation.proceed(); // Executor.query(..)
  103. if (resultObj instanceof List) {
  104. /* @SuppressWarnings({ "unchecked", "rawtypes" }) */
  105. page.setResults((List) resultObj);
  106. }
  107. return resultObj;
  108. } finally {
  109. pageThreadLocal.remove();
  110. }
  111. }
  112. }
  113. protected Page<?> findPageObject(Object parameterObj) {
  114. if (parameterObj instanceof Page<?>) {
  115. return (Page<?>) parameterObj;
  116. } else if (parameterObj instanceof Map) {
  117. for (Object val : ((Map<?, ?>) parameterObj).values()) {
  118. if (val instanceof Page<?>) {
  119. return (Page<?>) val;
  120. }
  121. }
  122. }
  123. return null;
  124. }
  125. /**
  126. * <pre>
  127. * 把真正的参数对象解析出来
  128. * Spring会自动封装对个参数对象为Map<String, Object>对象
  129. * 对于通过@Param指定key值参数我们不做处理,因为XML文件需要该KEY值
  130. * 而对于没有@Param指定时,Spring会使用0,1作为主键
  131. * 对于没有@Param指定名称的参数,一般XML文件会直接对真正的参数对象解析,
  132. * 此时解析出真正的参数作为根对象
  133. * </pre>
  134. * @param parameterObj
  135. * @return
  136. */
  137. protected Object extractRealParameterObject(Object parameterObj) {
  138. if (parameterObj instanceof Map<?, ?>) {
  139. Map<?, ?> parameterMap = (Map<?, ?>) parameterObj;
  140. if (parameterMap.size() == 2) {
  141. boolean springMapWithNoParamName = true;
  142. for (Object key : parameterMap.keySet()) {
  143. if (!(key instanceof String)) {
  144. springMapWithNoParamName = false;
  145. break;
  146. }
  147. String keyStr = (String) key;
  148. if (!"0".equals(keyStr) && !"1".equals(keyStr)) {
  149. springMapWithNoParamName = false;
  150. break;
  151. }
  152. }
  153. if (springMapWithNoParamName) {
  154. for (Object value : parameterMap.values()) {
  155. if (!(value instanceof Page<?>)) {
  156. return value;
  157. }
  158. }
  159. }
  160. }
  161. }
  162. return parameterObj;
  163. }
  164. protected void prepareAndCheckDatabaseType(Connection connection) throws SQLException {
  165. if (databaseType == null) {
  166. String productName = connection.getMetaData().getDatabaseProductName();
  167. if (log.isTraceEnabled()) {
  168. log.trace("Database productName: " + productName);
  169. }
  170. productName = productName.toLowerCase();
  171. if (productName.indexOf(MYSQL) != -1) {
  172. databaseType = MYSQL;
  173. } else if (productName.indexOf(ORACLE) != -1) {
  174. databaseType = ORACLE;
  175. } else {
  176. throw new PageNotSupportException("Page not support for the type of database, database product name [" + productName + "]");
  177. }
  178. if (log.isInfoEnabled()) {
  179. log.info("自动检测到的数据库类型为: " + databaseType);
  180. }
  181. }
  182. }
  183. /**
  184. * <pre>
  185. * 生成分页SQL
  186. * </pre>
  187. *
  188. * @param page
  189. * @param sql
  190. * @return
  191. */
  192. protected String buildPageSql(Page<?> page, String sql) {
  193. if (MYSQL.equalsIgnoreCase(databaseType)) {
  194. return buildMysqlPageSql(page, sql);
  195. } else if (ORACLE.equalsIgnoreCase(databaseType)) {
  196. return buildOraclePageSql(page, sql);
  197. }
  198. return sql;
  199. }
  200. /**
  201. * <pre>
  202. * 生成Mysql分页查询SQL
  203. * </pre>
  204. *
  205. * @param page
  206. * @param sql
  207. * @return
  208. */
  209. protected String buildMysqlPageSql(Page<?> page, String sql) {
  210. // 计算第一条记录的位置,Mysql中记录的位置是从0开始的。
  211. int offset = (page.getPageNo() - 1) * page.getPageSize();
  212. return new StringBuilder(sql).append(" limit ").append(offset).append(",").append(page.getPageSize()).toString();
  213. }
  214. /**
  215. * <pre>
  216. * 生成Oracle分页查询SQL
  217. * </pre>
  218. *
  219. * @param page
  220. * @param sql
  221. * @return
  222. */
  223. protected String buildOraclePageSql(Page<?> page, String sql) {
  224. // 计算第一条记录的位置,Oracle分页是通过rownum进行的,而rownum是从1开始的
  225. int offset = (page.getPageNo() - 1) * page.getPageSize() + 1;
  226. StringBuilder sb = new StringBuilder(sql);
  227. sb.insert(0, "select u.*, rownum r from (").append(") u where rownum < ").append(offset + page.getPageSize());
  228. sb.insert(0, "select * from (").append(") where r >= ").append(offset);
  229. return sb.toString();
  230. }
  231. /**
  232. * <pre>
  233. * 查询总数
  234. * </pre>
  235. *
  236. * @param page
  237. * @param parameterObject
  238. * @param mappedStatement
  239. * @param connection
  240. * @throws SQLException
  241. */
  242. protected void queryTotalRecord(Page<?> page, Object parameterObject, MappedStatement mappedStatement, Connection connection) throws SQLException {
  243. BoundSql boundSql = mappedStatement.getBoundSql(page);
  244. String sql = boundSql.getSql();
  245. String countSql = this.buildCountSql(sql);
  246. if (log.isDebugEnabled()) {
  247. log.debug("分页时, 生成countSql: " + countSql);
  248. }
  249. List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  250. BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, parameterMappings, parameterObject);
  251. ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBoundSql);
  252. PreparedStatement pstmt = null;
  253. ResultSet rs = null;
  254. try {
  255. pstmt = connection.prepareStatement(countSql);
  256. parameterHandler.setParameters(pstmt);
  257. rs = pstmt.executeQuery();
  258. if (rs.next()) {
  259. long totalRecord = rs.getLong(1);
  260. page.setTotalRecord(totalRecord);
  261. }
  262. } finally {
  263. if (rs != null)
  264. try {
  265. rs.close();
  266. } catch (Exception e) {
  267. if (log.isWarnEnabled()) {
  268. log.warn("关闭ResultSet时异常.", e);
  269. }
  270. }
  271. if (pstmt != null)
  272. try {
  273. pstmt.close();
  274. } catch (Exception e) {
  275. if (log.isWarnEnabled()) {
  276. log.warn("关闭PreparedStatement时异常.", e);
  277. }
  278. }
  279. }
  280. }
  281. /**
  282. * 根据原Sql语句获取对应的查询总记录数的Sql语句
  283. *
  284. * @param sql
  285. * @return
  286. */
  287. protected String buildCountSql(String sql) {
  288. int index = sql.indexOf("from");
  289. return "select count(*) " + sql.substring(index);
  290. }
  291. /**
  292. * 利用反射进行操作的一个工具类
  293. *
  294. */
  295. private static class ReflectUtil {
  296. /**
  297. * 利用反射获取指定对象的指定属性
  298. *
  299. * @param obj 目标对象
  300. * @param fieldName 目标属性
  301. * @return 目标属性的值
  302. */
  303. public static Object getFieldValue(Object obj, String fieldName) {
  304. Object result = null;
  305. Field field = ReflectUtil.getField(obj, fieldName);
  306. if (field != null) {
  307. field.setAccessible(true);
  308. try {
  309. result = field.get(obj);
  310. } catch (IllegalArgumentException e) {
  311. // TODO Auto-generated catch block
  312. e.printStackTrace();
  313. } catch (IllegalAccessException e) {
  314. // TODO Auto-generated catch block
  315. e.printStackTrace();
  316. }
  317. }
  318. return result;
  319. }
  320. /**
  321. * 利用反射获取指定对象里面的指定属性
  322. *
  323. * @param obj 目标对象
  324. * @param fieldName 目标属性
  325. * @return 目标字段
  326. */
  327. private static Field getField(Object obj, String fieldName) {
  328. Field field = null;
  329. for (Class<?> clazz = obj.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
  330. try {
  331. field = clazz.getDeclaredField(fieldName);
  332. break;
  333. } catch (NoSuchFieldException e) {
  334. // 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。
  335. }
  336. }
  337. return field;
  338. }
  339. /**
  340. * 利用反射设置指定对象的指定属性为指定的值
  341. *
  342. * @param obj 目标对象
  343. * @param fieldName 目标属性
  344. * @param fieldValue 目标值
  345. */
  346. public static void setFieldValue(Object obj, String fieldName, String fieldValue) {
  347. Field field = ReflectUtil.getField(obj, fieldName);
  348. if (field != null) {
  349. try {
  350. field.setAccessible(true);
  351. field.set(obj, fieldValue);
  352. } catch (IllegalArgumentException e) {
  353. // TODO Auto-generated catch block
  354. e.printStackTrace();
  355. } catch (IllegalAccessException e) {
  356. // TODO Auto-generated catch block
  357. e.printStackTrace();
  358. }
  359. }
  360. }
  361. }
  362. public static class PageNotSupportException extends RuntimeException {
  363. /** serialVersionUID*/
  364. private static final long serialVersionUID = 1L;
  365. public PageNotSupportException() {
  366. super();
  367. }
  368. public PageNotSupportException(String message, Throwable cause) {
  369. super(message, cause);
  370. }
  371. public PageNotSupportException(String message) {
  372. super(message);
  373. }
  374. public PageNotSupportException(Throwable cause) {
  375. super(cause);
  376. }
  377. }
  378. }

分页的Page对象:

  1. package ssm.utils;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. public class Page<T> {
  6. public static final int DEFAULT_PAGE_SIZE = 10;
  7. protected int pageNo = 1; // 当前页, 默认为第1页
  8. protected int pageSize = DEFAULT_PAGE_SIZE; // 每页记录数
  9. protected long totalRecord = -1; // 总记录数, 默认为-1, 表示需要查询
  10. protected int totalPage = -1; // 总页数, 默认为-1, 表示需要计算
  11. protected List<T> results; // 当前页记录List形式
  12. public Map<String, Object> params = new HashMap<String, Object>();//设置页面传递的查询参数
  13. public Map<String, Object> getParams() {
  14. return params;
  15. }
  16. public void setParams(Map<String, Object> params) {
  17. this.params = params;
  18. }
  19. public int getPageNo() {
  20. return pageNo;
  21. }
  22. public void setPageNo(int pageNo) {
  23. this.pageNo = pageNo;
  24. }
  25. public int getPageSize() {
  26. return pageSize;
  27. }
  28. public void setPageSize(int pageSize) {
  29. this.pageSize = pageSize;
  30. computeTotalPage();
  31. }
  32. public long getTotalRecord() {
  33. return totalRecord;
  34. }
  35. public int getTotalPage() {
  36. return totalPage;
  37. }
  38. public void setTotalRecord(long totalRecord) {
  39. this.totalRecord = totalRecord;
  40. computeTotalPage();
  41. }
  42. protected void computeTotalPage() {
  43. if (getPageSize() > 0 && getTotalRecord() > -1) {
  44. this.totalPage = (int) (getTotalRecord() % getPageSize() == 0 ? getTotalRecord() / getPageSize() : getTotalRecord() / getPageSize() + 1);
  45. }
  46. }
  47. public List<T> getResults() {
  48. return results;
  49. }
  50. public void setResults(List<T> results) {
  51. this.results = results;
  52. }
  53. @Override
  54. public String toString() {
  55. StringBuilder builder = new StringBuilder().append("Page [pageNo=").append(pageNo).append(", pageSize=").append(pageSize)
  56. .append(", totalRecord=").append(totalRecord < 0 ? "null" : totalRecord).append(", totalPage=")
  57. .append(totalPage < 0 ? "null" : totalPage).append(", curPageObjects=").append(results == null ? "null" : results.size()).append("]");
  58. return builder.toString();
  59. }
  60. }

ServiceImpl调用过程:最后查询出来的分页的信息

  1. @Override
  2. public List<UserVo> selectSelective(UserVo userVo) {
  3. List<UserVo> listVo = new ArrayList<UserVo>();
  4. //      UserPoExample example = new UserPoExample();
  5. //      Criteria criteria = example.createCriteria();
  6. //      criteria.andUsernameEqualTo(userVo.getUsername());
  7. //      criteria.andRoleEqualTo(userVo.getRole());
  8. //      example.setOrderByClause("userId desc");//设置排序方式
  9. //      example.setStart(0);
  10. //      example.setLimit(10);
  11. Page<UserVo> page = new Page<UserVo>();
  12. List<UserPo> listPo =null;
  13. try {
  14. //          UserPo po1 = new UserPo();
  15. //          po1.setUsername(userVo.getUsername());
  16. //          po1.setRole(userVo.getRole());
  17. Map<String, Object> params = new HashMap<String, Object>();
  18. params.put("username", userVo.getUsername());
  19. params.put("role", userVo.getRole());
  20. params.put("orderByClause","userId desc");
  21. page.setParams(params);
  22. listPo = userPoMapper.selectBySelective(page);
  23. for(UserPo po:listPo){
  24. UserVo vo = new UserVo();
  25. BeanUtils.copyProperties(po, vo);
  26. listVo.add(vo);
  27. }
  28. page.setResults(listVo);
  29. } catch (Exception e) {
  30. logger.error(e);
  31. }
  32. return listVo;
  33. }

对应的xml

  1. <select id="selectBySelective" parameterType="ssm.utils.Page" resultType="ssm.po.UserPo">
  2. select * from tb_user
  3. <where>
  4. <if test="params.username != null and params.username !=''">
  5. userName = #{params.username}
  6. <!-- userName like '%${usesrname}%' -->
  7. </if>
  8. <if test="params.password != null and params.password !=''">
  9. and password = #{params.password}
  10. </if>
  11. <if test="params.sex != null and params.sex !=''">
  12. and sex = #{params.sex}
  13. </if>
  14. <if test="params.age != null and params.age !=''">
  15. and age = #{params.age}
  16. </if>
  17. <if test="params.email != null and params.email !=''">
  18. and email = #{params.email}
  19. </if>
  20. <if test="params.courseid != null and params.courseid !=''">
  21. and courseId = #{params.courseid}
  22. </if>
  23. <if test="params.role != null and params.role !=''">
  24. and role = #{params.role}
  25. </if>
  26. <if test="params.state != null and params.state !=''">
  27. and state = #{params.state}
  28. </if>
  29. </where>
  30. <if test="params.orderByClause != null and params.orderByClause !=''"></if>
  31. order by #{params.orderByClause}
  32. </select>

mybatis分页方式对比的更多相关文章

  1. Spring Boot CRUD+分页(基于Mybatis注解方式)

    步骤一:关于Mybatis Mybatis 是用来进行数据库操作的框架.其中分页使用Mybatis中的PageHelper插件. Mybatis与hibernate对比: 1.hibernate是一个 ...

  2. 【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法

    spring boot集成mybatis,集成使用mybatis拖沓了好久,今天终于可以补起来了. 本篇源码中,同时使用了Spring data JPA 和 Mybatis两种方式. 在使用的过程中一 ...

  3. Mybatis分页和Spring的集成

    写了一个Mybatis分页控件,在这记录一下使用方式. 在Maven中加入依赖: ? 1 2 3 4 5 6 7 8 9 <dependencies>   ...     <depe ...

  4. SQL SERVER2012新分页方式 轉載

    SQL SERVER2012在ORDER BY 子句中加入了新元素offset,允许用户在排序完成的结果集中自定义输出行范围,大大简化了分页SQL的书写方式和效率. SQL SERVER2012在OR ...

  5. Mybatis分页插件PageHelper的配置和使用方法

     Mybatis分页插件PageHelper的配置和使用方法 前言 在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页. 前端分 ...

  6. SSM 使用 mybatis 分页插件 pagehepler 实现分页

    使用分页插件的原因,简化了sql代码的写法,实现较好的物理分页,比写一段完整的分页sql代码,也能减少了误差性. Mybatis分页插件 demo 项目地址:https://gitee.com/fre ...

  7. MyBatis 分页之拦截器实现

    分页是WEB程序中常见的功能,mybatis分页实现与hibernate不同,相比hibernate,mybatis实现分页更为麻烦.mybatis实现分页需要自己编写(非逻辑分页RowBounds) ...

  8. MyBatis分页

    搞清楚什么是分页(pagination) 例如,在数据库的某个表里有1000条数据,我们每次只显示100条数据,在第1页显示第0到第99条,在第2页显示第100到199条,依次类推,这就是分页. 分页 ...

  9. MyBatis3-实现MyBatis分页

    此文章中的例子是沿用上一篇文章http://www.cnblogs.com/EasonJim/p/7055499.html的Spring MVC集成的例子改装的. MyBatis分页有以下方式实现: ...

随机推荐

  1. 如何处理错误消息Please install the gcc make perl packages

    如何处理这行错误消息? Please install the gcc make perl packages from your distribution. 执行命令行:yum install gcc ...

  2. 使用JDK自带的VisualVM进行Java程序的性能分析

    VisualVM是什么? VisualVM是JDK自带的一个用于Java程序性能分析的工具,JDK安装完毕后就有啦,在JDK安装目录的bin文件夹下能找到名称为jvisualvm.exe. 要使用Vi ...

  3. cesium模型加载-加载fbx格式模型

    整体思路: fbx格式→dae格式→gltf格式→cesium加载gltf格式模型 具体方法: 1. fbx格式→dae格式 工具:3dsMax, 3dsMax插件:OpenCOLLADA, 下载地址 ...

  4. python基础一 day15 内置函数

    '\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖: '\n' 换行,换到当前位置的下一行,而不会回到行首: # print()# input()# le ...

  5. 剑指offer18 树的子结构

    另一种写法 class Solution { public: bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) { bool result = f ...

  6. ctDNA|endosymbiosis

    5.10叶绿体基因组编码多种蛋白质和RNA 叶绿体和线粒体的共同点:叶绿体和线粒体的大小,功能(编码区)大体一致,但叶绿体拥有更多基因,所以在编码tRNA时,也有内含子作为被剪切片段. 因为在原核生物 ...

  7. oc 数据类型转换

    NSNumber转NSString: 假设现有一NSNumber的变量A,要转换成NSString类型的B 方法如下: NSNumberFormatter* numberFormatter = [[N ...

  8. 利用sysbench工具测试MHA

    利用sysbench工具测试MHA 1. sysbench准备数据 2. sysbench开始压测 3. master模拟意外宕机 4. mysqldb2 上观察mha状态 5. 手工failover ...

  9. destoon 信息发布表单提交验证

    sell 模块的form表单如下: <form method="post" id="dform" action="?" target= ...

  10. shutil,zipfile,tarfile模块

    一,shutil模块 1.shutil.chown() shutil.chown('test.txt',user='mysql',group='mysql') #改变文件的属主和属组. 2.shuti ...