一 方言
mybatis.pagination.dialect.Dialect.java
1
2
3
4
5
6
7
8
|
package
mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public
interface
Dialect {
public
String getLimitString(String sql,
int
offset,
int
limit);
}
|
mybatis.pagination.dialect.MySqlDialect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package
mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public
class
MySqlDialect
implements
Dialect{
@Override
public
String getLimitString(String sql,
int
offset,
int
limit) {
String newSql =
"select * from ("
+sql+
") e limit "
+offset+
","
+limit;
return
newSql;
}
}
|
mybatis.pagination.dialect.DialectProvider.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package
mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public
class
DialectProvider {
private
static
DialectProvider dialectProvider =
new
DialectProvider();
private
DialectProvider(){}
public
static
DialectProvider getInstance(){
return
dialectProvider;
}
public
Dialect getDialect(String dialectName){
if
(
"mysql"
.equals(dialectName)){
return
new
MySqlDialect();
}
throw
new
RuntimeException(
"can't find the specified dialect : "
+dialectName);
}
}
|
二 分页拦截器
mybatis.pagination.interceptor.PaginationInterceptor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package
mybatis.pagination.interceptor;
import
mybatis.pagination.dialect.Dialect;
import
mybatis.pagination.dialect.DialectProvider;
import
org.apache.ibatis.executor.statement.StatementHandler;
import
org.apache.ibatis.mapping.BoundSql;
import
org.apache.ibatis.plugin.*;
import
org.apache.ibatis.reflection.MetaObject;
import
org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import
org.apache.ibatis.reflection.factory.ObjectFactory;
import
org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import
org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import
org.apache.ibatis.session.Configuration;
import
org.apache.ibatis.session.RowBounds;
import
java.sql.Connection;
import
java.util.Properties;
/**
* 通过拦截<code>StatementHandler</code>的<code>prepare</code>方法,重写sql语句实现物理分页。
* 老规矩,签名里要拦截的类型只能是接口。
*
*/
@Intercepts
({
@Signature
(type = StatementHandler.
class
, method =
"prepare"
, args = {Connection.
class
})})
public
class
PaginationInterceptor
implements
Interceptor {
private
static
final
ObjectFactory DEFAULT_OBJECT_FACTORY =
new
DefaultObjectFactory();
private
static
final
ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY =
new
DefaultObjectWrapperFactory();
@Override
public
Object intercept(Invocation invocation)
throws
Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,DEFAULT_OBJECT_WRAPPER_FACTORY);
RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue(
"delegate.rowBounds"
);
// property在mybatis settings文件内配置
Configuration configuration = (Configuration) metaStatementHandler.getValue(
"delegate.configuration"
);
// 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue(
"delegate.boundSql"
);
String sql = boundSql.getSql();
// 重写sql
Dialect dialect = getDialect(configuration);
String newSql = dialect.getLimitString(sql,rowBounds.getOffset(),rowBounds.getLimit());
metaStatementHandler.setValue(
"delegate.boundSql.sql"
, newSql);
// 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
metaStatementHandler.setValue(
"delegate.rowBounds.offset"
, RowBounds.NO_ROW_OFFSET);
metaStatementHandler.setValue(
"delegate.rowBounds.limit"
, RowBounds.NO_ROW_LIMIT);
// 将执行权交给下一个拦截器
return
invocation.proceed();
}
private
Dialect getDialect(Configuration configuration){
Properties properties = configuration.getVariables();
if
(properties==
null
){
properties =
new
Properties();
}
String dialectName = properties.getProperty(
"dialect"
,
"mysql"
);
return
DialectProvider.getInstance().getDialect(dialectName);
}
@Override
public
Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
if
(target
instanceof
StatementHandler) {
return
Plugin.wrap(target,
this
);
}
else
{
return
target;
}
}
@Override
public
void
setProperties(Properties properties) {
//To change body of implemented methods use File | Settings | File Templates.
}
}
|
三 Mybatis 配置
1
2
3
|
<
properties
>
<
property
name
=
"dialect"
value
=
"mysql"
/>
</
properties
>
|
1
2
3
|
<
plugins
>
<
plugin
interceptor
=
"mybatis.pagination.interceptor.PaginationInterceptor"
/>
</
plugins
>
|
四 pom.xml
1
2
3
4
5
|
<
dependency
>
<
groupId
>org.mybatis</
groupId
>
<
artifactId
>mybatis</
artifactId
>
<
version
>3.1.1</
version
>
</
dependency
>
|
本文转自 antlove 51CTO博客,原文链接:http://blog.51cto.com/antlove/1641681