由于为了后续使用SpringBoot,本人还是推荐使用Java配置类来操作,但是这里还是提一下XML配置。
(本文项目基于第六节Mybatis集成Spring操作)
XML配置方式
使用XML文件来配置Mybatis的PageHelper分页插件:
mybatis-configuration:(mybatis的全局配置文件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?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>
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="offsetAsPageNum" value="true"/> <property name="helperDialect" value="mysql"/> <property name="rowBoundsWithCount" value="true"/> <property name="reasonable" value="true"/> </plugin> </plugins> </configuration>
|
Java配置类方式
完整的配置类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| @Configuration @PropertySource(value = "classpath:application.properties") @ComponentScan(basePackages = "com.ooyhao.mybatis") @MapperScan(basePackages = {"com.ooyhao.mybatis.mapper"}) @EnableTransactionManagement public class AppConfig {
@Value("${jdbc.url}") private String url;
@Value("${jdbc.driver}") private String driverClassName;
@Value("${jdbc.username}") private String username;
@Value("${jdbc.password}") private String password;
@Value("${mybatis.configuration}") private String mybatisConfiguration;
@Value("${mybatis.mapperLocations}") private String mybatisMapperLocations;
@Value("${mybatis.typeAliasesPackage}") private String mybatisTypeAliasesPackage;
@Bean public DataSource dataSource(){ DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setUrl(url); druidDataSource.setDriverClassName(driverClassName); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; }
@Bean public PageInterceptor pageInterceptor(){ PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); properties.setProperty("helperDialect","mysql");
properties.setProperty("offsetAsPageNum","true"); properties.setProperty("rowBoundsWithCount","true"); properties.setProperty("reasonable","true"); properties.setProperty("supportMethodsArguments","true"); pageInterceptor.setProperties(properties); properties.setProperty("pageSizeZero","true"); return pageInterceptor; }
@Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); ClassPathResource resource = new ClassPathResource(mybatisConfiguration); sqlSessionFactoryBean.setConfigLocation(resource); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources(mybatisMapperLocations); sqlSessionFactoryBean.setMapperLocations(resources); sqlSessionFactoryBean.setTypeAliasesPackage(mybatisTypeAliasesPackage); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor()}); sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactoryBean.getObject().getConfiguration().setLogImpl(StdOutImpl.class); sqlSessionFactoryBean.getObject().getConfiguration().setCacheEnabled(true); return sqlSessionFactoryBean; }
@Bean public DataSourceTransactionManager transactionManager(DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
|
提示:
- 添加了
PageInterceptor
组件
- 通过
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor()});
设置到SqlSessionFactoryBean中
开启了这个properties.setProperty("supportMethodsArguments","true");
则表示可以通过Mapper来进行参数传递,实现分页,如下:
1
| List<Role> findByPage(@Param("pageNum") int pageNum,@Param("pageSize") int pageSize);
|
xml文件不需要修改,只需要在参数上添加形参即可。
PageHelper的PageInterceptor的参数说明:一下是PageParams类中的setProperties方法的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public void setProperties(Properties properties) { String offsetAsPageNum = properties.getProperty("offsetAsPageNum"); this.offsetAsPageNum = Boolean.parseBoolean(offsetAsPageNum); String rowBoundsWithCount = properties.getProperty("rowBoundsWithCount"); this.rowBoundsWithCount = Boolean.parseBoolean(rowBoundsWithCount); String pageSizeZero = properties.getProperty("pageSizeZero"); this.pageSizeZero = Boolean.parseBoolean(pageSizeZero); String reasonable = properties.getProperty("reasonable"); this.reasonable = Boolean.parseBoolean(reasonable); String supportMethodsArguments = properties.getProperty("supportMethodsArguments"); this.supportMethodsArguments = Boolean.parseBoolean(supportMethodsArguments); String countColumn = properties.getProperty("countColumn"); if(StringUtil.isNotEmpty(countColumn)){ this.countColumn = countColumn; } PageObjectUtil.setParams(properties.getProperty("params")); }
|
测试:
下面是测试结果,以及获取PageInfo中的各个参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class AppTest { AnnotationConfigApplicationContext context = null; @Before public void init(){ context = new AnnotationConfigApplicationContext(AppConfig.class); }
@Test public void testFindByPage(){
RoleService bean = context.getBean(RoleService.class); List<Role> page = bean.findByPage(2, 2, true); PageInfo<Role> pageInfo = new PageInfo<>(page); List<Role> list = pageInfo.getList(); System.out.println(JSONObject.toJSONString(list)); System.out.println(JSONObject.toJSON(list)); System.out.println("total:"+pageInfo.getTotal()); System.out.println("pages:"+pageInfo.getPages()); System.out.println("navigatepageNums:"+Arrays.toString(pageInfo.getNavigatepageNums())); System.out.println("navigateFirstPage:"+pageInfo.getNavigateFirstPage()); System.out.println("navigateLastPage:"+pageInfo.getNavigateLastPage()); System.out.println("navigatePages:"+pageInfo.getNavigatePages()); System.out.println("pageNum:"+pageInfo.getPageNum()); System.out.println("prePage:"+pageInfo.getPrePage()); System.out.println("nextPage:"+pageInfo.getNextPage()); System.out.println("pageSize:"+pageInfo.getPageSize()); System.out.println("startRow:"+pageInfo.getStartRow()); System.out.println("endRow:"+pageInfo.getEndRow()); } }
|
提示:
List list = pageInfo.getList();我们通过打印这个list对象是无法正常打印出Role对象的数据,是因为Page对象继承自ArrayList,并且重写了toString方法。我们可以通过迭代循环打印出来。如下图:
这里由于循环打印才能看到Role对象的真实面部,个人觉得麻烦,所以使用了fastJson格式化为Json,但是发现一个之前没有留意的问题:
通过上面打印出的结果可以发现,list既然是Page对象,但是我们可以看到Page类中有诸多属性,为何通过JSON格式化工具之后,就没有了呢?通过查询fastJson的toJson源码就可以发现奥秘了,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static Object toJSON(Object javaObject, SerializeConfig config) { ...... if (javaObject instanceof Collection) { Collection<Object> collection = (Collection<Object>) javaObject; JSONArray array = new JSONArray(collection.size()); for (Object item : collection) { Object jsonValue = toJSON(item, config); array.add(jsonValue); } return array; } ...... String text = JSON.toJSONString(javaObject); return JSON.parse(text); }
|
里面有这样一个判断,如果对象是Collection或其子类,则强转为Collection,所以我们会发现,在使用JSONObject.toJson或是toJsonString的时候,不管是ArrayList还是Page中的属性都没有了,这是因为取的是Collection。对于数据存储,需要进一步研究Collection系列集合,暂不涉及。
Page对象源码
下面我们看一下Page对象源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
| public class Page<E> extends ArrayList<E> implements Closeable { private static final long serialVersionUID = 1L;
private int pageNum;
private int pageSize;
private int startRow;
private int endRow;
private long total;
private int pages;
private boolean count = true;
private Boolean reasonable;
private Boolean pageSizeZero;
private String countColumn;
private String orderBy;
private boolean orderByOnly;
public Page() { super(); }
public Page(int pageNum, int pageSize) { this(pageNum, pageSize, true, null); }
public Page(int pageNum, int pageSize, boolean count) { this(pageNum, pageSize, count, null); }
private Page(int pageNum, int pageSize, boolean count, Boolean reasonable) { super(0); if (pageNum == 1 && pageSize == Integer.MAX_VALUE) { pageSizeZero = true; pageSize = 0; } this.pageNum = pageNum; this.pageSize = pageSize; this.count = count; calculateStartAndEndRow(); setReasonable(reasonable); }
public Page(int[] rowBounds, boolean count) { super(0); if (rowBounds[0] == 0 && rowBounds[1] == Integer.MAX_VALUE) { pageSizeZero = true; this.pageSize = 0; } else { this.pageSize = rowBounds[1]; this.pageNum = rowBounds[1] != 0 ? (int) (Math.ceil(((double) rowBounds[0] + rowBounds[1]) / rowBounds[1])) : 0; } this.startRow = rowBounds[0]; this.count = count; this.endRow = this.startRow + rowBounds[1]; }
public List<E> getResult() { return this; }
public int getPages() { return pages; }
public Page<E> setPages(int pages) { this.pages = pages; return this; }
public int getEndRow() { return endRow; }
public Page<E> setEndRow(int endRow) { this.endRow = endRow; return this; }
public int getPageNum() { return pageNum; }
public Page<E> setPageNum(int pageNum) { this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum; return this; }
public int getPageSize() { return pageSize; }
public Page<E> setPageSize(int pageSize) { this.pageSize = pageSize; return this; }
public int getStartRow() { return startRow; }
public Page<E> setStartRow(int startRow) { this.startRow = startRow; return this; }
public long getTotal() { return total; }
public void setTotal(long total) { this.total = total; if (total == -1) { pages = 1; return; } if (pageSize > 0) { pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1)); } else { pages = 0; } if ((reasonable != null && reasonable) && pageNum > pages) { pageNum = pages; calculateStartAndEndRow(); } }
public Boolean getReasonable() { return reasonable; }
public Page<E> setReasonable(Boolean reasonable) { if (reasonable == null) { return this; } this.reasonable = reasonable; if (this.reasonable && this.pageNum <= 0) { this.pageNum = 1; calculateStartAndEndRow(); } return this; }
public Boolean getPageSizeZero() { return pageSizeZero; }
public Page<E> setPageSizeZero(Boolean pageSizeZero) { if (pageSizeZero != null) { this.pageSizeZero = pageSizeZero; } return this; } public String getOrderBy() { return orderBy; }
public <E> Page<E> setOrderBy(String orderBy) { this.orderBy = orderBy; return (Page<E>) this; }
public boolean isOrderByOnly() { return orderByOnly; }
public void setOrderByOnly(boolean orderByOnly) { this.orderByOnly = orderByOnly; }
private void calculateStartAndEndRow() { this.startRow = this.pageNum > 0 ? (this.pageNum - 1) * this.pageSize : 0; this.endRow = this.startRow + this.pageSize * (this.pageNum > 0 ? 1 : 0); }
public boolean isCount() { return this.count; }
public Page<E> setCount(boolean count) { this.count = count; return this; }
public Page<E> pageNum(int pageNum) { this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum; return this; }
public Page<E> pageSize(int pageSize) { this.pageSize = pageSize; calculateStartAndEndRow(); return this; }
public Page<E> count(Boolean count) { this.count = count; return this; }
public Page<E> reasonable(Boolean reasonable) { setReasonable(reasonable); return this; }
public Page<E> pageSizeZero(Boolean pageSizeZero) { setPageSizeZero(pageSizeZero); return this; }
public Page<E> countColumn(String columnName) { this.countColumn = columnName; return this; }
public PageInfo<E> toPageInfo() { PageInfo<E> pageInfo = new PageInfo<E>(this); return pageInfo; }
public <E> Page<E> doSelectPage(ISelect select) { select.doSelect(); return (Page<E>) this; }
public <E> PageInfo<E> doSelectPageInfo(ISelect select) { select.doSelect(); return (PageInfo<E>) this.toPageInfo(); }
public long doCount(ISelect select) { this.pageSizeZero = true; this.pageSize = 0; select.doSelect(); return this.total; }
public String getCountColumn() { return countColumn; }
public void setCountColumn(String countColumn) { this.countColumn = countColumn; }
@Override public String toString() { return "Page{" + "count=" + count + ", pageNum=" + pageNum + ", pageSize=" + pageSize + ", startRow=" + startRow + ", endRow=" + endRow + ", total=" + total + ", pages=" + pages + ", reasonable=" + reasonable + ", pageSizeZero=" + pageSizeZero + '}'; }
@Override public void close() { PageHelper.clearPage(); } }
|