├── .gitignore
├── deploy.sh
├── src
├── test
│ ├── resources
│ │ ├── sql
│ │ │ └── scheml.sql
│ │ ├── spring
│ │ │ ├── test.properties
│ │ │ └── test-context.xml
│ │ ├── log4j.properties
│ │ └── mapper
│ │ │ └── ResourcesMapper.xml
│ └── java
│ │ └── org
│ │ └── mybatis
│ │ └── pagination
│ │ ├── service
│ │ ├── UtilsTest.java
│ │ └── MapperTest.java
│ │ ├── mapper
│ │ └── ResourcesMapper.java
│ │ └── domain
│ │ ├── Resources.java
│ │ └── ResourcesCriteria.java
└── main
│ └── java
│ └── org
│ └── mybatis
│ └── pagination
│ ├── dialect
│ ├── DBMS.java
│ ├── Dialect.java
│ ├── db
│ │ ├── SybaseDialect.java
│ │ ├── DerbyDialect.java
│ │ ├── H2Dialect.java
│ │ ├── HSQLDialect.java
│ │ ├── MySQLDialect.java
│ │ ├── PostgreSQLDialect.java
│ │ ├── SQLServerDialect.java
│ │ ├── OracleDialect.java
│ │ ├── DB2Dialect.java
│ │ └── SQLServer2005Dialect.java
│ └── DialectClient.java
│ ├── extra
│ └── MyBatisRepository.java
│ ├── mvc
│ ├── TableParam.java
│ ├── DataTablesResultSet.java
│ └── TableParamArgumentResolver.java
│ ├── dto
│ ├── datatables
│ │ ├── SortDirection.java
│ │ ├── SortField.java
│ │ ├── SearchField.java
│ │ └── PagingCriteria.java
│ └── PageMyBatis.java
│ ├── helpers
│ ├── StringHelper.java
│ └── CountHelper.java
│ ├── PagingParametersFinder.java
│ ├── PaginationExecutor.java
│ └── PaginationInterceptor.java
├── LICENSE
├── Readme.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/*
2 | *.iml
3 | *.class
4 | target/*
5 | .idea
6 | /src/main/java/org/.DS_Store
7 | .DS_Store
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | /Users/yfyang/Applications/apache-maven-3.0.5/bin/mvn clean deploy -Dmaven.test.skip=true
--------------------------------------------------------------------------------
/src/test/resources/sql/scheml.sql:
--------------------------------------------------------------------------------
1 | create table res
2 | (
3 | id varchar(64) not null comment '主键',
4 | name varchar(120) comment '资源名称',
5 | type varchar(120) comment '资源类型',
6 | path varchar(120) comment '资源地址',
7 | action varchar(120) comment '资源请求',
8 | controller varchar(120) comment '资源控制',
9 | status tinyint comment '状态',
10 | primary key (id)
11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/pagination/service/UtilsTest.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.service;
2 |
3 | import com.google.common.base.CaseFormat;
4 | import org.junit.Test;
5 |
6 | /**
7 | *
8 | * .
9 | *
10 | *
11 | * @author walter yang
12 | * @version 1.0 2013-09-24 12:20 AM
13 | * @since JDK 1.5
14 | */
15 | public class UtilsTest {
16 |
17 | @Test
18 | public void testHump() throws Exception {
19 |
20 | System.out.println( CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "helloDoMyword"));
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/DBMS.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect;
6 |
7 | /**
8 | *
9 | * 数据库类型.
10 | *
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2012-05-08 上午11:36
14 | * @since JDK 1.5
15 | */
16 | public enum DBMS {
17 | MYSQL,
18 | ORACLE,
19 | DB2,
20 | H2,
21 | HSQL,
22 | POSTGRE,
23 | SQLSERVER,
24 | SQLSERVER2005,
25 | SYBASE,
26 | /**
27 | * 自定义
28 | */
29 | EX
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/extra/MyBatisRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.extra;
6 |
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | *
14 | * 标识MyBatis的DAO,方便{@link org.mybatis.spring.mapper.MapperScannerConfigurer}的扫描。.
15 | *
16 | *
17 | * @author poplar.yfyang
18 | * @version 1.0 2012-10-27 7:05 PM
19 | * @since JDK 1.5
20 | */
21 | @Retention(RetentionPolicy.RUNTIME)
22 | @Target(ElementType.TYPE)
23 | public @interface MyBatisRepository {
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/mvc/TableParam.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.mvc;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | /**
14 | *
15 | * Spring MVC argument resolver annotation.
16 | *
17 | *
18 | * @author mumu@yfyang
19 | * @version 1.0 2013-09-05 10:43 PM
20 | * @since JDK 1.5
21 | */
22 | @Target(ElementType.PARAMETER)
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Documented
25 | public @interface TableParam {
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/resources/spring/test.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2011-2012 NOO.com. All Rights Reserved.
3 | # This software for customer relationship management system, developed by Noo team.
4 | # Software code and design for the team, copy rights reserved.
5 | #
6 | driverClass=com.mysql.jdbc.Driver
7 | jdbcurl=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
8 | username=rhea
9 | password=rhea@123
10 | minPoolSize=10
11 | acquireRetryAttempts=50
12 | idleConnectionTestPeriod=60
13 | acquireIncrement=3
14 | maxIdleTime=60
15 | initialPoolSize=10
16 | maxPoolSize=100
17 | # \u4E8B\u52A1\u4F20\u64AD\u4EE5\u53CA\u9694\u79BB\u7EA7\u522B
18 | transaction.propagation=REQUIRED
19 | transaction.level=ISOLATION_READ_UNCOMMITTED
20 |
21 | database_dialect=MYSQL
22 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/Dialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect;
6 |
7 | /**
8 | * 类似hibernate的Dialect,但只精简出分页部分
9 | *
10 | * @author poplar.yfyang
11 | * @version 1.0 2011-11-18 下午12:31
12 | * @since JDK 1.5
13 | */
14 | public interface Dialect {
15 |
16 | /**
17 | * 数据库本身是否支持分页当前的分页查询方式
18 | * 如果数据库不支持的话,则不进行数据库分页
19 | *
20 | * @return true:支持当前的分页查询方式
21 | */
22 | public boolean supportsLimit();
23 |
24 | /**
25 | * 将sql转换为分页SQL,分别调用分页sql
26 | *
27 | * @param sql SQL语句
28 | * @param offset 开始条数
29 | * @param limit 每页显示多少纪录条数
30 | * @return 分页查询的sql
31 | */
32 | public String getLimitString(String sql, int offset, int limit);
33 |
34 | /**
35 | * 将sql转换为总记录数SQL
36 | * @param sql SQL语句
37 | * @return 总记录数的sql
38 | */
39 | public String getCountString(String sql);
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 yfyang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2011-2012 NOO.com. All Rights Reserved.
3 | # This software for customer relationship management system, developed by Noo team.
4 | # Software code and design for the team, copy rights reserved.
5 | #
6 | log4j.rootLogger = DEBUG , stdout
7 |
8 | ### print _log to console ###
9 | log4j.appender.stdout = org.apache.log4j.ConsoleAppender
10 | log4j.appender.stdout.Target = System.out
11 | log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
12 | log4j.appender.stdout.layout.ConversionPattern = %d %p [%c] - <%m>%n
13 |
14 | # SqlMap logging configuration...
15 | log4j.logger.com.ibatis=debug
16 | log4j.logger.com.ibatis.db=debug
17 | log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
18 | log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=debug
19 | log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=debug
20 | log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=debug
21 | log4j.logger.com.ibatis.common.util.StopWatch=debug
22 |
23 |
24 | log4j.logger.java.sql.Connection=debug
25 | log4j.logger.java.sql.Statement=error
26 | log4j.logger.java.sql.PreparedStatement=debug
27 | log4j.logger.java.sql.ResultSet=error
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dto/datatables/SortDirection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dto.datatables;
6 |
7 | /**
8 | *
9 | * sort's direction.
10 | *
11 | *
12 | * @author mumu@yfyang
13 | * @version 1.0 2013-09-05 10:41 PM
14 | * @since JDK 1.5
15 | */
16 | public enum SortDirection {
17 | /**
18 | * The ASC.
19 | */
20 | ASC("asc"),
21 | /**
22 | * The DESC.
23 | */
24 | DESC("desc");
25 | private String direction;
26 |
27 | private SortDirection(String direction) {
28 | this.direction = direction;
29 | }
30 |
31 | /**
32 | * Value of case insensitive.
33 | *
34 | * @param value the value
35 | * @return the sort direction
36 | */
37 | public static SortDirection valueOfCaseInsensitive(String value) {
38 | String valueUpper = value.toUpperCase();
39 | return SortDirection.valueOf(valueUpper);
40 | }
41 |
42 | /**
43 | * Gets direction.
44 | *
45 | * @return the direction
46 | */
47 | public String getDirection() {
48 | return this.direction;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dto/datatables/SortField.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dto.datatables;
6 |
7 | /**
8 | *
9 | * the sort's filed define.
10 | *
11 | *
12 | * @author mumu@yfyang
13 | * @version 1.0 2013-09-05 10:39 PM
14 | * @since JDK 1.5
15 | */
16 | public final class SortField {
17 | /** field name */
18 | private final String field;
19 | /** sort direction */
20 | private final SortDirection direction;
21 |
22 | /**
23 | * Instantiates a new Sort field.
24 | *
25 | * @param field the field
26 | * @param direction the direction
27 | */
28 | public SortField(String field, SortDirection direction) {
29 | this.field = field;
30 | this.direction = direction;
31 | }
32 |
33 | /**
34 | * Instantiates a new Sort field.
35 | *
36 | * @param field the field
37 | * @param direction the direction
38 | */
39 | public SortField(String field, String direction) {
40 | this.field = field;
41 | this.direction = SortDirection.valueOfCaseInsensitive(direction);
42 | }
43 |
44 | /**
45 | * Gets field.
46 | *
47 | * @return the field
48 | */
49 | public String getField() {
50 | return field;
51 | }
52 |
53 | /**
54 | * Gets direction.
55 | *
56 | * @return the direction
57 | */
58 | public SortDirection getDirection() {
59 | return direction;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/SybaseDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * Sybase数据库分页方言实现。
11 | * 还未实现
12 | *
13 | * @author poplar.yfyang
14 | * @version 1.0 2010-10-10 下午12:31
15 | * @since JDK 1.5
16 | */
17 | public class SybaseDialect implements Dialect {
18 |
19 | public boolean supportsLimit() {
20 | return false;
21 | }
22 |
23 | @Override
24 | public String getLimitString(String sql, int offset, int limit) {
25 | return null;
26 | }
27 |
28 | /**
29 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
30 | *
31 | * 如mysql
32 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
33 | * select * from user limit :offset,:limit
34 | *
35 | *
36 | * @param sql 实际SQL语句
37 | * @param offset 分页开始纪录条数
38 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
39 | * @param limit 分页每页显示纪录条数
40 | * @param limitPlaceholder 分页纪录条数占位符号
41 | * @return 包含占位符的分页sql
42 | */
43 | public String getLimitString(String sql, int offset, String offsetPlaceholder, int limit, String limitPlaceholder) {
44 | throw new UnsupportedOperationException("paged queries not supported");
45 | }
46 |
47 | @Override
48 | public String getCountString(String querySqlString) {
49 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
50 | return "select count(1) from (" + sql + ") as tmp_count";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/DerbyDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * @author poplar.yfyang
11 | * @version 1.0 2010-10-10 下午12:31
12 | * @since JDK 1.5
13 | */
14 | public class DerbyDialect implements Dialect {
15 | @Override
16 | public boolean supportsLimit() {
17 | return false;
18 | }
19 |
20 | @Override
21 | public String getLimitString(String sql, int offset, int limit) {
22 | // return getLimitString(sql,offset,Integer.toString(offset),limit,Integer.toString(limit));
23 | throw new UnsupportedOperationException("paged queries not supported");
24 | }
25 |
26 | /**
27 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
28 | *
29 | * 如mysql
30 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
31 | * select * from user limit :offset,:limit
32 | *
33 | *
34 | * @param sql 实际SQL语句
35 | * @param offset 分页开始纪录条数
36 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
37 | * @param limit 分页每页显示纪录条数
38 | * @param limitPlaceholder 分页纪录条数占位符号
39 | * @return 包含占位符的分页sql
40 | */
41 | public String getLimitString(String sql, int offset, String offsetPlaceholder, int limit, String limitPlaceholder) {
42 | throw new UnsupportedOperationException("paged queries not supported");
43 | }
44 |
45 | @Override
46 | public String getCountString(String querySqlString) {
47 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
48 | return "select count(1) from (" + sql + ") as tmp_count";
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/H2Dialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * A dialect compatible with the H2 database.
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class H2Dialect implements Dialect {
17 |
18 | public boolean supportsLimit() {
19 | return true;
20 | }
21 |
22 | /**
23 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
24 | *
25 | * 如mysql
26 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
27 | * select * from user limit :offset,:limit
28 | *
29 | *
30 | * @param sql 实际SQL语句
31 | * @param offset 分页开始纪录条数
32 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
33 | * @param limit 分页每页显示纪录条数
34 | * @param limitPlaceholder 分页纪录条数占位符号
35 | * @return 包含占位符的分页sql
36 | */
37 | private String getLimitString(String sql, int offset, String offsetPlaceholder, int limit, String limitPlaceholder) {
38 | return sql + ((offset > 0) ? " limit " + limitPlaceholder + " offset "
39 | + offsetPlaceholder : " limit " + limitPlaceholder);
40 | }
41 |
42 | @Override
43 | public String getLimitString(String sql, int offset, int limit) {
44 | return getLimitString(sql, offset, Integer.toString(offset), limit, Integer.toString(limit));
45 | }
46 |
47 | @Override
48 | public String getCountString(String querySqlString) {
49 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
50 | return "select count(1) from (" + sql + ") as tmp_count";
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/mvc/DataTablesResultSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.mvc;
6 |
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | import org.mybatis.pagination.dto.PageMyBatis;
11 |
12 | /**
13 | *
14 | * .
15 | *
16 | *
17 | * @author mumu@yfyang
18 | * @version 1.0 2013-09-05 10:48 PM
19 | * @since JDK 1.5
20 | */
21 | public final class DataTablesResultSet {
22 | private final int sEcho;
23 | private final long iTotalRecords;
24 | private final long iTotalDisplayRecords;
25 | private final List aaData;
26 |
27 | /**
28 | * Instantiates a new Data tables result set.
29 | *
30 | * @param sEcho the pc
31 | * @param rs the rs
32 | */
33 | public DataTablesResultSet(int sEcho, PageMyBatis rs) {
34 | this.sEcho = sEcho;
35 | this.aaData = rs;
36 | this.iTotalRecords = rs.getTotal();
37 | this.iTotalDisplayRecords = rs.getTotal();
38 | }
39 |
40 | /**
41 | * Gets echo.
42 | *
43 | * @return the echo
44 | */
45 | public int getsEcho() {
46 | return sEcho;
47 | }
48 |
49 | /**
50 | * Gets total records.
51 | *
52 | * @return the total records
53 | */
54 | public long getiTotalRecords() {
55 | return iTotalRecords;
56 | }
57 |
58 | /**
59 | * Gets total display records.
60 | *
61 | * @return the total display records
62 | */
63 | public long getiTotalDisplayRecords() {
64 | return iTotalDisplayRecords;
65 | }
66 |
67 | /**
68 | * Gets aa data.
69 | *
70 | * @return the aa data
71 | */
72 | public List getAaData() {
73 | return Collections.unmodifiableList(aaData);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/HSQLDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * Dialect for HSQLDB
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class HSQLDialect implements Dialect {
17 | @Override
18 | public boolean supportsLimit() {
19 | return true;
20 | }
21 |
22 | @Override
23 | public String getLimitString(String sql, int offset, int limit) {
24 | return getLimitString(sql, offset, Integer.toString(offset),
25 | Integer.toString(limit));
26 | }
27 |
28 | /**
29 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
30 | *
31 | * 如mysql
32 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
33 | * select * from user limit :offset,:limit
34 | *
35 | * select limit :offset,:limit * from user
36 | *
37 | *
38 | * @param sql 实际SQL语句
39 | * @param offset 分页开始纪录条数
40 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
41 | * @param limitPlaceholder 分页纪录条数占位符号
42 | * @return 包含占位符的分页sql
43 | */
44 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) {
45 | boolean hasOffset = offset > 0;
46 | return
47 | new StringBuffer(sql.length() + 10)
48 | .append(sql)
49 | .insert(sql.toLowerCase().indexOf("select") + 6, hasOffset ? " limit " + offsetPlaceholder + " " + limitPlaceholder : " top " + limitPlaceholder)
50 | .toString();
51 | }
52 |
53 | @Override
54 | public String getCountString(String sql) {
55 | return "select count(*) from (" + sql + ") as tmp_count";
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/MySQLDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * Mysql方言的实现
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class MySQLDialect implements Dialect {
17 |
18 |
19 | @Override
20 | public String getLimitString(String sql, int offset, int limit) {
21 | return getLimitString(sql, offset, Integer.toString(offset),
22 | Integer.toString(limit));
23 | }
24 |
25 | public boolean supportsLimit() {
26 | return true;
27 | }
28 |
29 | /**
30 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
31 | *
32 | * 如mysql
33 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
34 | * select * from user limit :offset,:limit
35 | *
36 | *
37 | * @param sql 实际SQL语句
38 | * @param offset 分页开始纪录条数
39 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
40 | * @param limitPlaceholder 分页纪录条数占位符号
41 | * @return 包含占位符的分页sql
42 | */
43 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) {
44 | StringBuilder stringBuilder = new StringBuilder(sql);
45 | stringBuilder.append(" limit ");
46 | if (offset > 0) {
47 | stringBuilder.append(offsetPlaceholder).append(",").append(limitPlaceholder);
48 | } else {
49 | stringBuilder.append(limitPlaceholder);
50 | }
51 | return stringBuilder.toString();
52 | }
53 |
54 | @Override
55 | public String getCountString(String querySqlString) {
56 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
57 | return "select count(1) from (" + sql + ") as tmp_count";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/PostgreSQLDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * Postgre Sql的方言实现
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class PostgreSQLDialect implements Dialect {
17 |
18 | public boolean supportsLimit() {
19 | return true;
20 | }
21 |
22 | @Override
23 | public String getLimitString(String sql, int offset, int limit) {
24 | return getLimitString(sql, offset, Integer.toString(offset),
25 | Integer.toString(limit));
26 | }
27 |
28 | /**
29 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
30 | *
31 | * 如mysql
32 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
33 | * select * from user limit :offset,:limit
34 | *
35 | *
36 | * @param sql 实际SQL语句
37 | * @param offset 分页开始纪录条数
38 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
39 | * @param limitPlaceholder 分页纪录条数占位符号
40 | * @return 包含占位符的分页sql
41 | */
42 | public String getLimitString(String sql, int offset,
43 | String offsetPlaceholder, String limitPlaceholder) {
44 | StringBuilder pageSql = new StringBuilder().append(sql);
45 | pageSql = offset <= 0
46 | ? pageSql.append(" limit ").append(limitPlaceholder) :
47 | pageSql.append(" limit ").append(limitPlaceholder).append(" offset ").append(offsetPlaceholder);
48 | return pageSql.toString();
49 | }
50 |
51 | @Override
52 | public String getCountString(String querySqlString) {
53 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
54 | return "select count(1) from (" + sql + ") as tmp_count";
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dto/datatables/SearchField.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.dto.datatables;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | *
7 | * The DataTables search filed model.
8 | *
9 | *
10 | * @author walter yang
11 | * @version 1.0 2013-09-12 10:22 AM
12 | * @since JDK 1.5
13 | */
14 | public class SearchField implements Serializable {
15 |
16 | private static final long serialVersionUID = -8493268499000005405L;
17 | /** field name */
18 | private final String field;
19 | /** True if the individual column filter should be treated as a regular expression for advanced filtering, false if not */
20 | private final boolean regex;
21 | /** Indicator for if a column is flagged as sortable or not on the client-side */
22 | private final boolean searchable;
23 | /** search value. */
24 | private final String value;
25 |
26 | /**
27 | * Instantiates a new Search field.
28 | *
29 | * @param field the field
30 | * @param regex the regex
31 | * @param searchable the searchable
32 | * @param value the value
33 | */
34 | public SearchField(String field, boolean regex, boolean searchable, String value) {
35 | this.field = field;
36 | this.regex = regex;
37 | this.searchable = searchable;
38 | this.value = value;
39 | }
40 |
41 | /**
42 | * Gets value.
43 | *
44 | * @return the value
45 | */
46 | public String getValue() {
47 | return value;
48 | }
49 |
50 | /**
51 | * Gets field.
52 | *
53 | * @return the field
54 | */
55 | public String getField() {
56 | return field;
57 | }
58 |
59 | /**
60 | * Is regex.
61 | *
62 | * @return the boolean
63 | */
64 | public boolean isRegex() {
65 | return regex;
66 | }
67 |
68 | /**
69 | * Is searchable.
70 | *
71 | * @return the boolean
72 | */
73 | public boolean isSearchable() {
74 | return searchable;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/SQLServerDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * MSSQLServer 数据库实现分页方言
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class SQLServerDialect implements Dialect {
17 |
18 | static int getAfterSelectInsertPoint(String sql) {
19 | int selectIndex = sql.toLowerCase().indexOf("select");
20 | final int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct");
21 | return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6);
22 | }
23 |
24 | public boolean supportsLimit() {
25 | return true;
26 | }
27 |
28 | public String getLimitString(String sql, int offset, int limit) {
29 | return getLimit(sql, offset, limit);
30 | }
31 |
32 | /**
33 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
34 | *
35 | * 如mysql
36 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
37 | * select * from user limit :offset,:limit
38 | *
39 | *
40 | * @param sql 实际SQL语句
41 | * @param offset 分页开始纪录条数
42 | * @param limit 分页每页显示纪录条数
43 | * @return 包含占位符的分页sql
44 | */
45 | public String getLimit(String sql, int offset, int limit) {
46 | if (offset > 0) {
47 | throw new UnsupportedOperationException("sql server has no offset");
48 | }
49 | return new StringBuffer(sql.length() + 8)
50 | .append(sql)
51 | .insert(getAfterSelectInsertPoint(sql), " top " + limit)
52 | .toString();
53 | }
54 |
55 | @Override
56 | public String getCountString(String querySqlString) {
57 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
58 | return "select count(1) from (" + sql + ") as tmp_count";
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Mybatis Pagination
2 | support Mysql、MSSQL、Oracle、MSSQL2005、Postgre SQL、DB2.
3 |
4 | ## Basic Usage
5 | in the Mybatis config, add the plugin.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | * `dbms`,database type. MYSQL\MSSQL\ORACLE\MSSQL2005\DB2
15 | * `sqlRegex` the mapper method/ sql mapper xml's id, regex string.
16 | * example `.*findAll.*` contain `findAll` query sql
17 |
18 | ### Sql Mapper config
19 |
20 |
22 | SELECT
23 | ID,CREATORTIME,DATASOURCE,DATATYPE,DICTNAME,DICTNUMBER,ENABLE,RENEWTIME,SORT
24 | from CD_DICT ORDER BY SORT
25 |
26 |
27 | # Spring usage
28 |
29 | @see [config](https://github.com/yfyang/mybatis-pagination/blob/master/src/test/resources/spring/test-context.xml) And [TestCase](https://github.com/yfyang/mybatis-pagination/tree/master/src/test/java/org/mybatis/pagination/service)
30 |
31 | # Maven Usage
32 |
33 | 1. add repositories into you project `pom.xml`
34 |
35 |
36 |
37 | yfyang-mvn-repo
38 | https://raw.github.com/yfyang/mybatis-pagination/mvn-repo/
39 |
40 | true
41 | always
42 |
43 |
44 |
45 |
46 | 2. add propertie into `pom.xml`:properties
47 |
48 |
49 | 0.0.3
50 |
51 |
52 | 3. add dependency into `pom.xml`
53 |
54 |
55 | org.mybatis
56 | mybatis-pagination
57 | ${org.mybatis.pagination.version}
58 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/DialectClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect;
6 |
7 | import java.io.Serializable;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | import org.mybatis.pagination.dialect.db.DB2Dialect;
12 | import org.mybatis.pagination.dialect.db.H2Dialect;
13 | import org.mybatis.pagination.dialect.db.HSQLDialect;
14 | import org.mybatis.pagination.dialect.db.MySQLDialect;
15 | import org.mybatis.pagination.dialect.db.OracleDialect;
16 | import org.mybatis.pagination.dialect.db.PostgreSQLDialect;
17 | import org.mybatis.pagination.dialect.db.SQLServer2005Dialect;
18 | import org.mybatis.pagination.dialect.db.SQLServerDialect;
19 | import org.mybatis.pagination.dialect.db.SybaseDialect;
20 |
21 |
22 | /**
23 | *
24 | * 数据库分页方言获取类.
25 | *
26 | *
27 | * @author poplar.yfyang
28 | * @version 1.0 2011-11-18 下午2:54
29 | * @since JDK 1.5
30 | */
31 | public class DialectClient implements Serializable {
32 | private static final long serialVersionUID = 8107330250767760951L;
33 | private static final Map DBMS_DIALECT = new HashMap();
34 |
35 | /**
36 | * 根据数据库名称获取数据库分页查询的方言实现。
37 | *
38 | * @param dbms 数据库名称
39 | * @return 数据库分页方言实现
40 | */
41 | public static Dialect getDbmsDialect(DBMS dbms) {
42 | if (DBMS_DIALECT.containsKey(dbms)) {
43 | return DBMS_DIALECT.get(dbms);
44 | }
45 | Dialect dialect = createDbmsDialect(dbms);
46 | DBMS_DIALECT.put(dbms, dialect);
47 | return dialect;
48 | }
49 |
50 | /**
51 | * 插入自定义方言的实例
52 | *
53 | * @param exDialect 方言实现
54 | */
55 | public static void putEx(Dialect exDialect) {
56 | DBMS_DIALECT.put(DBMS.EX, exDialect);
57 | }
58 |
59 | /**
60 | * 创建数据库方言
61 | *
62 | * @param dbms 数据库
63 | * @return 数据库
64 | */
65 | private static Dialect createDbmsDialect(DBMS dbms) {
66 | switch (dbms) {
67 | case MYSQL:
68 | return new MySQLDialect();
69 | case ORACLE:
70 | return new OracleDialect();
71 | case DB2:
72 | return new DB2Dialect();
73 | case POSTGRE:
74 | return new PostgreSQLDialect();
75 | case SQLSERVER:
76 | return new SQLServerDialect();
77 | case SQLSERVER2005:
78 | return new SQLServer2005Dialect();
79 | case SYBASE:
80 | return new SybaseDialect();
81 | case H2:
82 | return new H2Dialect();
83 | case HSQL:
84 | return new HSQLDialect();
85 | default:
86 | throw new UnsupportedOperationException("Empty dbms dialect");
87 | }
88 | }
89 |
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/pagination/mapper/ResourcesMapper.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.mapper;
2 |
3 | import org.apache.ibatis.annotations.Param;
4 | import org.mybatis.pagination.domain.Resources;
5 | import org.mybatis.pagination.domain.ResourcesCriteria;
6 | import org.mybatis.pagination.dto.PageMyBatis;
7 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
8 | import org.mybatis.pagination.extra.MyBatisRepository;
9 |
10 | import java.util.List;
11 |
12 | @MyBatisRepository
13 | public interface ResourcesMapper {
14 | /**
15 | * 根据指定的条件删除系统资源的数据库记录,auth_resources
16 | *
17 | * @param example 动态SQL条件实例
18 | */
19 | int deleteByExample(ResourcesCriteria example);
20 |
21 | /**
22 | * 根据主键删除系统资源的数据库记录,auth_resources
23 | *
24 | * @param id 主键唯一标志
25 | */
26 | int deleteByPrimaryKey(String id);
27 |
28 | /**
29 | * 新写入系统资源的数据库记录,auth_resources
30 | *
31 | * @param record 系统资源
32 | */
33 | int insert(Resources record);
34 |
35 | /**
36 | * 动态字段,写入系统资源的数据库记录,auth_resources
37 | *
38 | * @param record 系统资源
39 | */
40 | int insertSelective(Resources record);
41 |
42 | /**
43 | * 根据指定的条件查询符合条件的系统资源的数据库记录,auth_resources
44 | *
45 | * @param example 动态SQL条件实例
46 | */
47 | List selectByExample(ResourcesCriteria example);
48 |
49 | /**
50 | * 根据指定主键获取系统资源的数据库记录,auth_resources
51 | *
52 | * @param id 主键唯一标志
53 | */
54 | Resources selectByPrimaryKey(String id);
55 |
56 | /**
57 | * 动态根据指定的条件来更新符合条件的系统资源的数据库记录,auth_resources
58 | *
59 | * @param record 系统资源
60 | * @param example 动态SQL条件实例
61 | */
62 | int updateByExampleSelective(@Param("record") Resources record, @Param("example") ResourcesCriteria example);
63 |
64 | /**
65 | * 根据指定的条件来更新符合条件的系统资源的数据库记录,auth_resources
66 | *
67 | * @param record 系统资源
68 | * @param example 动态SQL条件实例
69 | */
70 | int updateByExample(@Param("record") Resources record, @Param("example") ResourcesCriteria example);
71 |
72 | /**
73 | * 动态字段,根据主键来更新符合条件的系统资源的数据库记录,auth_resources
74 | *
75 | * @param record 系统资源
76 | */
77 | int updateByPrimaryKeySelective(Resources record);
78 |
79 | /**
80 | * 根据主键来更新符合条件的系统资源的数据库记录,auth_resources
81 | *
82 | * @param record 系统资源
83 | */
84 | int updateByPrimaryKey(Resources record);
85 |
86 | PageMyBatis selectByPage(PagingCriteria pagingCriteria);
87 | PageMyBatis selectByPageOrder(PagingCriteria pagingCriteria);
88 | PageMyBatis selectByPageOrderAndWhere(PagingCriteria pagingCriteria,@Param("name") String name);
89 | }
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/OracleDialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import org.mybatis.pagination.dialect.Dialect;
8 |
9 | /**
10 | * Oracle的方言实现
11 | *
12 | * @author poplar.yfyang
13 | * @version 1.0 2010-10-10 下午12:31
14 | * @since JDK 1.5
15 | */
16 | public class OracleDialect implements Dialect {
17 | @Override
18 | public boolean supportsLimit() {
19 | return true;
20 | }
21 |
22 | @Override
23 | public String getLimitString(String sql, int offset, int limit) {
24 | return getLimitString(sql, offset, Integer.toString(offset), Integer.toString(limit));
25 | }
26 |
27 | /**
28 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
29 | *
30 | * 如mysql
31 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
32 | * select * from user limit :offset,:limit
33 | *
34 | *
35 | * @param sql 实际SQL语句
36 | * @param offset 分页开始纪录条数
37 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
38 | * @param limitPlaceholder 分页纪录条数占位符号
39 | * @return 包含占位符的分页sql
40 | */
41 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) {
42 | sql = sql.trim();
43 | boolean isForUpdate = false;
44 | if (sql.toLowerCase().endsWith(" for update")) {
45 | sql = sql.substring(0, sql.length() - 11);
46 | isForUpdate = true;
47 | }
48 | StringBuilder pagingSelect = new StringBuilder(sql.length() + 100);
49 | if (offset >= 0) {
50 | pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
51 | } else {
52 | pagingSelect.append("select * from ( ");
53 | }
54 | pagingSelect.append(sql);
55 | if (offset >= 0) {
56 | String endString = offsetPlaceholder + "+" + limitPlaceholder;
57 | pagingSelect.append(" ) row_ ) where rownum_ <= ")
58 | .append(endString).append(" and rownum_ > ").append(offsetPlaceholder);
59 | } else {
60 | pagingSelect.append(" ) where rownum <= ").append(limitPlaceholder);
61 | }
62 |
63 | if (isForUpdate) {
64 | pagingSelect.append(" for update");
65 | }
66 |
67 | return pagingSelect.toString();
68 | }
69 |
70 | @Override
71 | public String getCountString(String querySqlString) {
72 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
73 |
74 | return "select count(1) from (" + sql + ") tmp_count";
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dto/PageMyBatis.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.dto;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 | import java.util.List;
6 |
7 | import com.google.common.base.Objects;
8 | import com.google.common.collect.Lists;
9 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
10 | import org.mybatis.pagination.mvc.DataTablesResultSet;
11 |
12 | /**
13 | *
14 | * PageMyBatis.
15 | *
16 | *
17 | * @author mumu @yfyang
18 | * @version 1.0 2013-08-03 9:31 PM
19 | * @since JDK 1.5
20 | */
21 | public class PageMyBatis extends ArrayList {
22 | private static final long serialVersionUID = -3472924628671922516L;
23 | /**
24 | * data connection.
25 | */
26 | private final List content = Lists.newArrayList();
27 | /**
28 | * pagination information
29 | */
30 | private final PagingCriteria pageable;
31 | /**
32 | * count resultset.
33 | */
34 | private final long total;
35 |
36 | /**
37 | * Instantiates a new Page my batis.
38 | *
39 | * @param content the content
40 | * @param pageable the pageable
41 | * @param total the total
42 | */
43 | public PageMyBatis(Collection extends E> content, PagingCriteria pageable, long total) {
44 | super(content);
45 |
46 | this.content.addAll(content);
47 | this.total = total;
48 | this.pageable = pageable;
49 | }
50 |
51 | /**
52 | * Instantiates a new Page my batis.
53 | *
54 | * @param content the content
55 | */
56 | public PageMyBatis(List content) {
57 | // fixed total is 0 throw NullPointException
58 | this(content, null, null == content ? 0 : content.size());
59 | }
60 |
61 | /**
62 | * Gets total.
63 | *
64 | * @return the total
65 | */
66 | public long getTotal() {
67 | return total;
68 | }
69 |
70 | /**
71 | * Warp page.
72 | *
73 | * @return the page
74 | */
75 | public DataTablesResultSet warp() {
76 | return new DataTablesResultSet(pageable == null ? 0 : pageable.getPageNumber(), this);
77 | }
78 |
79 | @Override
80 | public String toString() {
81 | return Objects.toStringHelper(this)
82 | .add("content", content)
83 | .add("pageable", pageable)
84 | .add("total", total)
85 | .toString();
86 | }
87 |
88 | @Override
89 | public boolean equals(Object o) {
90 | if (this == o) {
91 | return true;
92 | }
93 | if (o == null || getClass() != o.getClass()) {
94 | return false;
95 | }
96 | if (!super.equals(o)) {
97 | return false;
98 | }
99 |
100 | PageMyBatis that = (PageMyBatis) o;
101 |
102 | return total == that.total && !(content != null ? !content.equals(that.content) : that.content != null) && !(pageable != null ? !pageable.equals(that.pageable) : that.pageable != null);
103 |
104 | }
105 |
106 | @Override
107 | public int hashCode() {
108 | int result = super.hashCode();
109 | result = 31 * result + (content != null ? content.hashCode() : 0);
110 | result = 31 * result + (pageable != null ? pageable.hashCode() : 0);
111 | result = 31 * result + (int) (total ^ (total >>> 32));
112 | return result;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/DB2Dialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 |
8 | import org.mybatis.pagination.dialect.Dialect;
9 |
10 | /**
11 | * DB2的分页数据库方言实现
12 | *
13 | * @author poplar.yfyang
14 | * @version 1.0 2010-10-10 下午12:31
15 | * @since JDK 1.5
16 | */
17 | public class DB2Dialect implements Dialect {
18 | private static String getRowNumber(String sql) {
19 | StringBuilder rownumber = new StringBuilder(50)
20 | .append("rownumber() over(");
21 |
22 | int orderByIndex = sql.toLowerCase().indexOf("order by");
23 |
24 | if (orderByIndex > 0 && !hasDistinct(sql)) {
25 | rownumber.append(sql.substring(orderByIndex));
26 | }
27 |
28 | rownumber.append(") as rownumber_,");
29 |
30 | return rownumber.toString();
31 | }
32 |
33 | private static boolean hasDistinct(String sql) {
34 | return sql.toLowerCase().contains("select distinct");
35 | }
36 |
37 | @Override
38 | public boolean supportsLimit() {
39 | return true;
40 | }
41 |
42 | @Override
43 | public String getLimitString(String sql, int offset, int limit) {
44 | return getLimitString(sql, offset, Integer.toString(offset), Integer.toString(limit));
45 | }
46 |
47 | /**
48 | * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
49 | *
50 | * 如mysql
51 | * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
52 | * select * from user limit :offset,:limit
53 | *
54 | *
55 | * @param sql 实际SQL语句
56 | * @param offset 分页开始纪录条数
57 | * @param offsetPlaceholder 分页开始纪录条数-占位符号
58 | * @param limitPlaceholder 分页纪录条数占位符号
59 | * @return 包含占位符的分页sql
60 | */
61 | public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) {
62 | int startOfSelect = sql.toLowerCase().indexOf("select");
63 |
64 | StringBuilder pagingSelect = new StringBuilder(sql.length() + 100)
65 | .append(sql.substring(0, startOfSelect)) //add the comment
66 | .append("select * from ( select ") //nest the main query in an outer select
67 | .append(getRowNumber(sql)); //add the rownnumber bit into the outer query select list
68 |
69 | if (hasDistinct(sql)) {
70 | pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
71 | .append(sql.substring(startOfSelect)) //add the main query
72 | .append(" ) as row_"); //close off the inner nested select
73 | } else {
74 | pagingSelect.append(sql.substring(startOfSelect + 6)); //add the main query
75 | }
76 |
77 | pagingSelect.append(" ) as temp_ where rownumber_ ");
78 |
79 | //add the restriction to the outer select
80 | if (offset > 0) {
81 | // int end = offset + limit;
82 | String endString = offsetPlaceholder + "+" + limitPlaceholder;
83 | pagingSelect.append("between ").append(offsetPlaceholder)
84 | .append("+1 and ").append(endString);
85 | } else {
86 | pagingSelect.append("<= ").append(limitPlaceholder);
87 | }
88 |
89 | return pagingSelect.toString();
90 | }
91 |
92 | @Override
93 | public String getCountString(String querySqlString) {
94 | String sql = SQLServer2005Dialect.getNonOrderByPart(querySqlString);
95 | return "select count(1) from (" + sql + ") as tmp_count";
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/test/resources/spring/test-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
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 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dialect/db/SQLServer2005Dialect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dialect.db;
6 |
7 | import io.github.sparta.helpers.sql.SqlRemoveHelper;
8 | import org.mybatis.pagination.dialect.Dialect;
9 | import org.mybatis.pagination.helpers.CountHelper;
10 | import org.mybatis.pagination.helpers.StringHelper;
11 |
12 | /**
13 | * Sql 2005的方言实现
14 | *
15 | * @author poplar.yfyang
16 | * @version 1.0 2010-10-10 下午12:31
17 | * @since JDK 1.5
18 | */
19 | public class SQLServer2005Dialect implements Dialect {
20 |
21 | static String getOrderByPart(String sql) {
22 | String loweredString = sql.toLowerCase();
23 | int orderByIndex = loweredString.indexOf("order by");
24 | if (orderByIndex != -1) {
25 | // if we find a new "order by" then we need to ignore
26 | // the previous one since it was probably used for a subquery
27 | return sql.substring(orderByIndex);
28 | } else {
29 | return "";
30 | }
31 | }
32 |
33 | /**
34 | * exclude in 'order by ' by sql
35 | *
36 | * @param sql sql
37 | * @return count sql.
38 | */
39 | public static String getNonOrderByPart(String sql) {
40 | return SqlRemoveHelper.removeOrders(sql);
41 | }
42 |
43 | @Override
44 | public boolean supportsLimit() {
45 | return true;
46 | }
47 |
48 | @Override
49 | public String getLimitString(String sql, int offset, int limit) {
50 | return getLimitString(sql, offset,
51 | limit, Integer.toString(limit));
52 | }
53 |
54 | /**
55 | * Add a LIMIT clause to the given SQL SELECT
56 | *
57 | * The LIMIT SQL will look like:
58 | *
59 | * WITH query AS
60 | * (SELECT TOP 100 percent ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * from table_name)
61 | * SELECT *
62 | * FROM query
63 | * WHERE __row_number__ BETWEEN :offset and :lastRows
64 | * ORDER BY __row_number__
65 | *
66 | * @param querySqlString The SQL statement to base the limit query off of.
67 | * @param offset Offset of the first row to be returned by the query (zero-based)
68 | * @param limit Maximum number of rows to be returned by the query
69 | * @param limitPlaceholder limitPlaceholder
70 | * @return A new SQL statement with the LIMIT clause applied.
71 | */
72 | private String getLimitString(String querySqlString, int offset, int limit, String limitPlaceholder) {
73 | StringBuilder pagingBuilder = new StringBuilder();
74 | String orderby = getOrderByPart(querySqlString);
75 | String distinctStr = "";
76 |
77 | String loweredString = querySqlString.toLowerCase();
78 | String sqlPartString = querySqlString;
79 | if (loweredString.trim().startsWith("select")) {
80 | int index = 6;
81 | if (loweredString.startsWith("select distinct")) {
82 | distinctStr = "DISTINCT ";
83 | index = 15;
84 | }
85 | sqlPartString = sqlPartString.substring(index);
86 | }
87 | pagingBuilder.append(sqlPartString);
88 |
89 | // if no ORDER BY is specified use fake ORDER BY field to avoid errors
90 | if (StringHelper.isEmpty(orderby)) {
91 | orderby = "ORDER BY CURRENT_TIMESTAMP";
92 | }
93 |
94 | StringBuilder result = new StringBuilder();
95 | result.append("WITH query AS (SELECT ")
96 | .append(distinctStr)
97 | .append("TOP 100 PERCENT ")
98 | .append(" ROW_NUMBER() OVER (")
99 | .append(orderby)
100 | .append(") as __row_number__, ")
101 | .append(pagingBuilder)
102 | .append(") SELECT * FROM query WHERE __row_number__ BETWEEN ")
103 | .append(offset + 1).append(" AND ").append(offset + limit)
104 | .append(" ORDER BY __row_number__");
105 |
106 | return result.toString();
107 | }
108 |
109 | @Override
110 | public String getCountString(String querySqlString) {
111 | String sql = getNonOrderByPart(querySqlString);
112 |
113 | return "select count(1) from (" + sql + ") as tmp_count";
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/pagination/service/MapperTest.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.service;
2 |
3 | import java.util.List;
4 | import javax.annotation.Resource;
5 |
6 | import com.google.common.collect.Lists;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.mybatis.pagination.domain.Resources;
10 | import org.mybatis.pagination.dto.PageMyBatis;
11 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
12 | import org.mybatis.pagination.dto.datatables.SearchField;
13 | import org.mybatis.pagination.dto.datatables.SortDirection;
14 | import org.mybatis.pagination.dto.datatables.SortField;
15 | import org.mybatis.pagination.mapper.ResourcesMapper;
16 | import org.springframework.test.context.ContextConfiguration;
17 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
18 |
19 | /**
20 | *
21 | * .
22 | *
23 | *
24 | * @author mumu@yfyang
25 | * @version 1.0 2013-09-09 2:15 PM
26 | * @since JDK 1.5
27 | */
28 | @RunWith(SpringJUnit4ClassRunner.class)
29 | @ContextConfiguration("classpath*:spring/test-context.xml")
30 | public class MapperTest {
31 |
32 | @Resource
33 | private ResourcesMapper resourcesMapper;
34 |
35 | // @Before
36 | // //使用该注释会使用事务,而且在测试完成之后会回滚事务,也就是说在该方法中做出的一切操作都不会对数据库中的数据产生任何影响
37 | // @Rollback(false) //这里设置为false,就让事务不回滚
38 | // public void setUp() throws Exception {
39 | // Resources resources;
40 | // for (int i = 0; i < 1000; i++) {
41 | // resources = new Resources();
42 | // resources.setId(UUID.randomUUID().toString());
43 | // resources.setName("测试数据" + i);
44 | // resources.setPath("test/pageh/" + i);
45 | // resourcesMapper.insertSelective(resources);
46 | // }
47 | //
48 | // }
49 |
50 | @Test
51 | public void testPagaination() throws Exception {
52 |
53 | PagingCriteria baseCriteria = PagingCriteria.createCriteria(0, 15, 15);
54 | PageMyBatis pageMyBatis = resourcesMapper.selectByPage(baseCriteria);
55 | for (Resources pageMyBati : pageMyBatis) {
56 | System.out.println(pageMyBati);
57 | }
58 | }
59 |
60 | @Test
61 | public void testPagainationSqlContainOrder() throws Exception {
62 | PagingCriteria baseCriteria = PagingCriteria.createCriteria(0, 15, 15);
63 | PageMyBatis pageMyBatis = resourcesMapper.selectByPageOrder(baseCriteria);
64 | for (Resources pageMyBati : pageMyBatis) {
65 | System.out.println(pageMyBati);
66 | }
67 |
68 | }
69 |
70 | @Test
71 | public void testPagainationAndWrap() throws Exception {
72 | PagingCriteria baseCriteria = PagingCriteria.createCriteria(0, 15, 15);
73 | PageMyBatis pageMyBatis = resourcesMapper.selectByPage(baseCriteria);
74 | System.out.println("pageMyBatis.warp() = " + pageMyBatis.warp());
75 | }
76 |
77 | @Test
78 | public void testPagainationAndOrder() throws Exception {
79 |
80 | List sortFields = Lists.newArrayList();
81 | sortFields.add(new SortField("name", SortDirection.DESC));
82 | sortFields.add(new SortField("path", SortDirection.ASC));
83 |
84 | PagingCriteria baseCriteria = PagingCriteria.createCriteriaWithSort(20, 15, 15, sortFields);
85 | PageMyBatis pageMyBatis = resourcesMapper.selectByPage(baseCriteria);
86 | for (Resources pageMyBati : pageMyBatis) {
87 | System.out.println(pageMyBati);
88 | }
89 | }
90 |
91 | @Test
92 | public void testPagainationAndSearch() throws Exception {
93 | List searchFields = Lists.newArrayList();
94 | searchFields.add(new SearchField("name", false, false, "11"));
95 |
96 | PagingCriteria baseCriteria = PagingCriteria.createCriteriaWithSearch(0, 15, 15, searchFields);
97 | PageMyBatis pageMyBatis = resourcesMapper.selectByPage(baseCriteria);
98 | for (Resources pageMyBati : pageMyBatis) {
99 | System.out.println(pageMyBati);
100 | }
101 | }
102 |
103 | @Test
104 | public void testPagainationAndOrderSearch() throws Exception {
105 | List searchFields = Lists.newArrayList();
106 | searchFields.add(new SearchField("name", false, false, "11"));
107 |
108 | PagingCriteria baseCriteria = PagingCriteria.createCriteriaWithSearch(0, 15, 15, searchFields);
109 | PageMyBatis pageMyBatis = resourcesMapper.selectByPageOrder(baseCriteria);
110 | for (Resources pageMyBati : pageMyBatis) {
111 | System.out.println(pageMyBati);
112 | }
113 | }
114 |
115 | @Test
116 | public void testPaginationMoreWhere() throws Exception {
117 | List searchFields = Lists.newArrayList();
118 | searchFields.add(new SearchField("name", false, false, "11"));
119 |
120 | PagingCriteria baseCriteria = PagingCriteria.createCriteriaWithSearch(0, 15, 15, searchFields);
121 | PageMyBatis pageMyBatis = resourcesMapper.selectByPageOrderAndWhere(baseCriteria,"aa");
122 | for (Resources pageMyBati : pageMyBatis) {
123 | System.out.println(pageMyBati);
124 | }
125 |
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/helpers/StringHelper.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.helpers;
2 |
3 | /**
4 | *
5 | * Help class by String.
6 | *
7 | *
8 | * @author mumu@yfyang
9 | * @version 1.0 2013-09-09 11:26 AM
10 | * @since JDK 1.5
11 | */
12 | public final class StringHelper {
13 |
14 |
15 | /** The empty String {@code ""}. */
16 | public static final String EMPTY = "";
17 | /** The dot String {@code ","}. */
18 | public static final String DOT_CHAR = ",";
19 | /** The blank String {@code " "}. */
20 | public static final String BLANK_CHAR = " ";
21 | /** The equal sign String {@code "="} */
22 | public static final String EQUAL_SIGN_CHAR = "=";
23 | /**
24 | * The like String {@code "like"}
25 | */
26 | public static final String LIKE_CHAR = " like ";
27 | private static final String INJECTION_SQL = ".*([';]+|(--)+).*";
28 | private static String LIKE_FORMATE = "'%%s%'";
29 |
30 | /**
31 | * Checks if a CharSequence is not empty ("") and not null.
32 | *
33 | *
34 | * StringUtils.isNotEmpty(null) = false
35 | * StringUtils.isNotEmpty("") = false
36 | * StringUtils.isNotEmpty(" ") = true
37 | * StringUtils.isNotEmpty("bob") = true
38 | * StringUtils.isNotEmpty(" bob ") = true
39 | *
40 | *
41 | * @param cs the CharSequence to check, may be null
42 | * @return {@code true} if the CharSequence is not empty and not null
43 | * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence)
44 | */
45 | public static boolean isNotEmpty(CharSequence cs) {
46 | return !isEmpty(cs);
47 | }
48 |
49 | /**
50 | * Checks if a CharSequence is empty ("") or null.
51 | *
52 | *
53 | * StringUtils.isEmpty(null) = true
54 | * StringUtils.isEmpty("") = true
55 | * StringUtils.isEmpty(" ") = false
56 | * StringUtils.isEmpty("bob") = false
57 | * StringUtils.isEmpty(" bob ") = false
58 | *
59 | *
60 | * NOTE: This method changed in Lang version 2.0.
61 | * It no longer trims the CharSequence.
62 | * That functionality is available in isBlank().
63 | *
64 | * @param cs the CharSequence to check, may be null
65 | * @return {@code true} if the CharSequence is empty or null
66 | * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence)
67 | */
68 | public static boolean isEmpty(CharSequence cs) {
69 | return cs == null || cs.length() == 0;
70 | }
71 |
72 | /**
73 | * Capitalizes a String changing the first letter to title case as
74 | * per {@link Character#toTitleCase(char)}. No other letters are changed.
75 | *
76 | * For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}.
77 | * A {@code null} input String returns {@code null}.
78 | *
79 | *
80 | * StringUtils.capitalize(null) = null
81 | * StringUtils.capitalize("") = ""
82 | * StringUtils.capitalize("cat") = "Cat"
83 | * StringUtils.capitalize("cAt") = "CAt"
84 | *
85 | *
86 | * @param str the String to capitalize, may be null
87 | * @return the capitalized String, {@code null} if null String input
88 | */
89 | public static String capitalize(String str) {
90 | if (str == null || (str.length()) == 0) {
91 | return str;
92 | }
93 | return String.valueOf(Character.toTitleCase(str.charAt(0))) + str.substring(1);
94 | }
95 |
96 | /**
97 | * Checks if a CharSequence is whitespace, empty ("") or null.
98 | *
99 | *
100 | * StringUtils.isBlank(null) = true
101 | * StringUtils.isBlank("") = true
102 | * StringUtils.isBlank(" ") = true
103 | * StringUtils.isBlank("bob") = false
104 | * StringUtils.isBlank(" bob ") = false
105 | *
106 | *
107 | * @param cs the CharSequence to check, may be null
108 | * @return {@code true} if the CharSequence is null, empty or whitespace
109 | * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence)
110 | */
111 | public static boolean isBlank(CharSequence cs) {
112 | int strLen;
113 | if (cs == null || (strLen = cs.length()) == 0) {
114 | return true;
115 | }
116 | for (int i = 0; i < strLen; i++) {
117 | if (!Character.isWhitespace(cs.charAt(i))) {
118 | return false;
119 | }
120 | }
121 | return true;
122 | }
123 |
124 | /**
125 | * Transact sQL injection.
126 | *
127 | * @param sql the sql
128 | * @return the string
129 | */
130 | public static String transactSQLInjection(String sql) {
131 | return sql.replaceAll(INJECTION_SQL, " ");
132 | }
133 |
134 | /**
135 | * Like value.
136 | *
137 | * @param value the value
138 | * @return the string
139 | */
140 | public static String likeValue(String value) {
141 | return String.format(LIKE_FORMATE, transactSQLInjection(value));
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/PagingParametersFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination;
6 |
7 | import com.google.common.collect.Maps;
8 | import org.apache.commons.beanutils.BeanMap;
9 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
10 | import org.mybatis.pagination.helpers.StringHelper;
11 |
12 | import java.lang.reflect.Array;
13 | import java.util.Collection;
14 | import java.util.Map;
15 |
16 | /**
17 | *
18 | * Paging PaginationCriteria finds.
19 | *
20 | *
21 | * @author poplar.yfyang
22 | * @version 1.0 2012-12-09 7:22 PM
23 | * @since JDK 1.5
24 | */
25 | public enum PagingParametersFinder {
26 |
27 | instance;
28 |
29 | /**
30 | * The search parameters by use of interim storage of results.
31 | */
32 | private final Map search_map = Maps.newHashMap();
33 |
34 | /**
35 | * private constructor
36 | */
37 | private PagingParametersFinder() {
38 | }
39 |
40 |
41 | /**
42 | * from the formulation of the objects found in the paging parameters object.
43 | *
44 | * @param object object.
45 | * @return paging parameters.
46 | */
47 | public PagingCriteria findCriteria(Object object) {
48 | if (object == null) {
49 | return null;
50 | }
51 | try {
52 | return findCriteriaFromObject(object);
53 | } finally {
54 | //cleanup query the value of the temporary Map.
55 | search_map.clear();
56 | }
57 | }
58 |
59 | /**
60 | * In the object to find whether contains PaginationCriteria objects.
61 | *
62 | * @param object parameter object.
63 | * @return PaginationCriteria
64 | */
65 | private PagingCriteria findCriteriaFromObject(Object object) {
66 |
67 | //如果已经寻找过这个对象,现在再来这里肯定是没找到。就直接返回NULL
68 | if (search_map.containsKey(object)) {
69 | return null;
70 | }
71 | //object class
72 | Class> obj_class = object.getClass();
73 | PagingCriteria pc;
74 | //primitive
75 | if (isPrimitiveType(obj_class)) {
76 | pc = null;
77 | } else if (object instanceof PagingCriteria) {
78 | pc = (PagingCriteria) object;
79 | } else if (object instanceof Map) {
80 | pc = findCriteriaFromMap((Map) object);
81 | } else if (object instanceof Collection) {
82 | pc = findCriteriaFromCollection((Collection) object);
83 | } else if (obj_class.isArray()) {
84 | pc = findCriteriaFromArray(object);
85 | } else {
86 | BeanMap map = new BeanMap(object);
87 | return findCriteriaFromMap(map);
88 | }
89 |
90 |
91 | search_map.put(object, StringHelper.EMPTY);
92 | return pc;
93 | }
94 |
95 | /**
96 | * In the array to find whether it contains the PaginationCriteria object.
97 | *
98 | * @param array the array.
99 | * @return PageQuery
100 | */
101 | private PagingCriteria findCriteriaFromArray(Object array) {
102 | if (search_map.containsKey(array)) {
103 | return null;
104 | }
105 |
106 | Object object;
107 | PagingCriteria pc;
108 | for (int i = 0; i < Array.getLength(array); i++) {
109 | object = Array.get(array, i);
110 | pc = findCriteriaFromObject(object);
111 | if (pc != null) {
112 | search_map.put(array, StringHelper.EMPTY);
113 | return pc;
114 | }
115 | }
116 | search_map.put(array, StringHelper.EMPTY);
117 | return null;
118 | }
119 |
120 | /**
121 | * In the Collection to find whether contains PaginationCriteria objects.
122 | *
123 | * @param collection parameter collection.
124 | * @return PageQuery
125 | */
126 | private PagingCriteria findCriteriaFromCollection(Collection collection) {
127 | if (search_map.containsKey(collection)) {
128 | return null;
129 | }
130 | PagingCriteria pc;
131 |
132 | for (Object e : collection) {
133 | pc = findCriteriaFromObject(e);
134 | if (pc != null) {
135 | search_map.put(collection, StringHelper.EMPTY);
136 | return pc;
137 | }
138 | }
139 |
140 | search_map.put(collection, StringHelper.EMPTY);
141 | return null;
142 | }
143 |
144 | /**
145 | * In the Map to find whether contains PaginationCriteria objects.
146 | *
147 | * @param map parameter map.
148 | * @return PaginationCriteria
149 | */
150 | private PagingCriteria findCriteriaFromMap(Map map) {
151 | if (search_map.containsKey(map)) {
152 | return null;
153 | }
154 |
155 | PagingCriteria pc;
156 | for (Object value : map.values()) {
157 | pc = findCriteriaFromObject(value);
158 | if (pc != null) {
159 | search_map.put(map, StringHelper.EMPTY);
160 | return pc;
161 | }
162 | }
163 |
164 | search_map.put(map, StringHelper.EMPTY);
165 | return null;
166 | }
167 |
168 |
169 |
170 | /**
171 | * 返回指定类型所对应的primitive类型。包含String类
172 | *
173 | * fixed:paramter string type.
174 | *
175 | * @param clazz 要检查的类型
176 | * @return 如果指定类型为null或不是primitive类型的包装类,则返回false,否则返回true。
177 | */
178 | public static boolean isPrimitiveType(Class clazz) {
179 | return clazz != null && (clazz.isPrimitive() || clazz.equals(Long.class) || clazz.equals(Integer.class)
180 | || clazz.equals(Short.class) || clazz.equals(Byte.class) || clazz.equals(Double.class)
181 | || clazz.equals(Float.class) || clazz.equals(Boolean.class) || clazz.equals(Character.class) || clazz.equals(String.class));
182 |
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/PaginationExecutor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination;
6 |
7 | import java.sql.SQLException;
8 | import java.util.List;
9 |
10 | import org.apache.ibatis.cache.Cache;
11 | import org.apache.ibatis.cache.CacheKey;
12 | import org.apache.ibatis.executor.BatchResult;
13 | import org.apache.ibatis.executor.CachingExecutor;
14 | import org.apache.ibatis.executor.Executor;
15 | import org.apache.ibatis.logging.Log;
16 | import org.apache.ibatis.logging.LogFactory;
17 | import org.apache.ibatis.mapping.BoundSql;
18 | import org.apache.ibatis.mapping.MappedStatement;
19 | import org.apache.ibatis.reflection.MetaObject;
20 | import org.apache.ibatis.session.ResultHandler;
21 | import org.apache.ibatis.session.RowBounds;
22 | import org.apache.ibatis.transaction.Transaction;
23 | import org.mybatis.pagination.dto.PageMyBatis;
24 |
25 |
26 | /**
27 | * Paging executor.
28 | * Dependence of mybatis agent.
29 | *
30 | * @author poplar.yfyang
31 | * @author htlu
32 | * @version 1.0 2012-09-09 7:22 PM
33 | * @since JDK 1.5
34 | */
35 | public class PaginationExecutor implements Executor {
36 |
37 | /** logging */
38 | private static final Log LOG = LogFactory.getLog(PaginationExecutor.class);
39 | /** mybatis executor interface */
40 | private final Executor executor;
41 |
42 | /**
43 | * Paging Constructor.
44 | *
45 | * @param executor Trim executor.
46 | */
47 | public PaginationExecutor(Executor executor) {
48 | this.executor = executor;
49 | }
50 |
51 | @Override
52 | public int update(MappedStatement ms, Object parameter) throws SQLException {
53 |
54 | return executor.update(ms, parameter);
55 | }
56 |
57 | @Override
58 | public List query(MappedStatement ms, Object parameter,
59 | RowBounds rowBounds, ResultHandler resultHandler,
60 | CacheKey cacheKey, BoundSql boundSql) throws SQLException {
61 |
62 | final List rows = executor.query(ms, parameter, rowBounds, resultHandler);
63 | int total = PaginationInterceptor.getPaginationTotal();
64 | try {
65 | if (total != 0) {
66 | final PageMyBatis result = new PageMyBatis(rows, PaginationInterceptor.getPageRequest(), total);
67 | doCache(ms, result, parameter, rowBounds);
68 | return result;
69 | } else {
70 | return new PageMyBatis(rows);
71 | }
72 | } finally {
73 | PaginationInterceptor.clean();
74 | }
75 | }
76 |
77 | @Override
78 | public List query(MappedStatement ms, Object parameter,
79 | RowBounds rowBounds, ResultHandler resultHandler)
80 | throws SQLException {
81 |
82 | final List rows = executor.query(ms, parameter, rowBounds, resultHandler);
83 | int total = PaginationInterceptor.getPaginationTotal();
84 | try {
85 | if (total != 0) {
86 | final PageMyBatis result = new PageMyBatis(rows, PaginationInterceptor.getPageRequest(), total);
87 | doCache(ms, result, parameter, rowBounds);
88 | return result;
89 | } else {
90 | return new PageMyBatis(rows);
91 | }
92 | } finally {
93 | PaginationInterceptor.clean();
94 | }
95 |
96 | }
97 |
98 | /**
99 | * do mybatis cache with this executor.
100 | *
101 | * @param ms mapped statuement.
102 | * @param result database result.
103 | * @param parameter sql paramater.
104 | * @param rowBounds row bounds
105 | * @param paramter.
106 | */
107 | private void doCache(MappedStatement ms, PageMyBatis result, Object parameter, RowBounds rowBounds) {
108 | // if the current of the executor is for CachingExecutor
109 | final Cache cache = ms.getCache();
110 | // Determine whether the current query cache.
111 | if (executor.getClass().isAssignableFrom(CachingExecutor.class) && cache != null) {
112 | BoundSql boundSql = ms.getBoundSql(parameter);
113 | final CacheKey cacheKey = createCacheKey(ms, parameter, rowBounds, boundSql);
114 | if (LOG.isDebugEnabled()) {
115 | LOG.debug("cache executor the cache's kye is " + cacheKey);
116 | }
117 | cache.putObject(cacheKey, result);
118 | }
119 | }
120 |
121 | @Override
122 | public List flushStatements() throws SQLException {
123 | return executor.flushStatements();
124 | }
125 |
126 | @Override
127 | public void commit(boolean required) throws SQLException {
128 | executor.commit(required);
129 | }
130 |
131 | @Override
132 | public void rollback(boolean required) throws SQLException {
133 | executor.rollback(required);
134 | }
135 |
136 | @Override
137 | public CacheKey createCacheKey(MappedStatement ms, Object parameterObject,
138 | RowBounds rowBounds, BoundSql boundSql) {
139 | return executor.createCacheKey(ms, parameterObject, rowBounds, boundSql);
140 | }
141 |
142 | @Override
143 | public boolean isCached(MappedStatement ms, CacheKey key) {
144 | return executor.isCached(ms, key);
145 | }
146 |
147 | @Override
148 | public void clearLocalCache() {
149 | executor.clearLocalCache();
150 | }
151 |
152 | @Override
153 | public void deferLoad(MappedStatement mappedStatement, MetaObject metaObject,
154 | String s, CacheKey cacheKey, Class> aClass) {
155 |
156 | executor.deferLoad(mappedStatement, metaObject, s, cacheKey, aClass);
157 | }
158 |
159 | @Override
160 | public Transaction getTransaction() {
161 | return executor.getTransaction();
162 | }
163 |
164 | @Override
165 | public void close(boolean forceRollback) {
166 | //clear
167 | PaginationInterceptor.clean();
168 | executor.close(forceRollback);
169 | }
170 |
171 | @Override
172 | public boolean isClosed() {
173 | return executor.isClosed();
174 | }
175 |
176 | }
177 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/helpers/CountHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.helpers;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.List;
12 |
13 | import org.apache.ibatis.executor.ErrorContext;
14 | import org.apache.ibatis.executor.ExecutorException;
15 | import org.apache.ibatis.logging.Log;
16 | import org.apache.ibatis.logging.LogFactory;
17 | import org.apache.ibatis.mapping.BoundSql;
18 | import org.apache.ibatis.mapping.MappedStatement;
19 | import org.apache.ibatis.mapping.ParameterMapping;
20 | import org.apache.ibatis.mapping.ParameterMode;
21 | import org.apache.ibatis.reflection.MetaObject;
22 | import org.apache.ibatis.reflection.property.PropertyTokenizer;
23 | import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
24 | import org.apache.ibatis.session.Configuration;
25 | import org.apache.ibatis.type.TypeHandler;
26 | import org.apache.ibatis.type.TypeHandlerRegistry;
27 | import org.mybatis.pagination.dialect.Dialect;
28 |
29 | /**
30 | *
31 | * .
32 | *
33 | *
34 | * @author poplar.yfyang
35 | * @version 1.0 2012-05-08 上午11:30
36 | * @since JDK 1.5
37 | */
38 | public class CountHelper {
39 |
40 | public static final String SQL_ORDER = " order by ";
41 | public static final String OR_JOINER = " or ";
42 | public static final String OR_SQL_FORMAT = "%s or (%s) %s";
43 | public static final String WHERE_SQL_FORMAT = "%s where (%s) %s";
44 | public static final String SQL_FORMAT = "%s, %s";
45 | public static final String ORDER_SQL_FORMAT = "%s order by %s";
46 | /** logging */
47 | private static final Log LOG = LogFactory.getLog(CountHelper.class);
48 |
49 | /**
50 | * 查询总纪录数
51 | *
52 | * @param sql SQL语句
53 | * @param connection 数据库连接
54 | * @param mappedStatement mapped
55 | * @param parameterObject 参数
56 | * @param boundSql boundSql
57 | * @param dialect database dialect
58 | * @return 总记录数
59 | * @throws java.sql.SQLException sql查询错误
60 | */
61 | public static int getCount(final String sql, final Connection connection,
62 | final MappedStatement mappedStatement, final Object parameterObject,
63 | final BoundSql boundSql, Dialect dialect) throws SQLException {
64 | final String count_sql = dialect.getCountString(sql);
65 | if (LOG.isDebugEnabled()) {
66 | LOG.debug("the pagination generate count sql is [" + count_sql + "]");
67 | }
68 | PreparedStatement countStmt = null;
69 | ResultSet rs = null;
70 | try {
71 | countStmt = connection.prepareStatement(count_sql);
72 | final BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), count_sql,
73 | boundSql.getParameterMappings(), parameterObject);
74 | CountHelper.setParameters(countStmt, mappedStatement, countBS, parameterObject);
75 | rs = countStmt.executeQuery();
76 | int count = 0;
77 | if (rs.next()) {
78 | count = rs.getInt(1);
79 | }
80 | return count;
81 | } finally {
82 | if (rs != null) {
83 | rs.close();
84 | }
85 | if (countStmt != null) {
86 | countStmt.close();
87 | }
88 | }
89 | }
90 |
91 | /**
92 | * 对SQL参数(?)设值
93 | *
94 | * @param ps 表示预编译的 SQL 语句的对象。
95 | * @param mappedStatement MappedStatement
96 | * @param boundSql SQL
97 | * @param parameterObject 参数对象
98 | * @throws java.sql.SQLException 数据库异常
99 | */
100 | @SuppressWarnings("unchecked")
101 | public static void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException {
102 | ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
103 | List parameterMappings = boundSql.getParameterMappings();
104 | if (parameterMappings != null) {
105 | Configuration configuration = mappedStatement.getConfiguration();
106 | TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
107 | MetaObject metaObject = parameterObject == null ? null :
108 | configuration.newMetaObject(parameterObject);
109 | for (int i = 0; i < parameterMappings.size(); i++) {
110 | ParameterMapping parameterMapping = parameterMappings.get(i);
111 | if (parameterMapping.getMode() != ParameterMode.OUT) {
112 | Object value;
113 | String propertyName = parameterMapping.getProperty();
114 | PropertyTokenizer prop = new PropertyTokenizer(propertyName);
115 | if (parameterObject == null) {
116 | value = null;
117 | } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
118 | value = parameterObject;
119 | } else if (boundSql.hasAdditionalParameter(propertyName)) {
120 | value = boundSql.getAdditionalParameter(propertyName);
121 | } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) {
122 | value = boundSql.getAdditionalParameter(prop.getName());
123 | if (value != null) {
124 | value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
125 | }
126 | } else {
127 | value = metaObject == null ? null : metaObject.getValue(propertyName);
128 | }
129 | TypeHandler typeHandler = parameterMapping.getTypeHandler();
130 | if (typeHandler == null) {
131 | throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());
132 | }
133 | typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
134 | }
135 | }
136 | }
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/pagination/domain/Resources.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.domain;
2 |
3 | import com.google.common.base.Objects;
4 |
5 | import java.io.Serializable;
6 |
7 | public class Resources implements Serializable {
8 | /**
9 | * 主键,所属表字段为auth_resources.id
10 | */
11 | private String id;
12 |
13 | /**
14 | * 资源名称,所属表字段为auth_resources.name
15 | */
16 | private String name;
17 |
18 | /**
19 | * 资源类型,所属表字段为auth_resources.type
20 | */
21 | private String type;
22 |
23 | /**
24 | * 资源地址,所属表字段为auth_resources.path
25 | */
26 | private String path;
27 |
28 | /**
29 | * 资源请求,所属表字段为auth_resources.action
30 | */
31 | private String action;
32 |
33 | /**
34 | * 资源控制,所属表字段为auth_resources.controller
35 | */
36 | private String controller;
37 |
38 | /**
39 | * 状态,所属表字段为auth_resources.status
40 | */
41 | private Boolean status;
42 |
43 | /**
44 | * 序列化ID,auth_resources
45 | */
46 | private static final long serialVersionUID = 1L;
47 |
48 | /**
49 | * 获取 主键 字段:auth_resources.id
50 | *
51 | * @return auth_resources.id, 主键
52 | */
53 | public String getId() {
54 | return id;
55 | }
56 |
57 | /**
58 | * 设置 主键 字段:auth_resources.id
59 | *
60 | * @param id auth_resources.id, 主键
61 | */
62 | public void setId(String id) {
63 | this.id = id == null ? null : id.trim();
64 | }
65 |
66 | /**
67 | * 获取 资源名称 字段:auth_resources.name
68 | *
69 | * @return auth_resources.name, 资源名称
70 | */
71 | public String getName() {
72 | return name;
73 | }
74 |
75 | /**
76 | * 设置 资源名称 字段:auth_resources.name
77 | *
78 | * @param name auth_resources.name, 资源名称
79 | */
80 | public void setName(String name) {
81 | this.name = name == null ? null : name.trim();
82 | }
83 |
84 | /**
85 | * 获取 资源类型 字段:auth_resources.type
86 | *
87 | * @return auth_resources.type, 资源类型
88 | */
89 | public String getType() {
90 | return type;
91 | }
92 |
93 | /**
94 | * 设置 资源类型 字段:auth_resources.type
95 | *
96 | * @param type auth_resources.type, 资源类型
97 | */
98 | public void setType(String type) {
99 | this.type = type == null ? null : type.trim();
100 | }
101 |
102 | /**
103 | * 获取 资源地址 字段:auth_resources.path
104 | *
105 | * @return auth_resources.path, 资源地址
106 | */
107 | public String getPath() {
108 | return path;
109 | }
110 |
111 | /**
112 | * 设置 资源地址 字段:auth_resources.path
113 | *
114 | * @param path auth_resources.path, 资源地址
115 | */
116 | public void setPath(String path) {
117 | this.path = path == null ? null : path.trim();
118 | }
119 |
120 | /**
121 | * 获取 资源请求 字段:auth_resources.action
122 | *
123 | * @return auth_resources.action, 资源请求
124 | */
125 | public String getAction() {
126 | return action;
127 | }
128 |
129 | /**
130 | * 设置 资源请求 字段:auth_resources.action
131 | *
132 | * @param action auth_resources.action, 资源请求
133 | */
134 | public void setAction(String action) {
135 | this.action = action == null ? null : action.trim();
136 | }
137 |
138 | /**
139 | * 获取 资源控制 字段:auth_resources.controller
140 | *
141 | * @return auth_resources.controller, 资源控制
142 | */
143 | public String getController() {
144 | return controller;
145 | }
146 |
147 | /**
148 | * 设置 资源控制 字段:auth_resources.controller
149 | *
150 | * @param controller auth_resources.controller, 资源控制
151 | */
152 | public void setController(String controller) {
153 | this.controller = controller == null ? null : controller.trim();
154 | }
155 |
156 | /**
157 | * 获取 状态 字段:auth_resources.status
158 | *
159 | * @return auth_resources.status, 状态
160 | */
161 | public Boolean getStatus() {
162 | return status;
163 | }
164 |
165 | /**
166 | * 设置 状态 字段:auth_resources.status
167 | *
168 | * @param status auth_resources.status, 状态
169 | */
170 | public void setStatus(Boolean status) {
171 | this.status = status;
172 | }
173 |
174 | @Override
175 | public String toString() {
176 | return Objects.toStringHelper(this)
177 | .add("id", id)
178 | .add("name", name)
179 | .add("type", type)
180 | .add("path", path)
181 | .add("action", action)
182 | .add("controller", controller)
183 | .add("status", status)
184 | .toString();
185 | }
186 |
187 | /**
188 | * ,auth_resources
189 | *
190 | * @param that
191 | */
192 | @Override
193 | public boolean equals(Object that) {
194 | if (this == that) {
195 | return true;
196 | }
197 | if (that == null) {
198 | return false;
199 | }
200 | if (getClass() != that.getClass()) {
201 | return false;
202 | }
203 | Resources other = (Resources) that;
204 | return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
205 | && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
206 | && (this.getType() == null ? other.getType() == null : this.getType().equals(other.getType()))
207 | && (this.getPath() == null ? other.getPath() == null : this.getPath().equals(other.getPath()))
208 | && (this.getAction() == null ? other.getAction() == null : this.getAction().equals(other.getAction()))
209 | && (this.getController() == null ? other.getController() == null : this.getController().equals(other.getController()))
210 | && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()));
211 | }
212 |
213 | /**
214 | * ,auth_resources
215 | */
216 | @Override
217 | public int hashCode() {
218 | final int prime = 31;
219 | int result = 1;
220 | result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
221 | result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
222 | result = prime * result + ((getType() == null) ? 0 : getType().hashCode());
223 | result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
224 | result = prime * result + ((getAction() == null) ? 0 : getAction().hashCode());
225 | result = prime * result + ((getController() == null) ? 0 : getController().hashCode());
226 | result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
227 | return result;
228 | }
229 | }
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/mvc/TableParamArgumentResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.mvc;
6 |
7 | import com.google.common.base.CaseFormat;
8 | import com.google.common.base.Strings;
9 | import com.google.common.collect.Lists;
10 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
11 | import org.mybatis.pagination.dto.datatables.SearchField;
12 | import org.mybatis.pagination.dto.datatables.SortField;
13 | import org.springframework.core.MethodParameter;
14 | import org.springframework.web.bind.support.WebArgumentResolver;
15 | import org.springframework.web.context.request.NativeWebRequest;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.util.List;
19 |
20 | /**
21 | *
22 | * resolver paramArgument with annotation.
23 | *
24 | *
25 | * @author mumu @yfyang
26 | * @version 1.0 2013-09-05 10:44 PM
27 | * @see
28 | * @see
29 | * @since JDK 1.5
30 | */
31 | public class TableParamArgumentResolver implements WebArgumentResolver {
32 | /**
33 | * Information for DataTables to use for rendering.
34 | */
35 | private static final String S_ECHO = "sEcho";
36 | /**
37 | * Display start point in the current data set.
38 | */
39 | private static final String I_DISPLAY_START = "iDisplayStart";
40 | /**
41 | * Number of records that the table can display in the current draw.
42 | * It is expected that the number of records returned will be equal to this number, unless the server has fewer records to return.
43 | */
44 | private static final String I_DISPLAY_LENGTH = "iDisplayLength";
45 | /**
46 | * Number of columns to sort on
47 | */
48 | private static final String I_SORTING_COLS = "iSortingCols";
49 | /**
50 | * Column being sorted on (you will need to decode this number for your database)
51 | */
52 | private static final String I_SORT_COLS = "iSortCol_";
53 | /**
54 | * Direction to be sorted - "desc" or "asc".
55 | */
56 | private static final String S_SORT_DIR = "sSortDir_";
57 | /**
58 | * The value specified by mDataProp for each column.
59 | * This can be useful for ensuring that the processing of data is independent from the order of the columns.
60 | */
61 | private static final String S_DATA_PROP = "mDataProp_";
62 | /**
63 | * Individual column filter
64 | */
65 | private static final String S_SEACHE_VAL = "sSearch_";
66 | /**
67 | * True if the individual column filter should be treated as a regular expression for advanced filtering, false if not
68 | */
69 | private static final String B_REGEX = "bRegex_";
70 | /**
71 | * Indicator for if a column is flagged as sortable or not on the client-side
72 | */
73 | private static final String B_SORTTABLE = "bSortable_";
74 | /**
75 | * Global search field value
76 | */
77 | private static final String S_SEARCH = "sSearch";
78 | /**
79 | * Number of columns being displayed (useful for getting individual column search info)
80 | */
81 | private static final String I_COLUMNS = "iColumns";
82 | /**
83 | * Hump Split colum name
84 | */
85 | private final boolean humpSplit;
86 |
87 | /**
88 | * Instantiates a new Table param argument resolver.
89 | *
90 | * @param humpSplit the hump split
91 | */
92 | public TableParamArgumentResolver(boolean humpSplit) {
93 | this.humpSplit = humpSplit;
94 | }
95 |
96 |
97 | @Override
98 | public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
99 | TableParam tableParamAnnotation = methodParameter.getParameterAnnotation(TableParam.class);
100 | if (tableParamAnnotation != null) {
101 | HttpServletRequest httpRequest = (HttpServletRequest) webRequest.getNativeRequest();
102 |
103 | String sEcho = httpRequest.getParameter(S_ECHO);
104 | String sDisplayStart = httpRequest.getParameter(I_DISPLAY_START);
105 | String sDisplayLength = httpRequest.getParameter(I_DISPLAY_LENGTH);
106 |
107 | int iEcho = Integer.parseInt(sEcho);
108 | int iDisplayStart = Integer.parseInt(sDisplayStart);
109 | int iDisplayLength = Integer.parseInt(sDisplayLength);
110 |
111 | List sortFields = getSortFileds(httpRequest);
112 | List searchFields = getSearchParam(httpRequest);
113 |
114 | return PagingCriteria.createCriteriaWithAllParamter(iDisplayStart, iDisplayLength, iEcho, sortFields, searchFields);
115 | }
116 |
117 | return WebArgumentResolver.UNRESOLVED;
118 | }
119 |
120 | /**
121 | * Gets sort fileds.
122 | *
123 | * @param httpRequest the http request
124 | * @return the sort fileds
125 | */
126 | private List getSortFileds(final HttpServletRequest httpRequest) {
127 |
128 | String sSortingCols = httpRequest.getParameter(I_SORTING_COLS);
129 |
130 | int iSortingCols = Integer.parseInt(sSortingCols);
131 | final List sortFields = Lists.newArrayListWithCapacity(iSortingCols);
132 | String sSortDir;
133 | String sColName;
134 | String sSortCol;
135 | for (int colCount = 0; colCount < iSortingCols; colCount++) {
136 | sSortCol = httpRequest.getParameter(I_SORT_COLS + colCount);
137 | sSortDir = httpRequest.getParameter(S_SORT_DIR + colCount);
138 | sColName = httpRequest.getParameter(S_DATA_PROP + sSortCol);
139 | sColName = humpSplit
140 | ? CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, sColName)
141 | : sColName;
142 | sortFields.add(new SortField(sColName, sSortDir));
143 | }
144 | return sortFields;
145 | }
146 |
147 | /**
148 | * Gets search param.
149 | *
150 | * @param httpRequest the http request
151 | * @return the search param
152 | */
153 | private List getSearchParam(final HttpServletRequest httpRequest) {
154 | int iColumns = Integer.valueOf(httpRequest.getParameter(I_COLUMNS));
155 | final List searchFields = Lists.newArrayListWithCapacity(iColumns);
156 | boolean regex;
157 | boolean searchable;
158 | String searchValue;
159 | String sColName;
160 | final String sSearch = httpRequest.getParameter(S_SEARCH);
161 | for (int col = 0; col < iColumns; col++) {
162 | searchValue = httpRequest.getParameter(S_SEACHE_VAL + col);
163 | sColName = httpRequest.getParameter(S_DATA_PROP + col);
164 | sColName = humpSplit
165 | ? CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, sColName)
166 | : sColName;
167 | if (!Strings.isNullOrEmpty(searchValue)) {
168 | regex = Boolean.valueOf(httpRequest.getParameter(B_REGEX + col));
169 | searchable = Boolean.valueOf(httpRequest.getParameter(B_SORTTABLE + col));
170 | searchFields.add(new SearchField(sColName, regex, searchable, searchValue));
171 | } else if (!Strings.isNullOrEmpty(sSearch)) {
172 | searchFields.add(new SearchField(sColName, false, false, sSearch));
173 | }
174 | }
175 | return searchFields;
176 | }
177 |
178 | }
179 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/dto/datatables/PagingCriteria.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination.dto.datatables;
6 |
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | import com.google.common.collect.Lists;
11 |
12 | /**
13 | *
14 | * jQuery DataTables's PagingCriteria.
15 | *
16 | *
17 | * @author mumu@yfyang
18 | * @version 1.0 2013-09-05 10:37 PM
19 | * @since JDK 1.5
20 | */
21 | public final class PagingCriteria {
22 | /** The constant DEFAULT_CRITERIA. */
23 | private static final PagingCriteria DEFAULT_CRITERIA = new PagingCriteria(0, PagingCriteria.DEFAULT_SIZE, PagingCriteria.DEFAULT_SIZE);
24 | /** default page size. */
25 | private static final int DEFAULT_SIZE = 10;
26 | /** start display */
27 | private final int displayStart;
28 | /** disaplaySize */
29 | private final int displaySize;
30 | /** sort fields */
31 | private final List sortFields;
32 | /** search field information */
33 | private final List searchFields;
34 | /** pageNumber */
35 | private final int pageNumber;
36 |
37 | /**
38 | * Instantiates a new Paging criteria.
39 | *
40 | * @param displayStart the display start
41 | * @param displaySize the display size
42 | * @param pageNumber the page number
43 | * @param sortFields the sort fields
44 | * @param searchFields the search information
45 | */
46 | private PagingCriteria(int displayStart
47 | , int displaySize
48 | , int pageNumber
49 | , List sortFields
50 | , List searchFields) {
51 | this.displayStart = displayStart;
52 | this.displaySize = displaySize;
53 | this.pageNumber = pageNumber;
54 | this.sortFields = sortFields;
55 | this.searchFields = searchFields;
56 | }
57 |
58 | /**
59 | * Instantiates a new Paging criteria and not sort\search.
60 | *
61 | * @param displaySize the display size
62 | * @param displayStart the display start
63 | * @param pageNumber the page number
64 | */
65 | private PagingCriteria(int displaySize
66 | , int displayStart
67 | , int pageNumber) {
68 | this.displaySize = displaySize;
69 | this.displayStart = displayStart;
70 | this.pageNumber = pageNumber;
71 | this.searchFields = Lists.newArrayListWithCapacity(0);
72 | this.sortFields = Lists.newArrayListWithCapacity(0);
73 | }
74 |
75 | /**
76 | * Instantiates a new Paging criteria and no search.
77 | *
78 | * @param displaySize the display size
79 | * @param displayStart the display start
80 | * @param pageNumber the page number
81 | * @param sortFields the sort fields
82 | */
83 | private PagingCriteria(int displaySize
84 | , int displayStart
85 | , int pageNumber
86 | , List sortFields) {
87 | this.sortFields = sortFields;
88 | this.displaySize = displaySize;
89 | this.displayStart = displayStart;
90 | this.pageNumber = pageNumber;
91 | this.searchFields = Lists.newArrayListWithCapacity(0);
92 | }
93 |
94 | /**
95 | * Instantiates a new Paging criteria and no sort.
96 | *
97 | * @param displayStart the display start
98 | * @param displaySize the display size
99 | * @param searchFields the search fields
100 | * @param pageNumber the page number
101 | */
102 | private PagingCriteria(int displayStart
103 | , int displaySize
104 | , List searchFields
105 | , int pageNumber) {
106 | this.displayStart = displayStart;
107 | this.displaySize = displaySize;
108 | this.searchFields = searchFields;
109 | this.pageNumber = pageNumber;
110 | this.sortFields = Lists.newArrayListWithCapacity(0);
111 | }
112 |
113 | /**
114 | * Create criteria with all paramter.
115 | *
116 | * @param displayStart the display start
117 | * @param displaySize the display size
118 | * @param pageNumber the page number
119 | * @param sortFields the sort fields
120 | * @param searchFields the search fields
121 | * @return the paging criteria
122 | */
123 | public static PagingCriteria createCriteriaWithAllParamter(int displayStart
124 | , int displaySize
125 | , int pageNumber
126 | , List sortFields
127 | , List searchFields) {
128 | return new PagingCriteria(displayStart, displaySize, pageNumber, sortFields, searchFields);
129 | }
130 |
131 | /**
132 | * Create criteria with sort.
133 | *
134 | * @param displayStart the display start
135 | * @param displaySize the display size
136 | * @param pageNumber the page number
137 | * @param sortFields the sort fields
138 | * @return the paging criteria
139 | */
140 | public static PagingCriteria createCriteriaWithSort(int displayStart, int displaySize, int pageNumber
141 | , List sortFields) {
142 | return new PagingCriteria(displayStart, displaySize, pageNumber, sortFields);
143 | }
144 |
145 | /**
146 | * Create criteria with search.
147 | *
148 | * @param displayStart the display start
149 | * @param displaySize the display size
150 | * @param pageNumber the page number
151 | * @param searchFields the search fields
152 | * @return the paging criteria
153 | */
154 | public static PagingCriteria createCriteriaWithSearch(int displayStart, int displaySize, int pageNumber
155 | , List searchFields) {
156 | return new PagingCriteria(displayStart, displaySize, searchFields, pageNumber);
157 | }
158 |
159 | /**
160 | * Create criteria.
161 | *
162 | * @param displayStart the display start
163 | * @param displaySize the display size
164 | * @param pageNumber the page number
165 | * @return the paging criteria
166 | */
167 | public static PagingCriteria createCriteria(int displayStart, int displaySize, int pageNumber) {
168 | return new PagingCriteria(displayStart, displaySize, pageNumber);
169 | }
170 |
171 | /**
172 | * Get default criteria.
173 | *
174 | * @return the paging criteria
175 | */
176 | public static PagingCriteria getDefaultCriteria() {
177 | return DEFAULT_CRITERIA;
178 | }
179 |
180 | /**
181 | * Gets display start.
182 | *
183 | * @return the display start
184 | */
185 | public Integer getDisplayStart() {
186 | return displayStart;
187 | }
188 |
189 | /**
190 | * Gets display size.
191 | *
192 | * @return the display size
193 | */
194 | public Integer getDisplaySize() {
195 | return displaySize;
196 | }
197 |
198 | /**
199 | * Gets search fields.
200 | *
201 | * @return the search fields
202 | */
203 | public List getSearchFields() {
204 | if (this.searchFields == null) {
205 | return Lists.newArrayListWithCapacity(0);
206 | }
207 | return Collections.unmodifiableList(searchFields);
208 | }
209 |
210 | /**
211 | * Gets sort fields.
212 | *
213 | * @return the sort fields
214 | */
215 | public List getSortFields() {
216 | if (this.sortFields == null) {
217 | return Lists.newArrayListWithCapacity(0);
218 | }
219 | return Collections.unmodifiableList(sortFields);
220 | }
221 |
222 | /**
223 | * Gets page number.
224 | *
225 | * @return the page number
226 | */
227 | public Integer getPageNumber() {
228 | return pageNumber;
229 | }
230 |
231 | }
232 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | org.mybatis
7 | mybatis-pagination
8 | 0.0.3
9 | jar
10 |
11 | mybatis-paging
12 | http://maven.apache.org
13 |
14 |
15 |
16 | peak yfyang
17 | poplar1123@gmail.com
18 |
19 |
20 |
21 |
22 | UTF-8
23 | 3.2.2
24 | 3.2.4.RELEASE
25 | 1.2.0
26 | github
27 |
28 |
29 |
30 |
31 |
32 |
33 | com.google.guava
34 | guava
35 | 15.0
36 |
37 |
38 | org.mybatis
39 | mybatis
40 | ${mybatis.version}
41 |
42 |
43 | commons-beanutils
44 | commons-beanutils
45 | 1.8.3
46 |
47 |
48 | org.springframework
49 | spring-webmvc
50 | ${spring.version}
51 | provided
52 |
53 |
54 | javax.servlet
55 | servlet-api
56 | 2.5
57 | provided
58 |
59 |
60 |
61 |
62 |
63 | junit
64 | junit
65 | 4.10
66 | test
67 |
68 |
69 | org.springframework
70 | spring-context
71 | ${spring.version}
72 | test
73 |
74 |
75 | org.springframework
76 | spring-tx
77 | ${spring.version}
78 | test
79 |
80 |
81 | org.springframework
82 | spring-jdbc
83 | ${spring.version}
84 | test
85 |
86 |
87 | org.springframework
88 | spring-test
89 | ${spring.version}
90 | test
91 |
92 |
93 | org.mybatis
94 | mybatis-spring
95 | ${spring.mybatis.version}
96 | test
97 |
98 |
99 | mysql
100 | mysql-connector-java
101 | 5.1.20
102 | test
103 |
104 |
105 | net.sourceforge
106 | jtds
107 | 1.2.5
108 | test
109 |
110 |
111 | log4j
112 | log4j
113 | 1.2.16
114 | test
115 |
116 |
117 | com.alibaba
118 | druid
119 | 0.2.8
120 | test
121 |
122 |
123 | org.aspectj
124 | aspectjrt
125 | 1.7.2
126 | test
127 |
128 |
129 | c3p0
130 | c3p0
131 | 0.9.1.2
132 | test
133 |
134 |
135 | org.aspectj
136 | aspectjweaver
137 | 1.7.2
138 | test
139 |
140 |
141 | commons-dbcp
142 | commons-dbcp
143 | 1.4
144 | test
145 |
146 |
147 |
148 | io.github.yfyang
149 | sparta-helper
150 | 0.0.1
151 |
152 |
153 |
154 |
155 |
156 | mybatis-paging
157 |
158 |
159 | org.apache.maven.plugins
160 | maven-source-plugin
161 |
162 | true
163 |
164 |
165 |
166 | attach-sources
167 |
168 | jar
169 |
170 |
171 |
172 |
173 |
174 | maven-deploy-plugin
175 | 2.7
176 |
177 | internal.repo::default::file://${project.build.directory}/mvn-repo
178 |
179 |
180 |
181 | com.github.github
182 | site-maven-plugin
183 | 0.8
184 |
185 | Maven artifacts for ${project.version}
186 | true
187 | ${project.build.directory}/mvn-repo
188 | refs/heads/mvn-repo
189 | **/*
190 | mybatis-pagination
191 | yfyang
192 |
193 |
194 |
195 |
196 |
197 | site
198 |
199 | deploy
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | yfyang-mvn-repo
208 | https://raw.github.com/yfyang/sparta-helpers/mvn-repo/
209 |
210 | true
211 | always
212 |
213 |
214 |
215 |
216 |
217 | github
218 | GitHub ${project.artifactId} Repository
219 | https://raw.github.com/yfyang/${project.artifactId}/mvn-repo
220 |
221 |
222 |
223 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/pagination/PaginationInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2013 mumu@yfyang. All Rights Reserved.
3 | */
4 |
5 | package org.mybatis.pagination;
6 |
7 | import com.google.common.base.Joiner;
8 | import com.google.common.base.Preconditions;
9 | import com.google.common.collect.Lists;
10 | import io.github.sparta.helpers.reflex.Reflections;
11 | import io.github.sparta.helpers.sql.SqlRemoveHelper;
12 | import org.apache.ibatis.executor.Executor;
13 | import org.apache.ibatis.logging.Log;
14 | import org.apache.ibatis.logging.LogFactory;
15 | import org.apache.ibatis.mapping.BoundSql;
16 | import org.apache.ibatis.mapping.MappedStatement;
17 | import org.apache.ibatis.mapping.ParameterMapping;
18 | import org.apache.ibatis.mapping.SqlSource;
19 | import org.apache.ibatis.plugin.*;
20 | import org.apache.ibatis.session.ResultHandler;
21 | import org.apache.ibatis.session.RowBounds;
22 | import org.mybatis.pagination.dialect.DBMS;
23 | import org.mybatis.pagination.dialect.Dialect;
24 | import org.mybatis.pagination.dialect.DialectClient;
25 | import org.mybatis.pagination.dto.datatables.PagingCriteria;
26 | import org.mybatis.pagination.dto.datatables.SearchField;
27 | import org.mybatis.pagination.dto.datatables.SortField;
28 | import org.mybatis.pagination.helpers.CountHelper;
29 | import org.mybatis.pagination.helpers.StringHelper;
30 |
31 | import java.io.Serializable;
32 | import java.sql.Connection;
33 | import java.sql.SQLException;
34 | import java.util.List;
35 | import java.util.Properties;
36 |
37 | /**
38 | *
39 | * Mybatis数据库分页插件.
40 | * 拦截StatementHandler的prepare方法
41 | *
42 | *
43 | * @author poplar.yfyang
44 | * @version 1.0 2011-11-18 下午12:31
45 | * @since JDK 1.5
46 | */
47 | @Intercepts({@Signature(
48 | type = Executor.class,
49 | method = "query",
50 | args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
51 | public class PaginationInterceptor implements Interceptor, Serializable {
52 | /** serial Version */
53 | private static final long serialVersionUID = -6075937069117597841L;
54 | private static final ThreadLocal PAGINATION_TOTAL = new ThreadLocal();
55 | private static final ThreadLocal PAGE_REQUEST = new ThreadLocal();
56 | /** logging */
57 | private static final Log log = LogFactory.getLog(PaginationInterceptor.class);
58 | /** mapped statement parameter index. */
59 | private static final int MAPPED_STATEMENT_INDEX = 0;
60 | /** sql id , in the mapper xml file. */
61 | private static String _sql_regex = "[*]";
62 | /** DataBase dialect. */
63 | protected Dialect _dialect;
64 |
65 | /**
66 | * Gets pagination total.
67 | *
68 | * @return the pagination total
69 | */
70 | public static int getPaginationTotal() {
71 | if (PAGINATION_TOTAL.get() == null) {
72 | return 0;
73 | }
74 | return PAGINATION_TOTAL.get();
75 | }
76 |
77 | /**
78 | * Gets page request.
79 | *
80 | * @return the page request
81 | */
82 | public static PagingCriteria getPageRequest() {
83 | return PAGE_REQUEST.get();
84 | }
85 |
86 | /** clear total context. */
87 | public static void clean() {
88 | PAGE_REQUEST.remove();
89 | PAGINATION_TOTAL.remove();
90 | }
91 |
92 | /**
93 | * Set the paging information,to RowBuounds.
94 | *
95 | * @param rowBounds rowBounds.
96 | * @return rowBounds.
97 | */
98 | private static RowBounds offset_paging(RowBounds rowBounds, PagingCriteria pageRequest) {
99 | // rowBuounds has offset.
100 | if (rowBounds.getOffset() == RowBounds.NO_ROW_OFFSET) {
101 | if (pageRequest != null) {
102 | return new RowBounds(pageRequest.getDisplayStart(), pageRequest.getDisplaySize());
103 | }
104 | }
105 | return rowBounds;
106 | }
107 |
108 | /**
109 | * Sort and filter sql.
110 | *
111 | *
112 | * @param sql the sql
113 | * @param pagingCriteria the paging criteria
114 | * @return the string
115 | */
116 | private static String sortAndFilterSql(String sql, PagingCriteria pagingCriteria) {
117 |
118 | boolean order = SqlRemoveHelper.containOrder(sql);
119 | final List searchFields = pagingCriteria.getSearchFields();
120 | if (searchFields != null && !searchFields.isEmpty()) {
121 | List where_field = Lists.newArrayList();
122 | for (SearchField searchField : searchFields) {
123 | // fix inject sql
124 | where_field.add(searchField.getField() + StringHelper.LIKE_CHAR + StringHelper.likeValue(searchField.getValue()));
125 | }
126 | boolean where = SqlRemoveHelper.containWhere(sql);
127 | String orderBy = StringHelper.EMPTY;
128 | if (order) {
129 | String[] sqls = sql.split(SqlRemoveHelper.ORDER_REGEX);
130 | sql = sqls[0];
131 | orderBy = CountHelper.SQL_ORDER + sqls[1];
132 | }
133 | sql = String.format((where ? CountHelper.OR_SQL_FORMAT : CountHelper.WHERE_SQL_FORMAT), sql
134 | , Joiner.on(CountHelper.OR_JOINER).skipNulls().join(where_field), orderBy);
135 | }
136 |
137 | final List sortFields = pagingCriteria.getSortFields();
138 | if (sortFields != null && !sortFields.isEmpty()) {
139 | List field_order = Lists.newArrayList();
140 | for (SortField sortField : sortFields) {
141 | field_order.add(sortField.getField() + StringHelper.BLANK_CHAR + sortField.getDirection().getDirection());
142 | }
143 | return String.format(order ? CountHelper.SQL_FORMAT : CountHelper.ORDER_SQL_FORMAT, sql
144 | , Joiner.on(StringHelper.DOT_CHAR).skipNulls().join(field_order));
145 | }
146 |
147 | return sql;
148 | }
149 |
150 | /**
151 | * Copy from bound sql.
152 | *
153 | * @param ms the ms
154 | * @param boundSql the bound sql
155 | * @param sql the sql
156 | * @return the bound sql
157 | */
158 | public static BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql,
159 | String sql) {
160 | BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
161 | for (ParameterMapping mapping : boundSql.getParameterMappings()) {
162 | String prop = mapping.getProperty();
163 | if (boundSql.hasAdditionalParameter(prop)) {
164 | newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
165 | }
166 | }
167 | return newBoundSql;
168 | }
169 |
170 | //see: MapperBuilderAssistant
171 | private static MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
172 | MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
173 |
174 | builder.resource(ms.getResource());
175 | builder.fetchSize(ms.getFetchSize());
176 | builder.statementType(ms.getStatementType());
177 | builder.keyGenerator(ms.getKeyGenerator());
178 | String[] keyProperties = ms.getKeyProperties();
179 | builder.keyProperty(keyProperties == null ? null : keyProperties[0]);
180 |
181 | //setStatementTimeout()
182 | builder.timeout(ms.getTimeout());
183 |
184 | //setStatementResultMap()
185 | builder.parameterMap(ms.getParameterMap());
186 |
187 | //setStatementResultMap()
188 | builder.resultMaps(ms.getResultMaps());
189 | builder.resultSetType(ms.getResultSetType());
190 |
191 | //setStatementCache()
192 | builder.cache(ms.getCache());
193 | builder.flushCacheRequired(ms.isFlushCacheRequired());
194 | builder.useCache(ms.isUseCache());
195 |
196 | return builder.build();
197 | }
198 |
199 | /**
200 | * perform paging intercetion.
201 | *
202 | * @param queryArgs Executor.query params.
203 | */
204 | private void processIntercept(final Object[] queryArgs) {
205 | final MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
206 | final Object parameter = queryArgs[1];
207 |
208 | //the need for paging intercept.
209 | boolean interceptor = ms.getId().matches(_sql_regex);
210 | //obtain paging information.
211 | final PagingCriteria pageRequest = interceptor
212 | ? PagingParametersFinder.instance.findCriteria(parameter)
213 | : PagingCriteria.getDefaultCriteria();
214 | PAGE_REQUEST.set(pageRequest);
215 |
216 | final RowBounds oldRow = (RowBounds) queryArgs[2];
217 | final RowBounds rowBounds = (interceptor) ? offset_paging(oldRow, pageRequest) : oldRow;
218 | int offset = rowBounds.getOffset();
219 | int limit = rowBounds.getLimit();
220 |
221 | if (_dialect.supportsLimit() && (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) {
222 | final BoundSql boundSql = ms.getBoundSql(parameter);
223 | String sql = boundSql.getSql().trim();
224 |
225 | Connection connection = null;
226 | try {
227 | //get connection
228 | connection = ms.getConfiguration().getEnvironment().getDataSource().getConnection();
229 | int count = CountHelper.getCount(sql, connection, ms, parameter, boundSql, _dialect);
230 | PAGINATION_TOTAL.set(count);
231 | } catch (SQLException e) {
232 | log.error("The total number of access to the database failure.", e);
233 | } finally {
234 | try {
235 | if (connection != null && !connection.isClosed()) {
236 | connection.close();
237 | }
238 | } catch (SQLException e) {
239 | log.error("Close the database connection error.", e);
240 | }
241 | }
242 | String new_sql = sortAndFilterSql(sql, pageRequest);
243 | if (_dialect.supportsLimit()) {
244 | new_sql = _dialect.getLimitString(new_sql, offset, limit);
245 | offset = RowBounds.NO_ROW_OFFSET;
246 | } else {
247 | new_sql = _dialect.getLimitString(new_sql, 0, limit);
248 | }
249 | if (log.isDebugEnabled()) {
250 | log.debug("pagination sql is :[" + new_sql + "]");
251 | }
252 | limit = RowBounds.NO_ROW_LIMIT;
253 |
254 | queryArgs[2] = new RowBounds(offset, limit);
255 |
256 | BoundSql newBoundSql = copyFromBoundSql(ms, boundSql, new_sql);
257 |
258 | MappedStatement newMs = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
259 | queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
260 | }
261 | }
262 |
263 | @Override
264 | public Object intercept(Invocation invocation) throws Throwable {
265 | processIntercept(invocation.getArgs());
266 | return invocation.proceed();
267 | }
268 |
269 | @Override
270 | public Object plugin(Object o) {
271 |
272 | if (Executor.class.isAssignableFrom(o.getClass())) {
273 | return Plugin.wrap(new PaginationExecutor((Executor) o), this);
274 | }
275 | return Plugin.wrap(o, this);
276 |
277 | }
278 |
279 | /**
280 | * 设置属性,支持自定义方言类和制定数据库的方式
281 | *
282 | * dialectClass,自定义方言类。可以不配置这项
283 | * dbms 数据库类型,插件支持的数据库
284 | * sqlRegex 需要拦截的SQL ID
285 | *
286 | * 如果同时配置了dialectClass和dbms,则以dbms为主
287 | *
288 | * @param p 属性
289 | */
290 | @Override
291 | public void setProperties(Properties p) {
292 | String dialectClass = p.getProperty("dialectClass");
293 | DBMS dbms;
294 | if (StringHelper.isEmpty(dialectClass)) {
295 | String dialect = p.getProperty("dbms");
296 | Preconditions.checkArgument(!StringHelper.isEmpty(dialect), "dialect property is not found!");
297 | dbms = DBMS.valueOf(dialect.toUpperCase());
298 | Preconditions.checkNotNull(dbms, "plugin not super on this database.");
299 | } else {
300 | Dialect dialect1 = (Dialect) Reflections.instance(dialectClass);
301 | Preconditions.checkNotNull(dialect1, "dialectClass is not found!");
302 | DialectClient.putEx(dialect1);
303 | dbms = DBMS.EX;
304 | }
305 |
306 |
307 | _dialect = DialectClient.getDbmsDialect(dbms);
308 |
309 | String sql_regex = p.getProperty("sqlRegex");
310 | if (!StringHelper.isEmpty(sql_regex)) {
311 | _sql_regex = sql_regex;
312 | }
313 | clean();
314 | }
315 |
316 | public static class BoundSqlSqlSource implements SqlSource {
317 | BoundSql boundSql;
318 |
319 | public BoundSqlSqlSource(BoundSql boundSql) {
320 | this.boundSql = boundSql;
321 | }
322 |
323 | public BoundSql getBoundSql(Object parameterObject) {
324 | return boundSql;
325 | }
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/src/test/resources/mapper/ResourcesMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | and ${criterion.condition}
30 |
31 |
32 | and ${criterion.condition} #{criterion.value}
33 |
34 |
35 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
36 |
37 |
38 | and ${criterion.condition}
39 |
41 | #{listItem}
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | and ${criterion.condition}
64 |
65 |
66 | and ${criterion.condition} #{criterion.value}
67 |
68 |
69 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
70 |
71 |
72 | and ${criterion.condition}
73 |
75 | #{listItem}
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
90 | id, name, type, path, action, controller, status
91 |
92 |
93 |
97 | select
98 |
99 | distinct
100 |
101 |
102 | from res
103 |
104 |
105 |
106 |
107 | order by ${orderByClause}
108 |
109 |
110 |
111 |
115 | select
116 |
117 | from res
118 | where id = #{id,jdbcType=VARCHAR}
119 |
120 |
121 |
125 | delete from res
126 | where id = #{id,jdbcType=VARCHAR}
127 |
128 |
129 |
133 | delete from res
134 |
135 |
136 |
137 |
138 |
139 |
143 | insert into res (id, name, type,
144 | path, action, controller,
145 | status)
146 | values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
147 | #{path,jdbcType=VARCHAR}, #{action,jdbcType=VARCHAR}, #{controller,jdbcType=VARCHAR},
148 | #{status,jdbcType=BIT})
149 |
150 |
151 |
155 | insert into res
156 |
157 |
158 | id,
159 |
160 |
161 | name,
162 |
163 |
164 | type,
165 |
166 |
167 | path,
168 |
169 |
170 | action,
171 |
172 |
173 | controller,
174 |
175 |
176 | status,
177 |
178 |
179 |
180 |
181 | #{id,jdbcType=VARCHAR},
182 |
183 |
184 | #{name,jdbcType=VARCHAR},
185 |
186 |
187 | #{type,jdbcType=VARCHAR},
188 |
189 |
190 | #{path,jdbcType=VARCHAR},
191 |
192 |
193 | #{action,jdbcType=VARCHAR},
194 |
195 |
196 | #{controller,jdbcType=VARCHAR},
197 |
198 |
199 | #{status,jdbcType=BIT},
200 |
201 |
202 |
203 |
204 |
208 | update res
209 |
210 |
211 | id = #{record.id,jdbcType=VARCHAR},
212 |
213 |
214 | name = #{record.name,jdbcType=VARCHAR},
215 |
216 |
217 | type = #{record.type,jdbcType=VARCHAR},
218 |
219 |
220 | path = #{record.path,jdbcType=VARCHAR},
221 |
222 |
223 | action = #{record.action,jdbcType=VARCHAR},
224 |
225 |
226 | controller = #{record.controller,jdbcType=VARCHAR},
227 |
228 |
229 | status = #{record.status,jdbcType=BIT},
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
241 | update res
242 | set id = #{record.id,jdbcType=VARCHAR},
243 | name = #{record.name,jdbcType=VARCHAR},
244 | type = #{record.type,jdbcType=VARCHAR},
245 | path = #{record.path,jdbcType=VARCHAR},
246 | action = #{record.action,jdbcType=VARCHAR},
247 | controller = #{record.controller,jdbcType=VARCHAR},
248 | status = #{record.status,jdbcType=BIT}
249 |
250 |
251 |
252 |
253 |
254 |
258 | update res
259 |
260 |
261 | name = #{name,jdbcType=VARCHAR},
262 |
263 |
264 | type = #{type,jdbcType=VARCHAR},
265 |
266 |
267 | path = #{path,jdbcType=VARCHAR},
268 |
269 |
270 | action = #{action,jdbcType=VARCHAR},
271 |
272 |
273 | controller = #{controller,jdbcType=VARCHAR},
274 |
275 |
276 | status = #{status,jdbcType=BIT},
277 |
278 |
279 | where id = #{id,jdbcType=VARCHAR}
280 |
281 |
282 |
286 | update res
287 | set name = #{name,jdbcType=VARCHAR},
288 | type = #{type,jdbcType=VARCHAR},
289 | path = #{path,jdbcType=VARCHAR},
290 | action = #{action,jdbcType=VARCHAR},
291 | controller = #{controller,jdbcType=VARCHAR},
292 | status = #{status,jdbcType=BIT}
293 | where id = #{id,jdbcType=VARCHAR}
294 |
295 |
296 |
297 | select id, name, type, path, action, controller, status from res
298 |
299 |
300 |
301 | select id, name, type, path, action, controller, status from res order by name
302 |
303 |
304 | select id, name, type, path, action, controller, status from res where name=#{name} order by name
305 |
306 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/pagination/domain/ResourcesCriteria.java:
--------------------------------------------------------------------------------
1 | package org.mybatis.pagination.domain;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class ResourcesCriteria {
7 | /**
8 | * 排序字段,auth_resources
9 | */
10 | protected String orderByClause;
11 |
12 | /**
13 | * 是否过滤重复数据,auth_resources
14 | */
15 | protected boolean distinct;
16 |
17 | /**
18 | * ,auth_resources
19 | */
20 | protected List oredCriteria;
21 |
22 | /**
23 | * 构造查询条件,auth_resources
24 | */
25 | public ResourcesCriteria() {
26 | oredCriteria = new ArrayList();
27 | }
28 |
29 | /**
30 | * 为系统资源设置排序字段,auth_resources
31 | *
32 | * @param orderByClause 排序字段
33 | */
34 | public void setOrderByClause(String orderByClause) {
35 | this.orderByClause = orderByClause;
36 | }
37 |
38 | /**
39 | * 获取排序字段,auth_resources
40 | */
41 | public String getOrderByClause() {
42 | return orderByClause;
43 | }
44 |
45 | /**
46 | * 为系统资源设置过滤重复数据,auth_resources
47 | *
48 | * @param distinct 是否过滤重复数据
49 | */
50 | public void setDistinct(boolean distinct) {
51 | this.distinct = distinct;
52 | }
53 |
54 | /**
55 | * 是否过滤重复数据,auth_resources
56 | */
57 | public boolean isDistinct() {
58 | return distinct;
59 | }
60 |
61 | /**
62 | * 获取当前的查询条件实例,auth_resources
63 | */
64 | public List getOredCriteria() {
65 | return oredCriteria;
66 | }
67 |
68 | /**
69 | * ,auth_resources
70 | *
71 | * @param criteria 过滤条件实例
72 | */
73 | public void or(Criteria criteria) {
74 | oredCriteria.add(criteria);
75 | }
76 |
77 | /**
78 | * ,auth_resources
79 | */
80 | public Criteria or() {
81 | Criteria criteria = createCriteriaInternal();
82 | oredCriteria.add(criteria);
83 | return criteria;
84 | }
85 |
86 | /**
87 | * 为系统资源创建一个查询条件,auth_resources
88 | */
89 | public Criteria createCriteria() {
90 | Criteria criteria = createCriteriaInternal();
91 | if (oredCriteria.size() == 0) {
92 | oredCriteria.add(criteria);
93 | }
94 | return criteria;
95 | }
96 |
97 | /**
98 | * 内部构建查询条件对象,auth_resources
99 | */
100 | protected Criteria createCriteriaInternal() {
101 | Criteria criteria = new Criteria();
102 | return criteria;
103 | }
104 |
105 | /**
106 | * 清除查询条件,auth_resources
107 | */
108 | public void clear() {
109 | oredCriteria.clear();
110 | orderByClause = null;
111 | distinct = false;
112 | }
113 |
114 | /**
115 | * 基本动态SQL对象,auth_resources
116 | */
117 | protected abstract static class GeneratedCriteria {
118 | protected List criteria;
119 |
120 | protected GeneratedCriteria() {
121 | super();
122 | criteria = new ArrayList();
123 | }
124 |
125 | public boolean isValid() {
126 | return criteria.size() > 0;
127 | }
128 |
129 | public List getAllCriteria() {
130 | return criteria;
131 | }
132 |
133 | public List getCriteria() {
134 | return criteria;
135 | }
136 |
137 | protected void addCriterion(String condition) {
138 | if (condition == null) {
139 | throw new RuntimeException("Value for condition cannot be null");
140 | }
141 | criteria.add(new Criterion(condition));
142 | }
143 |
144 | protected void addCriterion(String condition, Object value, String property) {
145 | if (value == null) {
146 | throw new RuntimeException("Value for " + property + " cannot be null");
147 | }
148 | criteria.add(new Criterion(condition, value));
149 | }
150 |
151 | protected void addCriterion(String condition, Object value1, Object value2, String property) {
152 | if (value1 == null || value2 == null) {
153 | throw new RuntimeException("Between values for " + property + " cannot be null");
154 | }
155 | criteria.add(new Criterion(condition, value1, value2));
156 | }
157 |
158 | public Criteria andIdIsNull() {
159 | addCriterion("id is null");
160 | return (Criteria) this;
161 | }
162 |
163 | public Criteria andIdIsNotNull() {
164 | addCriterion("id is not null");
165 | return (Criteria) this;
166 | }
167 |
168 | public Criteria andIdEqualTo(String value) {
169 | addCriterion("id =", value, "id");
170 | return (Criteria) this;
171 | }
172 |
173 | public Criteria andIdNotEqualTo(String value) {
174 | addCriterion("id <>", value, "id");
175 | return (Criteria) this;
176 | }
177 |
178 | public Criteria andIdGreaterThan(String value) {
179 | addCriterion("id >", value, "id");
180 | return (Criteria) this;
181 | }
182 |
183 | public Criteria andIdGreaterThanOrEqualTo(String value) {
184 | addCriterion("id >=", value, "id");
185 | return (Criteria) this;
186 | }
187 |
188 | public Criteria andIdLessThan(String value) {
189 | addCriterion("id <", value, "id");
190 | return (Criteria) this;
191 | }
192 |
193 | public Criteria andIdLessThanOrEqualTo(String value) {
194 | addCriterion("id <=", value, "id");
195 | return (Criteria) this;
196 | }
197 |
198 | public Criteria andIdLike(String value) {
199 | addCriterion("id like", value, "id");
200 | return (Criteria) this;
201 | }
202 |
203 | public Criteria andIdNotLike(String value) {
204 | addCriterion("id not like", value, "id");
205 | return (Criteria) this;
206 | }
207 |
208 | public Criteria andIdIn(List values) {
209 | addCriterion("id in", values, "id");
210 | return (Criteria) this;
211 | }
212 |
213 | public Criteria andIdNotIn(List values) {
214 | addCriterion("id not in", values, "id");
215 | return (Criteria) this;
216 | }
217 |
218 | public Criteria andIdBetween(String value1, String value2) {
219 | addCriterion("id between", value1, value2, "id");
220 | return (Criteria) this;
221 | }
222 |
223 | public Criteria andIdNotBetween(String value1, String value2) {
224 | addCriterion("id not between", value1, value2, "id");
225 | return (Criteria) this;
226 | }
227 |
228 | public Criteria andNameIsNull() {
229 | addCriterion("name is null");
230 | return (Criteria) this;
231 | }
232 |
233 | public Criteria andNameIsNotNull() {
234 | addCriterion("name is not null");
235 | return (Criteria) this;
236 | }
237 |
238 | public Criteria andNameEqualTo(String value) {
239 | addCriterion("name =", value, "name");
240 | return (Criteria) this;
241 | }
242 |
243 | public Criteria andNameNotEqualTo(String value) {
244 | addCriterion("name <>", value, "name");
245 | return (Criteria) this;
246 | }
247 |
248 | public Criteria andNameGreaterThan(String value) {
249 | addCriterion("name >", value, "name");
250 | return (Criteria) this;
251 | }
252 |
253 | public Criteria andNameGreaterThanOrEqualTo(String value) {
254 | addCriterion("name >=", value, "name");
255 | return (Criteria) this;
256 | }
257 |
258 | public Criteria andNameLessThan(String value) {
259 | addCriterion("name <", value, "name");
260 | return (Criteria) this;
261 | }
262 |
263 | public Criteria andNameLessThanOrEqualTo(String value) {
264 | addCriterion("name <=", value, "name");
265 | return (Criteria) this;
266 | }
267 |
268 | public Criteria andNameLike(String value) {
269 | addCriterion("name like", value, "name");
270 | return (Criteria) this;
271 | }
272 |
273 | public Criteria andNameNotLike(String value) {
274 | addCriterion("name not like", value, "name");
275 | return (Criteria) this;
276 | }
277 |
278 | public Criteria andNameIn(List values) {
279 | addCriterion("name in", values, "name");
280 | return (Criteria) this;
281 | }
282 |
283 | public Criteria andNameNotIn(List values) {
284 | addCriterion("name not in", values, "name");
285 | return (Criteria) this;
286 | }
287 |
288 | public Criteria andNameBetween(String value1, String value2) {
289 | addCriterion("name between", value1, value2, "name");
290 | return (Criteria) this;
291 | }
292 |
293 | public Criteria andNameNotBetween(String value1, String value2) {
294 | addCriterion("name not between", value1, value2, "name");
295 | return (Criteria) this;
296 | }
297 |
298 | public Criteria andTypeIsNull() {
299 | addCriterion("type is null");
300 | return (Criteria) this;
301 | }
302 |
303 | public Criteria andTypeIsNotNull() {
304 | addCriterion("type is not null");
305 | return (Criteria) this;
306 | }
307 |
308 | public Criteria andTypeEqualTo(String value) {
309 | addCriterion("type =", value, "type");
310 | return (Criteria) this;
311 | }
312 |
313 | public Criteria andTypeNotEqualTo(String value) {
314 | addCriterion("type <>", value, "type");
315 | return (Criteria) this;
316 | }
317 |
318 | public Criteria andTypeGreaterThan(String value) {
319 | addCriterion("type >", value, "type");
320 | return (Criteria) this;
321 | }
322 |
323 | public Criteria andTypeGreaterThanOrEqualTo(String value) {
324 | addCriterion("type >=", value, "type");
325 | return (Criteria) this;
326 | }
327 |
328 | public Criteria andTypeLessThan(String value) {
329 | addCriterion("type <", value, "type");
330 | return (Criteria) this;
331 | }
332 |
333 | public Criteria andTypeLessThanOrEqualTo(String value) {
334 | addCriterion("type <=", value, "type");
335 | return (Criteria) this;
336 | }
337 |
338 | public Criteria andTypeLike(String value) {
339 | addCriterion("type like", value, "type");
340 | return (Criteria) this;
341 | }
342 |
343 | public Criteria andTypeNotLike(String value) {
344 | addCriterion("type not like", value, "type");
345 | return (Criteria) this;
346 | }
347 |
348 | public Criteria andTypeIn(List values) {
349 | addCriterion("type in", values, "type");
350 | return (Criteria) this;
351 | }
352 |
353 | public Criteria andTypeNotIn(List values) {
354 | addCriterion("type not in", values, "type");
355 | return (Criteria) this;
356 | }
357 |
358 | public Criteria andTypeBetween(String value1, String value2) {
359 | addCriterion("type between", value1, value2, "type");
360 | return (Criteria) this;
361 | }
362 |
363 | public Criteria andTypeNotBetween(String value1, String value2) {
364 | addCriterion("type not between", value1, value2, "type");
365 | return (Criteria) this;
366 | }
367 |
368 | public Criteria andPathIsNull() {
369 | addCriterion("path is null");
370 | return (Criteria) this;
371 | }
372 |
373 | public Criteria andPathIsNotNull() {
374 | addCriterion("path is not null");
375 | return (Criteria) this;
376 | }
377 |
378 | public Criteria andPathEqualTo(String value) {
379 | addCriterion("path =", value, "path");
380 | return (Criteria) this;
381 | }
382 |
383 | public Criteria andPathNotEqualTo(String value) {
384 | addCriterion("path <>", value, "path");
385 | return (Criteria) this;
386 | }
387 |
388 | public Criteria andPathGreaterThan(String value) {
389 | addCriterion("path >", value, "path");
390 | return (Criteria) this;
391 | }
392 |
393 | public Criteria andPathGreaterThanOrEqualTo(String value) {
394 | addCriterion("path >=", value, "path");
395 | return (Criteria) this;
396 | }
397 |
398 | public Criteria andPathLessThan(String value) {
399 | addCriterion("path <", value, "path");
400 | return (Criteria) this;
401 | }
402 |
403 | public Criteria andPathLessThanOrEqualTo(String value) {
404 | addCriterion("path <=", value, "path");
405 | return (Criteria) this;
406 | }
407 |
408 | public Criteria andPathLike(String value) {
409 | addCriterion("path like", value, "path");
410 | return (Criteria) this;
411 | }
412 |
413 | public Criteria andPathNotLike(String value) {
414 | addCriterion("path not like", value, "path");
415 | return (Criteria) this;
416 | }
417 |
418 | public Criteria andPathIn(List values) {
419 | addCriterion("path in", values, "path");
420 | return (Criteria) this;
421 | }
422 |
423 | public Criteria andPathNotIn(List values) {
424 | addCriterion("path not in", values, "path");
425 | return (Criteria) this;
426 | }
427 |
428 | public Criteria andPathBetween(String value1, String value2) {
429 | addCriterion("path between", value1, value2, "path");
430 | return (Criteria) this;
431 | }
432 |
433 | public Criteria andPathNotBetween(String value1, String value2) {
434 | addCriterion("path not between", value1, value2, "path");
435 | return (Criteria) this;
436 | }
437 |
438 | public Criteria andActionIsNull() {
439 | addCriterion("action is null");
440 | return (Criteria) this;
441 | }
442 |
443 | public Criteria andActionIsNotNull() {
444 | addCriterion("action is not null");
445 | return (Criteria) this;
446 | }
447 |
448 | public Criteria andActionEqualTo(String value) {
449 | addCriterion("action =", value, "action");
450 | return (Criteria) this;
451 | }
452 |
453 | public Criteria andActionNotEqualTo(String value) {
454 | addCriterion("action <>", value, "action");
455 | return (Criteria) this;
456 | }
457 |
458 | public Criteria andActionGreaterThan(String value) {
459 | addCriterion("action >", value, "action");
460 | return (Criteria) this;
461 | }
462 |
463 | public Criteria andActionGreaterThanOrEqualTo(String value) {
464 | addCriterion("action >=", value, "action");
465 | return (Criteria) this;
466 | }
467 |
468 | public Criteria andActionLessThan(String value) {
469 | addCriterion("action <", value, "action");
470 | return (Criteria) this;
471 | }
472 |
473 | public Criteria andActionLessThanOrEqualTo(String value) {
474 | addCriterion("action <=", value, "action");
475 | return (Criteria) this;
476 | }
477 |
478 | public Criteria andActionLike(String value) {
479 | addCriterion("action like", value, "action");
480 | return (Criteria) this;
481 | }
482 |
483 | public Criteria andActionNotLike(String value) {
484 | addCriterion("action not like", value, "action");
485 | return (Criteria) this;
486 | }
487 |
488 | public Criteria andActionIn(List values) {
489 | addCriterion("action in", values, "action");
490 | return (Criteria) this;
491 | }
492 |
493 | public Criteria andActionNotIn(List values) {
494 | addCriterion("action not in", values, "action");
495 | return (Criteria) this;
496 | }
497 |
498 | public Criteria andActionBetween(String value1, String value2) {
499 | addCriterion("action between", value1, value2, "action");
500 | return (Criteria) this;
501 | }
502 |
503 | public Criteria andActionNotBetween(String value1, String value2) {
504 | addCriterion("action not between", value1, value2, "action");
505 | return (Criteria) this;
506 | }
507 |
508 | public Criteria andControllerIsNull() {
509 | addCriterion("controller is null");
510 | return (Criteria) this;
511 | }
512 |
513 | public Criteria andControllerIsNotNull() {
514 | addCriterion("controller is not null");
515 | return (Criteria) this;
516 | }
517 |
518 | public Criteria andControllerEqualTo(String value) {
519 | addCriterion("controller =", value, "controller");
520 | return (Criteria) this;
521 | }
522 |
523 | public Criteria andControllerNotEqualTo(String value) {
524 | addCriterion("controller <>", value, "controller");
525 | return (Criteria) this;
526 | }
527 |
528 | public Criteria andControllerGreaterThan(String value) {
529 | addCriterion("controller >", value, "controller");
530 | return (Criteria) this;
531 | }
532 |
533 | public Criteria andControllerGreaterThanOrEqualTo(String value) {
534 | addCriterion("controller >=", value, "controller");
535 | return (Criteria) this;
536 | }
537 |
538 | public Criteria andControllerLessThan(String value) {
539 | addCriterion("controller <", value, "controller");
540 | return (Criteria) this;
541 | }
542 |
543 | public Criteria andControllerLessThanOrEqualTo(String value) {
544 | addCriterion("controller <=", value, "controller");
545 | return (Criteria) this;
546 | }
547 |
548 | public Criteria andControllerLike(String value) {
549 | addCriterion("controller like", value, "controller");
550 | return (Criteria) this;
551 | }
552 |
553 | public Criteria andControllerNotLike(String value) {
554 | addCriterion("controller not like", value, "controller");
555 | return (Criteria) this;
556 | }
557 |
558 | public Criteria andControllerIn(List values) {
559 | addCriterion("controller in", values, "controller");
560 | return (Criteria) this;
561 | }
562 |
563 | public Criteria andControllerNotIn(List values) {
564 | addCriterion("controller not in", values, "controller");
565 | return (Criteria) this;
566 | }
567 |
568 | public Criteria andControllerBetween(String value1, String value2) {
569 | addCriterion("controller between", value1, value2, "controller");
570 | return (Criteria) this;
571 | }
572 |
573 | public Criteria andControllerNotBetween(String value1, String value2) {
574 | addCriterion("controller not between", value1, value2, "controller");
575 | return (Criteria) this;
576 | }
577 |
578 | public Criteria andStatusIsNull() {
579 | addCriterion("status is null");
580 | return (Criteria) this;
581 | }
582 |
583 | public Criteria andStatusIsNotNull() {
584 | addCriterion("status is not null");
585 | return (Criteria) this;
586 | }
587 |
588 | public Criteria andStatusEqualTo(Boolean value) {
589 | addCriterion("status =", value, "status");
590 | return (Criteria) this;
591 | }
592 |
593 | public Criteria andStatusNotEqualTo(Boolean value) {
594 | addCriterion("status <>", value, "status");
595 | return (Criteria) this;
596 | }
597 |
598 | public Criteria andStatusGreaterThan(Boolean value) {
599 | addCriterion("status >", value, "status");
600 | return (Criteria) this;
601 | }
602 |
603 | public Criteria andStatusGreaterThanOrEqualTo(Boolean value) {
604 | addCriterion("status >=", value, "status");
605 | return (Criteria) this;
606 | }
607 |
608 | public Criteria andStatusLessThan(Boolean value) {
609 | addCriterion("status <", value, "status");
610 | return (Criteria) this;
611 | }
612 |
613 | public Criteria andStatusLessThanOrEqualTo(Boolean value) {
614 | addCriterion("status <=", value, "status");
615 | return (Criteria) this;
616 | }
617 |
618 | public Criteria andStatusIn(List values) {
619 | addCriterion("status in", values, "status");
620 | return (Criteria) this;
621 | }
622 |
623 | public Criteria andStatusNotIn(List values) {
624 | addCriterion("status not in", values, "status");
625 | return (Criteria) this;
626 | }
627 |
628 | public Criteria andStatusBetween(Boolean value1, Boolean value2) {
629 | addCriterion("status between", value1, value2, "status");
630 | return (Criteria) this;
631 | }
632 |
633 | public Criteria andStatusNotBetween(Boolean value1, Boolean value2) {
634 | addCriterion("status not between", value1, value2, "status");
635 | return (Criteria) this;
636 | }
637 | }
638 |
639 | /**
640 | * 数据库表 auth_resources映射实体
641 | */
642 | public static class Criteria extends GeneratedCriteria {
643 |
644 | protected Criteria() {
645 | super();
646 | }
647 | }
648 |
649 | /**
650 | * 动态SQL对象,auth_resources
651 | */
652 | public static class Criterion {
653 | private String condition;
654 |
655 | private Object value;
656 |
657 | private Object secondValue;
658 |
659 | private boolean noValue;
660 |
661 | private boolean singleValue;
662 |
663 | private boolean betweenValue;
664 |
665 | private boolean listValue;
666 |
667 | private String typeHandler;
668 |
669 | public String getCondition() {
670 | return condition;
671 | }
672 |
673 | public Object getValue() {
674 | return value;
675 | }
676 |
677 | public Object getSecondValue() {
678 | return secondValue;
679 | }
680 |
681 | public boolean isNoValue() {
682 | return noValue;
683 | }
684 |
685 | public boolean isSingleValue() {
686 | return singleValue;
687 | }
688 |
689 | public boolean isBetweenValue() {
690 | return betweenValue;
691 | }
692 |
693 | public boolean isListValue() {
694 | return listValue;
695 | }
696 |
697 | public String getTypeHandler() {
698 | return typeHandler;
699 | }
700 |
701 | protected Criterion(String condition) {
702 | super();
703 | this.condition = condition;
704 | this.typeHandler = null;
705 | this.noValue = true;
706 | }
707 |
708 | protected Criterion(String condition, Object value, String typeHandler) {
709 | super();
710 | this.condition = condition;
711 | this.value = value;
712 | this.typeHandler = typeHandler;
713 | if (value instanceof List>) {
714 | this.listValue = true;
715 | } else {
716 | this.singleValue = true;
717 | }
718 | }
719 |
720 | protected Criterion(String condition, Object value) {
721 | this(condition, value, null);
722 | }
723 |
724 | protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
725 | super();
726 | this.condition = condition;
727 | this.value = value;
728 | this.secondValue = secondValue;
729 | this.typeHandler = typeHandler;
730 | this.betweenValue = true;
731 | }
732 |
733 | protected Criterion(String condition, Object value, Object secondValue) {
734 | this(condition, value, secondValue, null);
735 | }
736 | }
737 | }
--------------------------------------------------------------------------------