springMVC,myBatis的物理分页和高级查询

springMVC、myBatis的物理分页和高级查询分类:JavaEE 2013-06-09 13:44 797人阅读评论(4) 收藏举报springMVCmybatis高级查询分页ajax最新项目用到springMVC和mybatis,分页其实用一个RowBounds可以实现,但是高级查询不好封装,经过反复测试,总算搞出来了,感觉封装的不是很好,有待优化和提高!原理:利用mybatis自定义插件功能,自定义一个拦截器,拦截需要分页的sql,并想办法通过BoundSql对象进行处理,大致分8步:1、获得BoundSql对象2、获取原始的写在配置文件中的SQL3、拦截到mapper中定义的执行查询方法中的参数4、解析参数,获取高级查询参数信息5、解析参数,获取查询限制条件6、根据4、5中的参数拼装并重新生成SQL语句7、将SQL设置回BoundSql对象中8、完成。

拦截器:[java]view plaincopyprint?1.package com.wtas.page.interceptor;2.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 java.util.Set;11.12.import javax.xml.bind.PropertyException;13.14.import org.apache.ibatis.executor.ErrorContext;15.import org.apache.ibatis.executor.ExecutorException;16.import org.apache.ibatis.executor.statement.BaseStatementHandler;17.import org.apache.ibatis.executor.statement.RoutingStatementHandler;18.import org.apache.ibatis.executor.statement.StatementHandler;19.import org.apache.ibatis.mapping.BoundSql;20.import org.apache.ibatis.mapping.MappedStatement;21.import org.apache.ibatis.mapping.ParameterMapping;22.import org.apache.ibatis.mapping.ParameterMode;23.import org.apache.ibatis.plugin.Interceptor;24.import org.apache.ibatis.plugin.Intercepts;25.import org.apache.ibatis.plugin.Invocation;26.import org.apache.ibatis.plugin.Plugin;27.import org.apache.ibatis.plugin.Signature;28.import org.apache.ibatis.reflection.MetaObject;29.import org.apache.ibatis.reflection.property.PropertyTokenizer;30.import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;31.import org.apache.ibatis.session.Configuration;32.import org.apache.ibatis.type.TypeHandler;33.import org.apache.ibatis.type.TypeHandlerRegistry;34.import org.slf4j.Logger;35.import org.slf4j.LoggerFactory;36.37.import com.wtas.page.PageContext;38.import com.wtas.page.Pager;39.import com.wtas.page.Query;40.import com.wtas.utils.SystemUtil;41.42./**43. * 查询分页拦截器,用户拦截SQL,并加上分页的参数和高级查询条件44. *45. * @author dendy46. *47. */48.@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })49.public class PaginationInterceptor implements Interceptor {50.51. private final Logger logger = LoggerFactory52. .getLogger(PaginationInterceptor.class);53.54. private String dialect = "";55.56. // 暂时不需要这个参数,现在根据参数类型来判断是否是分页sql57. // private String pageMethodPattern = "";58.59. public Object intercept(Invocation ivk) throws Throwable {60. if (!(ivk.getTarget() instanceof RoutingStatementHandler)) {61. return ivk.proceed();62. }63. RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk64. .getTarget();65. BaseStatementHandler delegate = (BaseStatementHandler) SystemUtil66. .getValueByFieldName(statementHandler, "delegate");67. MappedStatement mappedStatement = (MappedStatement) SystemUtil68. .getValueByFieldName(delegate, "mappedStatement");69.70. // BoundSql封装了sql语句71. BoundSql boundSql = delegate.getBoundSql();72. // 获得查询对象73. Object parameterObject = boundSql.getParameterObject();74. // 根据参数类型判断是否是分页方法75. if (!(parameterObject instanceof Query)) {76. return ivk.proceed();77. }78. logger.debug(" beginning to intercept page SQL...");79. Connection connection = (Connection) ivk.getArgs()[0];80. String sql = boundSql.getSql();81. Query query = (Query) parameterObject;82. // 查询参数对象83. Pager pager = null;84. // 查询条件Map85. Map<String, Object> conditions = query.getQueryParams();86. pager = query.getPager();87. // 拼装查询条件88. if (conditions != null) {89. Set<String> keys = conditions.keySet();90. Object value = null;91. StringBuffer sb = new StringBuffer();92. boolean first = true;93. for (String key : keys) {94. value = conditions.get(key);95. if (first) {96. sb.append(" where ").append(key).append(value);97. first = !first;98. } else {99. sb.append(" and ").append(key).append(value); 100. }101. }102. sql += sb.toString();103. }104.105. // 获取查询数来的总数目106. String countSql = "SELECT COUNT(0) FROM (" + sql + ") AS t mp ";107. PreparedStatement countStmt = connection.prepareStatement( countSql);108. BoundSql countBS = new BoundSql(mappedStatement.getConfigu ration(),109. countSql, boundSql.getParameterMappings(), paramet erObject);110. setParameters(countStmt, mappedStatement, countBS, paramet erObject);111. ResultSet rs = countStmt.executeQuery();112. int count = 0;113. if (rs.next()) {114. count = rs.getInt(1);115. }116. rs.close();117. countStmt.close();118.119. // 设置总记录数120. pager.setTotalResult(count);121. // 设置总页数122. pager.setTotalPage((count + pager.getShowCount() - 1) 123. / pager.getShowCount());124. // 放到作用于125. PageContext.getInstance().set(pager);126.127. // 拼装查询参数128. String pageSql = generatePageSql(sql, pager);129. SystemUtil.setValueByFieldName(boundSql, "sql", pageSql);130. logger.debug("generated pageSql is : " + pageSql); 131.132. return ivk.proceed();133. }134.135. /**136. * setting parameters137. *138. * @param ps139. * @param mappedStatement140. * @param boundSql141. * @param parameterObject142. * @throws SQLException143. */144. private void setParameters(PreparedStatement ps,145. MappedStatement mappedStatement, BoundSql boundSql, 146. Object parameterObject) throws SQLException {147. ErrorContext.instance().activity("setting parameters") 148. .object(mappedStatement.getParameterMap().getId()) ;149. List<ParameterMapping> parameterMappings = boundSql 150. .getParameterMappings();151. if (parameterMappings != null) {152. Configuration configuration = mappedStatement.getConfi guration();153. TypeHandlerRegistry typeHandlerRegistry = configuratio n154. .getTypeHandlerRegistry();155. MetaObject metaObject = parameterObject == null ? null156. : configuration.newMetaObject(parameterObject) ;157. for (int i = 0; i < parameterMappings.size(); i++) { 158. ParameterMapping parameterMapping = parameterMappi ngs.get(i);159. if (parameterMapping.getMode() != ParameterMode.OU T) {160. Object value;161. String propertyName = parameterMapping.getProp erty();162. PropertyTokenizer prop = new PropertyTokenizer (propertyName);163. if (parameterObject == null) {164. value = null;165. } else if (typeHandlerRegistry166. .hasTypeHandler(parameterObject.getCla ss())) {167. value = parameterObject;168. } else if (boundSql.hasAdditionalParameter(pro pertyName)) {169. value = boundSql.getAdditionalParameter(pr opertyName);170. } else if (propertyName171. .startsWith(ForEachSqlNode.ITEM_PREFIX )172. && boundSql.hasAdditionalParameter(pro p.getName())) {173. value = boundSql.getAdditionalParameter(pr op.getName());174. if (value != null) {175. value = configuration.newMetaObject(va lue)176. .getValue(177. propertyName.substring (prop178. .getName().len gth()));179. }180. } else {181. value = metaObject == null ? null : metaOb ject182. .getValue(propertyName);183. }184.@SuppressWarnings("unchecked")185. TypeHandler<Object> typeHandler = (TypeHandler <Object>) parameterMapping186. .getTypeHandler();187. if (typeHandler == null) {188. throw new ExecutorException(189. "There was no TypeHandler found fo r parameter "190. + propertyName + " of stat ement "191. + mappedStatement.getId()) ;192. }193. typeHandler.setParameter(ps, i + 1, value, 194. parameterMapping.getJdbcType()); 195. }196. }197. }198. }199.200. /**201. * 生成Sql语句202. *203. * @param sql204. * @param page205. * @return206. */207. private String generatePageSql(String sql, Pager page) { 208. if (page != null && (dialect != null || !dialect.equals(""))) {209. StringBuffer pageSql = new StringBuffer();210. if ("mysql".equals(dialect)) {211. pageSql.append(sql);212. pageSql.append(" LIMIT " + page.getCurrentResult() + ","213. + page.getShowCount());214. } else if ("oracle".equals(dialect)) {215. pageSql.append("SELECT * FROM (SELECT t.*,ROWNUM r FROM (");216. pageSql.append(sql);217. pageSql.append(") t WHERE r <= ");218. pageSql.append(page.getCurrentResult() + page.getS howCount());219. pageSql.append(") WHERE r >");220. pageSql.append(page.getCurrentResult());221. }222. return pageSql.toString();223. } else {224. return sql;225. }226. }227.228. public Object plugin(Object arg0) {229. return Plugin.wrap(arg0, this);230. }231.232. public void setProperties(Properties p) {233. dialect = p.getProperty("dialect");234. if (dialect == null || dialect.equals("")) {235. try {236. throw new PropertyException("dialect property is n ot found!");237. } catch (PropertyException e) {238. e.printStackTrace();239. }240. }241. // pageMethodPattern = p.getProperty("pageMethodPattern");242. if (dialect == null || dialect.equals("")) {243. try {244. throw new PropertyException(245. "pageMethodPattern property is not found!");246. } catch (PropertyException e) {247. e.printStackTrace();248. }249. }250. }251.252.}查询对象的封装:1、map封装查询条件2、pager对象封装查询限制条件,就是MySql中limit后的参数等附加信息[java]view plaincopyprint?1.package com.wtas.page;2.3./**4. * 分页描述信息5. *6. * @author dendy7. *8. */9.public class Pager {10. // 每一页的显示条数11. private int showCount;12. // 总的页数13. private int totalPage;14. // 查询的数据总条数15. private int totalResult;16. // 当前页17. private int currentPage;18. // 从第几条开始获取数据19.@SuppressWarnings("unused")20. private int currentResult;21.22. public Pager() {23. this(1);24. }25.26. public Pager(int currentPage) {27. // 默认每页显示10条记录28. this(currentPage, 10);29. }30.31. public Pager(int currentPage, int showCount) {32. this.currentPage = currentPage;33. if (showCount > 0) {34. this.showCount = showCount;35. }36. // 错误处理37. if (this.currentPage < 1) {38. this.currentPage = 1;39. }40. }41.42. //只列出关键的getter和setter……43.44. public int getTotalPage() {45. // 分页算法,计算总页数46. return this.totalPage;47. }48.49. public int getCurrentResult() {50. // 计算从第几条获取数据51. return (currentPage - 1) * showCount;52. }53.54.}[java]view plaincopyprint?1.package com.wtas.page;2.3.import java.util.Map;4.5./**6. * 封装查询蚕食和查询条件7. *8. * @author dendy9. *10. */11.public class Query {12. private Map<String, Object> queryParams;13. private Pager pager;14.15. public Map<String, Object> getQueryParams() {16. return queryParams;17. }18.19. public void setQueryParams(Map<String, Object> queryParams) {20. this.queryParams = queryParams;21. }22.23. //省略getter和setter24.}控制层关键代码:[java]view plaincopyprint?1. /**2. * 分页时获取所有的学生3. *4. * @return5. */6.@RequestMapping("pageStus")7.@ResponseBody8.public List<User> pageAllStudents(HttpServletRequest req) {9. try {10. Query query = new Query();11. Pager pager = new Pager();12. Map<String, Object> queryParams = new HashMap<String, Object>();13.14. // 获取分页参数15. String showCount = req.getParameter("showCount");16. String currentPage = req.getParameter("currentPage");18. if (StringUtils.hasLength(showCount)) {19. pager.setShowCount(Integer.parseInt(showCount));20. }21. if (StringUtils.hasLength(currentPage)) {22. pager.setCurrentPage(Integer.parseInt(currentPage));23. }24.25. // 高级查询条件:学生真实姓名26. String trueNameForQuery = req.getParameter("trueNameForQuery");27. if (StringUtils.hasLength(trueNameForQuery)) {28. queryParams.put(" u.REAL_NAME like ", "'%" + trueNameForQuery29. + "%'");30. }31.32. query.setPager(pager);33. query.setQueryParams(queryParams);34. List<User> users = userService.pageUsersByRole(query);35.36. // req.setAttribute("pager", PageContext.getInstance().get());37.38. return users;39. } catch (Exception e) {40. LOG.error("getAllStudents error : " + e.getMessage());41. }42. return null;43.}44.45.@RequestMapping("getPager")46.@ResponseBody47.public Pager getPager() {48. return PageContext.getInstance().get();dao中的方法:[java]view plaincopyprint?1. /**2.* 级联查询所有某一角色的用户信息,带分页3.*4.* @param roleValue5.* @param page6.* @return7.*/8.ist<User> pageUsers(Object query);dao的Mappder.xml定义:[html]view plaincopyprint?1.<select id="pageUsers"resultMap="userMapping"parameterType="hashMap">2. SELECT DISTINCT u.* FROM T_USER u LEFT JOIN T_REL_USER_ROLE ur ON3.u.id=er_id4. LEFT JOIN T_ROLE r ON ur.role_id=r.id5.</select>页面通过javascript来异常发送请求获取数据,关键代码:[javascript]view plaincopyprint?1./**2. * 处理分页3. *4. * @param curPage5. * @param id6. */7.function page(curPage, id) {8. if(curPage <= 0){9. curPage = 1;10. }11.12. var trueNameForQuery = $("#findByTrueNameInput").val().trim();13.14. var url = path + "/studygroup/pageStus.do";15. var thCss = "class='s-th-class'";16. var tdCss = "class='s-td-class'";17. $.ajax({18. type : "POST",19. url : url,20. dataType : "json",21. data : {22. "id" : id,23. "currentPage" : curPage,24. "trueNameForQuery" : trueNameForQuery25. },26. success : function(data) {27. var json = eval(data);28. var res = "<tr><th " + thCss + ">选择</th>"29. + "<th " + thCss + ">用户名</th>"30. + "<th " + thCss + ">真实姓名</th>"31. + "<th " + thCss + ">性别</th>"32. + "<th " + thCss + ">学校</th>"33. + "<th " + thCss + ">年级</th>"34. + "<th " + thCss + ">班级</th></tr>";35. for ( var i = 0; i < json.length; i++) {36. var userId = json[i].id;37. var name = json[i].name;38. var trueName = json[i].trueName;39. var sex = json[i].sex;40. var school = "";41. if (json[i].school) {42. school = json[i];43. }44. var grade = "";45. if (json[i].grade) {46. grade = json[i];47. }48. var clazz = "";49. if (json[i].clazz) {50. clazz = json[i];51. }52. res += "<tr><td align='center' " + tdCss + "><input type='checkbox' value='" + userId + "' /></td>"53. + "<td align='center' " + tdCss + ">" + (name|| "") + "</td>"54. + "<td align='center' " + tdCss + ">" + (trueName || "") + "</td>"55. + "<td align='center' " + tdCss + ">" + (sex== 1 ? '女' : '男' || "") + "</td>"56. + "<td align='center' " + tdCss + ">" + school + "</td>"57. + "<td align='center' " + tdCss + ">" + grade+ "</td>"58. + "<td align='center' " + tdCss + ">" + clazz+ "</td>"59. + "</td></tr>";60. }61. $("#inviteStudentsTbl").html(res);62. // 每次加载完成都要刷新分页栏数据63. freshPager(id);64. }65. });66.}67.68./**69. * 重新获取分页对象,刷新分页工具栏70. */71.function freshPager(id){72. var url = path + "/studygroup/getPager.do";73. var studyGroupId = id;74. $.ajax({75. type : "POST",76. url : url,77. dataType : "json",78. success : function (data) {79. var pager = eval(data);80. var currentPage = pager.currentPage;81.// var currentResult = pager.currentResult;82.// var showCount = pager.showCount;83. var totalPage = pager.totalPage;84.// var totalResult = pager.totalResult;85.86. var prePage = currentPage - 1;87. var nextPage = currentPage + 1;88. if (prePage <= 0) {89. prePage = 1;90. }91. if (nextPage > totalPage) {92. nextPage = totalPage;93. }94.95. $("#topPageId").attr("href", "javascript:page(1, " + studyGroupId + ");");96. $("#prefixPageId").attr("href", "javascript:page(" + prePage + ", " + studyGroupId + ");");97. $("#nextPageId").attr("href", "javascript:page(" + nextPage + ", " + studyGroupId + ");");98. $("#endPageId").attr("href", "javascript:page(" + totalPage + ", " + studyGroupId + ");");99. $("#curPageId").html(currentPage);100. $("#totalPageId").html(totalPage);101. }102. });103.}104.105./**106. * 按真实姓名搜索107. */108.function findByTrueName() {109. page(1, studyGroupId);110.}end. ————————————————————————————————————————————————应网友需要,贴上SystemUtil的代码:[java]view plaincopyprint?1.package mon.utils;2.3.import ng.reflect.Field;4.5.import javax.servlet.http.HttpSession;6.7.import mon.consts.SystemConst;8.import er;9.10./**11. * 系统工具类,定义系统常用的工具方法12. *13. * @author dendy14. *15. */16.public class SystemUtil {17. private SystemUtil() {18.19. }20.21. /**22. * 获取系统访问的相对路径,如:/WTAS23. *24. * @return25. */26. public static String getContextPath() {27. return System.getProperty(SystemConst.SYSTEM_CONTEXT_PATH_KEY);28. }29.30. /**31. * 修改一个bean(源)中的属性值,该属性值从目标bean获取32. *33. * @param dest34. * 目标bean,其属性将被复制到源bean中35. * @param src36. * 需要被修改属性的源bean37. * @param filtNullProps38. * 源bean的null属性是否覆盖目标的属性<li>true : 源bean中只有为null的属性才会被覆盖<li>false39. * : 不管源bean的属性是否为null,均覆盖40. * @throws IllegalArgumentException41. * @throws IllegalAccessException42. */43. public static void copyBean(Object dest, Object src, boolean filtNullProps)44. throws IllegalArgumentException, IllegalAccessException {45. if (dest.getClass() == src.getClass()) {46. // 目标bean的所有字段47. Field[] destField = dest.getClass().getDeclaredFields();48. // 源bean的所有字段49. Field[] srcField = src.getClass().getDeclaredFields();50. for (int i = 0; i < destField.length; i++) {51. String destFieldName = destField[i].getName();52. String destFieldType = destField[i].getGenericType().toString();53. for (int n = 0; n < srcField.length; n++) {54. String srcFieldName = srcField[n].getName();55. String srcFieldType = srcField[n].getGenericType()56. .toString();57. // String srcTypeName =58. // srcField[n].getType().getSimpleName();59. if (destFieldName.equals(srcFieldName)60. && destFieldType.equals(srcFieldType)) {61. destField[i].setAccessible(true);62. srcField[n].setAccessible(true);63. Object srcValue = srcField[n].get(src);64. Object destValue = destField[i].get(dest);65. if (filtNullProps) {66. // 源bean中的属性已经非空,则不覆盖67. if (srcValue == null) {68. srcField[n].set(src, destValue);69. }70. } else {71. srcField[n].set(dest, srcValue);72. }73. }74. }75. }76. }77. }78.79. /**80. * 根据字段的值获取该字段81. *82. * @param obj83. * @param fieldName84. * @return85. */86. public static Field getFieldByFieldName(Object obj, String fieldName) {87. for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass88. .getSuperclass()) {89. try {90. return superClass.getDeclaredField(fieldName);91. } catch (NoSuchFieldException e) {92. }93. }94. return null;95. }96.97. /**98. * 获取对象某一字段的值99. *100. * @param obj101. * @param fieldName102. * @return103. * @throws SecurityException104. * @throws NoSuchFieldException105. * @throws IllegalArgumentException106. * @throws IllegalAccessException107. */108. public static Object getValueByFieldName(Object obj, String fi eldName)109. throws SecurityException, NoSuchFieldException, 110. IllegalArgumentException, IllegalAccessException { 111. Field field = getFieldByFieldName(obj, fieldName); 112. Object value = null;113. if (field != null) {114. if (field.isAccessible()) {115. value = field.get(obj);116. } else {117. field.setAccessible(true);118. value = field.get(obj);119. field.setAccessible(false);120. }121. }122. return value;123. }124.125. /**126. * 向对象的某一字段上设置值127. *128. * @param obj129. * @param fieldName130. * @param value131. * @throws SecurityException132. * @throws NoSuchFieldException133. * @throws IllegalArgumentException134. * @throws IllegalAccessException135. */136. public static void setValueByFieldName(Object obj, String fiel dName,137. Object value) throws SecurityException, NoSuchFieldExc eption,138. IllegalArgumentException, IllegalAccessException { 139. Field field = obj.getClass().getDeclaredField(fieldName);140. if (field.isAccessible()) {141. field.set(obj, value);142. } else {143. field.setAccessible(true);144. field.set(obj, value);145. field.setAccessible(false);146. }147. }148.149. /**150. * 从session中获取当前登录用户151. *152. * @param session153. * @return154. */155. public static User getLoginUser(HttpSession session) { 156. return (User) session.getAttribute(ER_IN_SES SION);157. }158.159. /**160. * @Description 设置更新信息后的登录用户给session161. * @param user 登录用户162. * @param session session163. */164. public static void setUser(User user, HttpSession session) { 165. session.setAttribute(ER_IN_SESSION, user); 166. }167.}。

合集下载

Java的MyBatis框架中实现多表连接查询和查询结果分页

Java的MyBatis框架中实现多表连接查询和查询结果分页

Java的MyBatis框架中实现多表连接查询和查询结果分页实现多表联合查询还是在david.mybatis.model包下⾯新建⼀个Website类,⽤来持久化数据之⽤,重写下相应toString()⽅法,⽅便测试程序之⽤。

package david.mybatis.model;import java.text.SimpleDateFormat;import java.util.Date;public class Website {private int id;private String name;private int visitorId;private int status;private Date createTime;private Visitor visitor;public Website() {// TODO Auto-generated constructor stubcreateTime = new Date();visitor = new Visitor();}public Website(String name, int visitorId) { = name;this.visitorId = visitorId;visitor = new Visitor();status = 1;createTime = new Date();}public int getId() {return id;}public void setId(int id) {this.id = id;}public Visitor getVisitor() {return visitor;}public void setVisitor(Visitor visitor) {this.visitor = visitor;}public String getName() {return name;}public void setName(String name) { = name;}public int getStatus() {return status;}public void setStatus(int status) {this.status = status;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public int getVisitorId() {int id = 0;if (visitor == null)id = visitorId;elseid = visitor.getId();return id;}public void setVisitorId(int visitorId) {this.visitorId = visitorId;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder(String.format("Website=> {Id:%d, Name:%s, CreateTime:%s}\r\n", id, name,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createTime)));if (visitor != null)sb.append(String.format("Visitor=> %s", visitor.toString()));return sb.toString();}}在david.mybatis.demo下⾯分别新建相应的操作接⼝:package david.mybatis.demo;import java.util.List;import david.mybatis.model.Website;public interface IWebsiteOperation {public int add(Website website);public int delete(int id);public int update(Website website);public Website query(int id);public List<Website> getList();}在mapper⽂件夹下新建WebsiteMapper.xml映射⽂件,分别参照上⼀张所说的把增删改查的单表操作配置分别放进去,这样你可以建造⼀点测试数据。

mybatis的pagehelper分页案例

mybatis的pagehelper分页案例

mybatis的pagehelper分页案例
以下是一个使用Mybatis的pagehelper插件进行分页的案例:
1. 添加依赖:在Spring Boot项目中引入pagehelper的依赖。

2. 配置分页插件:在配置文件中配置分页插件,配置内容如下:
```xml
< plugins>
<plugin
interceptor="com.github.pagehelper.PageInterceptor" /> </plugins>
```
3. 设置分页参数:在查询方法中设置分页参数,示例代码如下:
```java
Page<Article> page = articleMapper.findByTitle(title, new Page<Article>(pageNo, pageSize));
```
其中`Article`是实体类,`articleMapper`是对应的mapper接
口,`findByTitle`是查询方法,`title`是查询条件,`new Page(pageNo, pageSize)`是分页参数,分别表示页码和每页显示的条数。

4. 获取分页结果:通过分页对象`page`的方法获取分页结果,示例代码如下:
```java
List<Article> articles = page.getResult();
```
其中`articles`是分页结果。

以上是Mybatis的pagehelper分页案例的基本步骤。

请注意,具体的配置和参数可能因项目而异,你可以根据实际情况进行调整。

mybatisrowbounds分页原理

mybatisrowbounds分页原理

mybatisrowbounds分页原理MyBatis是一个流行的Java持久化框架,它提供了多种分页方式,其中一种是使用RowBounds来实现分页。

本文将介绍MyBatis RowBounds分页原理,包括如何使用RowBounds实现分页、分页的实现原理以及如何优化分页性能。

一、使用RowBounds实现分页MyBatis提供了两种分页方式:基于物理分页和基于逻辑分页。

基于物理分页是通过数据库分页语句(如MySQL的LIMIT语句)来实现分页,而基于逻辑分页是通过查询所有结果,然后在内存中进行分页。

RowBounds是一种基于逻辑分页的方式,它通过设置查询结果集的偏移量和限制数量来实现分页。

使用RowBounds实现分页非常简单。

首先,需要在Mapper接口中定义一个方法,该方法应该包含两个参数:一个是查询条件,另一个是RowBounds对象。

例如:```List<User> getUsersByPage(String name, RowBounds rowBounds);```在XML映射文件中,需要编写一个SQL语句,该语句应该查询所有符合条件的记录,并将结果集限制在指定的偏移量和限制数量内。

例如:```<select id='getUsersByPage' resultType='User'>select * from user where name like #{name} limit #{offset}, #{limit}</select>```在Java代码中,需要构造一个RowBounds对象,该对象包含偏移量和限制数量。

例如:```int offset = (pageNum - 1) * pageSize;int limit = pageSize;RowBounds rowBounds = new RowBounds(offset, limit);List<User> users = userMapper.getUsersByPage(name, rowBounds);```以上代码将查询所有名字包含name的用户,并将结果集限制在从offset开始的limit个记录内。

分页查询--SpringMVC+JDBC 2

分页查询--SpringMVC+JDBC 2

本文通过一个实例,详细地说明了如何用SpringMVC进行数据库查询并且分页显示开发环境:操作系统:windows XP sp3数据库:Oracle10gIDE:MyEclipse6Web容器:Tomcat5.xJDK版本:JDK1.6工程切图如下基本上参照之前示例修改得来,重点关注SimpleJdbcTemplate与JdbcTemplate用法以下只列出比较重要的类UserController.javapackage com.liuzd.sj.web;import java.util.List;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.servlet.ModelAndView;import com.liuzd.page.Page;import er;import erService;@Controller@RequestMapping("/user")@SessionAttributes("userList")public class UserController extends BaseController{private UserService userService;public UserService getUserService() {return userService;}@Resourcepublic void setUserService(UserService userService) {erService = userService;}@RequestMapping("/userList")public ModelAndView userList(HttpServletRequest request){ StringBuilder querySql = new StringBuilder();querySql.append("select * from users where 1=1 ");String oracleQuerySql = querySql.toString();//获取总条数Long totalCount = newLong(this.getUserService().pageCounts(oracleQuerySql));//设置分页对象Page page =executePage(request,oracleQuerySql,totalCount," id desc ");ModelAndView mv = new ModelAndView();//查询集合List<User> users =this.getUserService().pageList(page.getQuerySql());mv.addObject("userList",users);mv.setViewName("userList");return mv;}@RequestMapping("/addUser")public ModelAndView addUser(HttpServletRequest request,User user){System.out.println("ADD USER: "+ user);erService.addUser(user);return userList(request);}@RequestMapping("/toAddUser")public String toAddUser(){return "addUser";}@RequestMapping("/delUser/{id}")public ModelAndView delUser(@PathVariable("id") Stringid,HttpServletRequest request){erService.delUser(new User().setId(id));return userList(request);}@RequestMapping("/getUser/{id}")public ModelAndView getUser(@PathVariable("id") String id){ User user = erService.getUserById(newUser().setId(id));ModelAndView mv = new ModelAndView("updateUser");mv.addObject("user",user);return mv;}@RequestMapping("/updateUser")public ModelAndView editUser(User user,HttpServletRequest request){System.out.println("编辑: "+user);erService.editUser(user);return userList(request);}}BaseController.javapackage com.liuzd.sj.web;import javax.servlet.http.HttpServletRequest;import com.liuzd.page.Page;import com.liuzd.page.PageState;import com.liuzd.page.PageUtil;/***Title:*Description:*Copyright: Copyright (c) 2011*Company:/*Makedate:2011-5-23 下午03:31:03* @author liuzidong* @version 1.0* @since 1.0**/public class BaseController {/*** oracel的三层分页语句* 子类在展现数据前,进行分页计算!* @param querySql 查询的SQL语句,未进行分页* @param totalCount 根据查询SQL获取的总条数* @param columnNameDescOrAsc 列名+排序方式 : ID DESC or ASC*/protected Page executePage(HttpServletRequest request,String querySql,Long totalCount,String columnNameDescOrAsc){String oracleSql =PageUtil.createQuerySql(querySql,columnNameDescOrAsc);if(null == totalCount){totalCount = 0L;}/**页面状态,这个状态是分页自带的,与业务无关*/String pageAction = request.getParameter("pageAction");String value = request.getParameter("pageKey");/**获取下标判断分页状态*/int index = PageState.getOrdinal(pageAction);Page page = null;/*** index < 1 只有二种状态* 1 当首次调用时,分页状态类中没有值为 NULL 返回 -1* 2 当页面设置每页显示多少条: index=0,当每页显示多少条时,分页类要重新计算* */Page sessionPage = getPage(request);if(index < 1){page =PageUtil.inintPage(oracleSql,totalCount,index,value,sessionPage);}else{page =PageUtil.execPage(index,value,sessionPage);}setSession(request,page);return page;}private Page getPage(HttpServletRequest request) {Page page =(Page)request.getSession().getAttribute(PageUtil.SESSION_PAGE_KEY);if(page == null){page = new Page();}return page;}private void setSession(HttpServletRequest request,Page page) {request.getSession().setAttribute(PageUtil.SESSION_PAGE_KEY,p age);}}UserRowMapper.javapackage com.liuzd.sj.dao;import java.sql.ResultSet;import java.sql.SQLException;import org.springframework.jdbc.core.RowMapper;import er;public class UserRowMapper implements RowMapper<User> {public UserRowMapper(){}public User mapRow(ResultSet rs, int index) throws SQLException {User user = new User(rs.getString("id"),rs.getString("name"),rs.getString("password"),rs.getString("address"),rs.getString("sex"),rs.getInt("age"));return user;}}UserDAOImpl.javapackage com.liuzd.sj.dao.impl;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.List;import javax.annotation.Resource;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.PreparedStatementSetter;import org.springframework.stereotype.Repository;import erDAO;import erRowMapper;import er;@Repository("userDao")public class UserDAOImpl implements UserDAO{private static final String INSERT = "insert intousers(id,name,age,sex,address,password)VALUES(?,?,?,?,?,?)";private static final String UPDATE = "update users setname=?,age=?,sex=?,address=?,password=? where id=?";private static final String GET = "select * from users where id=?";private static final String CHECK = "select count(1) from users where name=? and password=?";private static final String SELECT = "select * from users";private static final String DEL = "delete users where id=?";private org.springframework.jdbc.core.JdbcTemplate jdbcTemplate;public org.springframework.jdbc.core.JdbcTemplate getJdbcTemplate() {return jdbcTemplate;}@Resourcepublic void setJdbcTemplate(org.springframework.jdbc.core.JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void addUser(final User user) {getJdbcTemplate().update(INSERT, new PreparedStatementSetter(){public void setValues(PreparedStatement ps)throws SQLException {int i = 0;ps.setString(++i, user.getId());ps.setString(++i, user.getName());ps.setInt(++i, user.getAge());ps.setString(++i,user.getSex());ps.setString(++i,user.getAddress());ps.setString(++i,user.getPassword());}});}public int checkUserExits(User user) {return getJdbcTemplate().queryForInt(CHECK,user.getName(),user.getPassword());}public void delUser(User user) {getJdbcTemplate().update(DEL, user.getId());}public void editUser(final User user) {getJdbcTemplate().update(UPDATE, new PreparedStatementSetter(){public void setValues(PreparedStatement ps)throws SQLException {int i = 0;ps.setString(++i, user.getName());ps.setInt(++i, user.getAge());ps.setString(++i,user.getSex());ps.setString(++i,user.getAddress());ps.setString(++i,user.getPassword());ps.setString(++i, user.getId());}});}public List<User> getAllUser() {return getJdbcTemplate().query(SELECT, new BeanPropertyRowMapper<User>(User.class));}public User getUserById(User user) {return getJdbcTemplate().queryForObject(GET, new UserRowMapper(),user.getId());}public int pageCounts(String querySql) {return getJdbcTemplate().queryForInt("select count(1) from("+querySql+")");}public List<User> pageList(String querySql) {return getJdbcTemplate().query(querySql, new UserRowMapper());}}UserDAOImpl2.javapackage com.liuzd.sj.dao.impl;import java.util.List;import java.util.Map;import javax.annotation.Resource;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.stereotype.Repository;import erDAO;import er;import com.liuzd.util.BeanToMapUtil;@Repository("userDao2")public class UserDAOImpl2 implements UserDAO{private static final String INSERT = "insert intousers(id,name,age,sex,address,password)VALUES(:id,:name,:age,:sex,:ad dress,:password)";private static final String UPDATE = "update users setname=:name,age=:age,sex=:sex,address=:address,password=:password where id=:id";private static final String GET = "select * from users where id=?";private static final String CHECK = "select count(1) from users where name=? and password=?";private static final String SELECT = "select * from users";private static final String DEL = "delete users where id=?";privateorg.springframework.jdbc.core.simple.SimpleJdbcTemplate simpleJdbcTemplate;public org.springframework.jdbc.core.simple.SimpleJdbcTemplate getSimpleJdbcTemplate() {return simpleJdbcTemplate;}@Resourcepublic void setSimpleJdbcTemplate(org.springframework.jdbc.core.simple.SimpleJdbcTemplate simpleJdbcTemplate) {this.simpleJdbcTemplate = simpleJdbcTemplate;}public void addUser(final User user) {Map<String,Object> userMap =BeanToMapUtil.beanToMap(user);getSimpleJdbcTemplate().update(INSERT, userMap);}public int checkUserExits(User user) {return getSimpleJdbcTemplate().queryForInt(CHECK, user.getName(),user.getPassword());}public void delUser(User user) {getSimpleJdbcTemplate().update(DEL, user.getId());}public void editUser(final User user) {Map<String,Object> userMap =BeanToMapUtil.beanToMap(user);getSimpleJdbcTemplate().update(UPDATE, userMap);}public List<User> getAllUser() {return getSimpleJdbcTemplate().query(SELECT, new BeanPropertyRowMapper<User>(User.class));}public User getUserById(User user) {return getSimpleJdbcTemplate().queryForObject(GET, new BeanPropertyRowMapper<User>(User.class),user.getId());}public int pageCounts(String querySql) {return getSimpleJdbcTemplate().queryForInt("select count(1) from("+querySql+")");}public List<User> pageList(String querySql) {return getSimpleJdbcTemplate().query(querySql, new BeanPropertyRowMapper<User>(User.class));}}springmvc.xml<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:p="/schema/p"xmlns:context="/schema/context"xmlns:mvc="/schema/mvc"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/context/schema/context/spring-context-3.0.xsd /schema/mvc/schema/mvc/spring-mvc-3.0.xsd"><!--自动搜索@Controller标注的类用于指明系统从哪个路径下寻找controller,然后提前初始化这些对象。

SpringBoot:实现MyBatis分页

SpringBoot:实现MyBatis分页

SpringBoot:实现MyBatis分页综合概述想必⼤家都有过这样的体验,在使⽤Mybatis时,最头痛的就是写分页了,需要先写⼀个查询count的select语句,然后再写⼀个真正分页查询的语句,当查询条件多了之后,会发现真的不想花双倍的时间写 count 和 select,幸好我们有 pagehelper 分页插件,pagehelper 是⼀个强⼤实⽤的 MyBatis 分页插件,可以帮助我们快速的实现MyBatis分页功能,⽽且pagehelper有个优点是,分页和Mapper.xml完全解耦,并以插件的形式实现,对Mybatis执⾏的流程进⾏了强化,这有效的避免了我们需要直接写分页SQL语句来实现分页功能。

那么,接下来我们就来⼀起体验下吧。

实现案例接下来,我们就通过实际案例来讲解如何使⽤pagehelper来实现MyBatis分页,为了避免重复篇幅,此篇教程的源码基于《》⼀篇的源码实现,读者请先参考并根据教程链接先⾏获取基础源码和数据库内容。

添加相关依赖⾸先,我们需要在 pom.xml ⽂件中添加分页插件依赖包。

pom.xml<!-- pagehelper --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.5</version></dependency>添加相关配置然后在 application.yml 配置⽂件中添加分页插件有关的配置。

application.yml# pagehelperpagehelper:helperDialect: mysqlreasonable: truesupportMethodsArguments: trueparams: count=countSql编写分页代码⾸先,在 DAO 层添加⼀个分页查找⽅法。

解决mybatisplus分页查询有条数,total和pages都是零的问题

解决mybatisplus分页查询有条数,total和pages都是零的问题

解决mybatisplus分页查询有条数,total和pages都是零的问题⼀. 问题还原1. Controller代码部分Page<FixedAssetsEntity> pageForPlus = getPage();Page<FixedAssetsEntity> fixedAssetsEntityPage = fixedAssetsService.selectPage(pageForPlus);2.spring-mybatis.xml中的sqlSessionFactory配置<bean id="sqlSessionFactory"class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"><!-- 配置数据源 --><property name="dataSource" ref="dataSource" /><!-- ⾃动扫描 Xml ⽂件位置 --><property name="mapperLocations" value="classpath*:mapping/**/*.xml" /><!-- 配置 Mybatis 配置⽂件(可⽆) --><property name="configLocation" value="classpath:mybatis-config.xml" /><!-- 配置包别名,⽀持通配符 * 或者 ; 分割 --><property name="typeAliasesPackage" value="com.syb.dto,com.syb.sys.entity" /><!-- 枚举属性配置扫描,⽀持通配符 * 或者 ; 分割 --><!-- <property name="typeEnumsPackage" value="com.baomidou.springmvc.entity.*.enums"/> --><!-- 以上配置和传统 Mybatis ⼀致 --><!-- MP 全局配置注⼊ --><property name="globalConfig" ref="globalConfig" /></bean>打断点查看fixedAssetsEntityPage,records条⽬正确,但是total和pages都是0⼆. 解决查阅官⽅⽂档发现,缺少了分页插件的配置,在sqlSessionFactory中添加分页插件,添加后为<bean id="sqlSessionFactory"class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"><!-- 配置数据源 --><property name="dataSource" ref="dataSource" /><!-- ⾃动扫描 Xml ⽂件位置 --><property name="mapperLocations" value="classpath*:mapping/**/*.xml" /><!-- 配置 Mybatis 配置⽂件(可⽆) --><property name="configLocation" value="classpath:mybatis-config.xml" /><!-- 配置包别名,⽀持通配符 * 或者 ; 分割 --><property name="typeAliasesPackage" value="com.syb.dto,com.syb.sys.entity" /><!-- 枚举属性配置扫描,⽀持通配符 * 或者 ; 分割 --><!-- <property name="typeEnumsPackage" value="com.baomidou.springmvc.entity.*.enums"/> --><!-- 以上配置和传统 Mybatis ⼀致 --><!-- MP 全局配置注⼊ --><property name="plugins"><array><!-- 分页插件配置 --><bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"><property name="dialectType" value="mysql" /></bean></array></property><property name="globalConfig" ref="globalConfig" /></bean>运⾏程序,打断点查看,total和page已经正常显⽰补充知识:mybatisPlus分页查询多次查到相同数据的问题⼀、问题描述使⽤ mybatisPlus 3.1.0,在同⼀个⽅法内,多次调⽤同⼀个⽅法进⾏分页查询,每次查询的分页页码递增,结果每次查到的数据都⼀样。

Mybatis-Plus实现分页查询

Mybatis-Plus实现分页查询⽬录Mybatis-Plus实现分页查询技术概述分页查询是⼀项常⽤的数据库查询⽅法,⽽使⽤Mybatis-Plus的分页插件,可以为你省去更多的时间去编写复杂的数据库语句,当然,前提是你还是要懂得⼀些数据库查询语句以及Mybatis-Plus的常⽤⽅法。

之所以学习该技术,也是因为在软⼯实践中有分页查询的需求,为了能够加快开发效率,所以选择了使⽤分页插件。

难点:需要注意Mybatis-Plus不同版本的要求不同;对Mybatis-Plus的相关⽅法还是需要进⾏学习。

技术详述配置分页插件1、spring和mybatis-plus整合<!-- spring xml ⽅式 --><property name="plugins"><array><bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"><property name="sqlParser" ref="⾃定义解析类、可以没有"/><property name="dialectClazz" value="⾃定义⽅⾔类、可以没有"/><!-- COUNT SQL 解析.可以没有 --><property name="countSqlParser" ref="countSqlParser"/></bean></array></property><bean id="countSqlParser" class="com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize"><!-- 设置为 true 可以优化部分 left join 的sql --><property name="optimizeJoin" value="true"/></bean>2、spring boot和mybatis-plus整合//Spring boot⽅式@Configuration@MapperScan("mapper包名")public class MybatisPlusConfig {// 旧版@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// 设置请求的页⾯⼤于最⼤页后操作, true调回到⾸页,false 继续请求默认false// paginationInterceptor.setOverflow(false);// 设置最⼤单页限制数量,默认 500 条,-1 不受限制// paginationInterceptor.setLimit(500);// 开启 count 的 join 优化,只针对部分 left joinpaginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}// 最新版@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));return interceptor;}}⾃定义分页1、如果你的mapper没有继承BaseMapperUserMapper.java ⽅法内容public interface UserMapper {//可以继承或者不继承BaseMapper/*** <p>* 查询 : 根据state状态查询⽤户列表,分页显⽰* </p>** @param page 分页对象,xml中可以从⾥⾯进⾏取值,传递参数 Page 即⾃动分页,必须放在第⼀位(你可以继承Page实现⾃⼰的分页对象)* @param state 状态* @return 分页对象*/IPage<User> selectPageVo(Page<?> page, Integer state);}UserMapper.xml 等同于编写⼀个普通 list 查询,mybatis-plus ⾃动替你分页<!-- 下⾯给出⼀个简单的查询例⼦<select>标签就是表⽰查询,id属性是唯⼀标识符,注意要与你的mapper类的⽅法名⼀⼀对应,resultType就是获取的数据将被封装成的类型,关于mybatis的mapper.xml的语法、属性有很多种,这<select id="selectPageVo" resultType="erVo">SELECT id,name FROM user WHERE state=#{state}</select>UserServiceImpl.java 调⽤分页⽅法public IPage<User> selectUserPage(Page<User> page, Integer state) {// 不进⾏ count sql 优化,解决 MP ⽆法⾃动优化 SQL 问题,这时候你需要⾃⼰查询 count 部分// page.setOptimizeCountSql(false);// 当 total 为⼩于 0 或者设置 setSearchCount(false) 分页插件不会进⾏ count 查询// 要点!! 分页返回的对象与传⼊的对象是同⼀个return userMapper.selectPageVo(page, state);}需要注意的是:如果返回类型是 IPage 则⼊参的 IPage 不能为null,因为返回的IPage == ⼊参的IPage如果返回类型是 List 则⼊参的 IPage 可以为 null(为 null 则不分页),但需要你⼿动⼊参的IPage.setRecords(返回的 List);如果 xml 需要从 page ⾥取值,需要 page.属性获取。

mybatis分页查询语句

mybatis分页查询语句MyBatis是一个开源的持久层框架,提供了简化数据库访问的功能。

在实际应用中,我们常常需要对数据库进行分页查询,以便在大量数据中快速定位所需信息。

使用MyBatis进行分页查询可以通过两种方式实现:基于数据库的分页和基于内存的分页。

1. 基于数据库的分页查询基于数据库的分页查询是通过在SQL语句中使用LIMIT关键字来实现的。

LIMIT关键字可以指定查询结果的起始位置和返回的行数。

例如,下面的SQL语句可以查询从第10行开始的10条记录:```SELECT * FROM table_name LIMIT 10, 10;```其中,10表示起始位置,10表示返回的行数。

2. 基于内存的分页查询基于内存的分页查询是通过将查询结果全部加载到内存中,然后在内存中进行分页操作来实现的。

这种方式适用于数据量较小的情况。

在MyBatis中,可以通过设置fetchSize属性来控制每次从数据库中读取的记录数,然后在内存中进行分页操作。

3. 使用RowBounds进行分页查询除了上述两种方式,MyBatis还提供了一种更简洁的分页查询方式,即使用RowBounds进行分页查询。

RowBounds是MyBatis框架中的一个辅助类,用于指定查询结果的起始位置和返回的行数。

在SQL映射文件中,可以使用RowBounds来指定分页参数。

例如,下面的代码演示了如何使用RowBounds进行分页查询:```List<User> getUsers(SqlSession sqlSession, int offset, int limit) {RowBounds rowBounds = new RowBounds(offset, limit);return sqlSession.selectList("getUserList", null, rowBounds); }```其中,getUserList是SQL映射文件中定义的查询语句的ID。

mybatis分页插件PageHelper使用

private Date createdate;private Date lastlogintime;private List<Role> roleList;public List<Role> getRoleList() {return roleList;}public void setRoleList(List<Role> roleList) {this.roleList = roleList;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname == null ? null : uname.trim();}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd == null ? null : pwd.trim();}public String getName() {return name;}public void setName(String name) { = name == null ? null : name.trim();}public Integer getSex() {return sex;}public void setSex(Integer sex) {this.sex = sex;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone == null ? null : phone.trim();}public String getCompany() {return company;}public void setCompany(String company) {pany = company == null ? null : company.trim(); }public String getJobtitle() {return jobtitle;}public void setJobtitle(String jobtitle) {this.jobtitle = jobtitle == null ? null : jobtitle.trim();}public String getBirth() {return birth;}public void setBirth(String birth) {this.birth = birth == null ? null : birth.trim();private boolean isFirstPage = false;是否为最后⼀页private boolean isLastPage = false;是否有前⼀页private boolean hasPreviousPage = false;是否有下⼀页private boolean hasNextPage = false;导航页码数private int navigatePages;所有导航页号private int[] navigatepageNums;View Code。

mybatis-plus分页查询

mybatis-plus分页查询在springboot中整合mybatis-plus 按照官⽅⽂档进⾏的配置: 引⼊依赖:1<!-- 引⼊mybatisPlus -->2 <dependency>3<groupId>com.baomidou</groupId>4<artifactId>mybatis-plus-boot-starter</artifactId>5<version>3.2.0</version>6</dependency>7<!-- 引⼊mysql驱动包 -->8<dependency>9<groupId>mysql</groupId>10<artifactId>mysql-connector-java</artifactId>11<version>5.1.27</version>12</dependency>13<!-- 引⼊Druid依赖,阿⾥巴巴所提供的数据源 -->14<dependency>15<groupId>com.alibaba</groupId>16<artifactId>druid</artifactId>17<version>1.0.29</version>18 </dependency> 在application.yml配置1 spring:2 datasource:3 type: com.alibaba.druid.pool.DruidDataSource4 driver-class-name: com.mysql.jdbc.Driver5 url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-86 username: root7 password: 123456 在启动类上⾯添加@MapperScan注解,扫描mapper包1 @SpringBootApplication2 @MapperScan("com.qiao.demo02.mapper")3public class SpringbootDemo02Application {45public static void main(String[] args) {6 SpringApplication.run(SpringbootDemo02Application.class, args);7 }89 } 新建User和UserMapper user类1 @Data2public class User {3 @TableId4private Integer userId;5private String userName;6private Integer userAge;7private String userEmail;8 }View Code UserMapper接⼝1public interface UserMapper extends BaseMapper<User> {23 }View Code 最重要的是继承BaseMapper<E>接⼝:⾥⾯声明了很强⼤的CRUD⽅法1public interface BaseMapper<T> extends Mapper<T> {2int insert(T entity);34int deleteById(Serializable id);56int deleteByMap(@Param("cm") Map<String, Object> columnMap);78int delete(@Param("ew") Wrapper<T> wrapper);910int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);1112int updateById(@Param("et") T entity);1314int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);1516 T selectById(Serializable id);1718 List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);1920 List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);2122 T selectOne(@Param("ew") Wrapper<T> queryWrapper);2324 Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);2526 List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);2728 List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);2930 List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);3132 IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);3334 IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);35 }View Code分页查询 这点官⽅⽂档讲的也很详细: 新建⼀个config包,在⾥⾯建⼀个MybatisPlus配置类返回⼀个分页拦截器1package com.qiao.demo02.config;23 @Configuration4 @ConditionalOnClass(value = {PaginationInterceptor.class})5public class MybatisPlusConfig {6 @Bean7public PaginationInterceptor paginationInterceptor() {8 PaginationInterceptor paginationInterceptor = new PaginationInterceptor();9return paginationInterceptor;10 }11 } 这样就能使⽤mybatis的分页功能了 Junit测试1 @Resource2private UserMapper userMapper;3 @Test4public void queryUserForPage(){5 IPage<User> userPage = new Page<>(2, 2);//参数⼀是当前页,参数⼆是每页个数6 userPage = userMapper.selectPage(userPage, null);7 List<User> list = userPage.getRecords();8for(User user : list){9 System.out.println(user);10 }11 } Controller返回json串 先定义⼀个包装类UserVo,⽤来保存分页所需要的数据1package com.qiao.demo02.vo;23 @Data4public class UserVo {5private Integer current;6private Integer size;7private Long total;8private List<User> userList;9 } 然后在控制器编写代码,这⾥省略了service层,实际开发业务代码写在service层,Controller只负责:接受参数、调⽤service层⽅法处理业务逻辑,返回结果 Controller类贴上了@RestController注解1 @GetMapping("queryUser")2public UserVo queryList(Integer current, Integer size) {3/**4 * 这些代码应该写在service层5*/6 UserVo userVo = new UserVo();7 IPage<User> page = new Page<>(current, size);8 userMapper.selectPage(page, null);9 userVo.setCurrent(current);10 userVo.setSize(size);11 userVo.setTotal(page.getTotal());12 userVo.setUserList(page.getRecords());13return userVo;14 } 附上结果,前端直接处理json数据即可。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档