天天看點

Mybatis 實體分頁

一 方言

1

2

3

4

5

6

7

8

<code>package</code> <code>mybatis.pagination.dialect;</code>

<code>/**</code>

<code> </code><code>* Created by Administrator on 2015/4/29.</code>

<code> </code><code>*/</code>

<code>public</code> <code>interface</code> <code>Dialect {</code>

<code>    </code><code>public</code> <code>String getLimitString(String sql, </code><code>int</code> <code>offset, </code><code>int</code> <code>limit);</code>

<code>}</code>

9

10

11

12

13

14

<code> </code> 

<code>public</code> <code>class</code> <code>MySqlDialect </code><code>implements</code> <code>Dialect{</code>

<code>    </code><code>@Override</code>

<code>    </code><code>public</code> <code>String getLimitString(String sql, </code><code>int</code> <code>offset, </code><code>int</code> <code>limit) {</code>

<code>        </code><code>String newSql = </code><code>"select * from ("</code><code>+sql+</code><code>") e limit "</code><code>+offset+</code><code>","</code><code>+limit;</code>

<code>        </code><code>return</code> <code>newSql;</code>

<code>    </code><code>}</code>

mybatis.pagination.dialect.DialectProvider.java

15

16

17

18

19

20

21

22

23

<code>public</code> <code>class</code> <code>DialectProvider {</code>

<code>    </code><code>private</code> <code>static</code> <code>DialectProvider dialectProvider = </code><code>new</code> <code>DialectProvider();</code>

<code>    </code><code>private</code> <code>DialectProvider(){}</code>

<code>    </code><code>public</code> <code>static</code> <code>DialectProvider getInstance(){</code>

<code>        </code><code>return</code> <code>dialectProvider;</code>

<code>    </code><code>public</code> <code>Dialect getDialect(String dialectName){</code>

<code>        </code><code>if</code><code>(</code><code>"mysql"</code><code>.equals(dialectName)){</code>

<code>            </code><code>return</code> <code>new</code> <code>MySqlDialect();</code>

<code>        </code><code>}</code>

<code>        </code><code>throw</code> <code>new</code> <code>RuntimeException(</code><code>"can't find the specified dialect : "</code><code>+dialectName);</code>

二 分頁攔截器 

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

<code>package</code> <code>mybatis.pagination.interceptor;</code>

<code>import</code> <code>mybatis.pagination.dialect.Dialect;</code>

<code>import</code> <code>mybatis.pagination.dialect.DialectProvider;</code>

<code>import</code> <code>org.apache.ibatis.executor.statement.StatementHandler;</code>

<code>import</code> <code>org.apache.ibatis.mapping.BoundSql;</code>

<code>import</code> <code>org.apache.ibatis.plugin.*;</code>

<code>import</code> <code>org.apache.ibatis.reflection.MetaObject;</code>

<code>import</code> <code>org.apache.ibatis.reflection.factory.DefaultObjectFactory;</code>

<code>import</code> <code>org.apache.ibatis.reflection.factory.ObjectFactory;</code>

<code>import</code> <code>org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;</code>

<code>import</code> <code>org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;</code>

<code>import</code> <code>org.apache.ibatis.session.Configuration;</code>

<code>import</code> <code>org.apache.ibatis.session.RowBounds;</code>

<code>import</code> <code>java.sql.Connection;</code>

<code>import</code> <code>java.util.Properties;</code>

<code> </code><code>* 通過攔截&lt;code&gt;StatementHandler&lt;/code&gt;的&lt;code&gt;prepare&lt;/code&gt;方法,重寫sql語句實作實體分頁。</code>

<code> </code><code>* 老規矩,簽名裡要攔截的類型隻能是接口。</code>

<code> </code><code>*</code>

<code>@Intercepts</code><code>({</code><code>@Signature</code><code>(type = StatementHandler.</code><code>class</code><code>, method = </code><code>"prepare"</code><code>, args = {Connection.</code><code>class</code><code>})})</code>

<code>public</code> <code>class</code> <code>PaginationInterceptor </code><code>implements</code> <code>Interceptor {</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>ObjectFactory DEFAULT_OBJECT_FACTORY = </code><code>new</code> <code>DefaultObjectFactory();</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = </code><code>new</code> <code>DefaultObjectWrapperFactory();</code>

<code>    </code><code>public</code> <code>Object intercept(Invocation invocation) </code><code>throws</code> <code>Throwable {</code>

<code>        </code><code>StatementHandler statementHandler = (StatementHandler) invocation.getTarget();</code>

<code>        </code><code>MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,DEFAULT_OBJECT_WRAPPER_FACTORY);</code>

<code>        </code><code>RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue(</code><code>"delegate.rowBounds"</code><code>);</code>

<code>        </code><code>// property在mybatis settings檔案内配置</code>

<code>        </code><code>Configuration configuration = (Configuration) metaStatementHandler.getValue(</code><code>"delegate.configuration"</code><code>);</code>

<code>        </code><code>// 隻重寫需要分頁的sql語句。通過MappedStatement的ID比對,預設重寫以Page結尾的MappedStatement的sql</code>

<code>        </code><code>BoundSql boundSql = (BoundSql) metaStatementHandler.getValue(</code><code>"delegate.boundSql"</code><code>);</code>

<code>        </code><code>String sql = boundSql.getSql();</code>

<code>        </code><code>// 重寫sql</code>

<code>        </code><code>Dialect dialect = getDialect(configuration);</code>

<code>        </code><code>String newSql = dialect.getLimitString(sql,rowBounds.getOffset(),rowBounds.getLimit());</code>

<code>        </code><code>metaStatementHandler.setValue(</code><code>"delegate.boundSql.sql"</code><code>, newSql);</code>

<code>        </code><code>// 采用實體分頁後,就不需要mybatis的記憶體分頁了,是以重置下面的兩個參數</code>

<code>        </code><code>metaStatementHandler.setValue(</code><code>"delegate.rowBounds.offset"</code><code>, RowBounds.NO_ROW_OFFSET);</code>

<code>        </code><code>metaStatementHandler.setValue(</code><code>"delegate.rowBounds.limit"</code><code>, RowBounds.NO_ROW_LIMIT);</code>

<code>        </code><code>// 将執行權交給下一個攔截器</code>

<code>        </code><code>return</code> <code>invocation.proceed();</code>

<code>    </code><code>private</code> <code>Dialect getDialect(Configuration configuration){</code>

<code>        </code><code>Properties properties = configuration.getVariables();</code>

<code>        </code><code>if</code><code>(properties==</code><code>null</code><code>){</code>

<code>            </code><code>properties = </code><code>new</code> <code>Properties();</code>

<code>        </code><code>String dialectName = properties.getProperty(</code><code>"dialect"</code><code>,</code><code>"mysql"</code><code>);</code>

<code>        </code><code>return</code> <code>DialectProvider.getInstance().getDialect(dialectName);</code>

<code>    </code><code>public</code> <code>Object plugin(Object target) {</code>

<code>        </code><code>// 當目标類是StatementHandler類型時,才包裝目标類,否者直接傳回目标本身,減少目标被代理的次數</code>

<code>        </code><code>if</code> <code>(target </code><code>instanceof</code> <code>StatementHandler) {</code>

<code>            </code><code>return</code> <code>Plugin.wrap(target, </code><code>this</code><code>);</code>

<code>        </code><code>} </code><code>else</code> <code>{</code>

<code>            </code><code>return</code> <code>target;</code>

<code>    </code><code>public</code> <code>void</code> <code>setProperties(Properties properties) {</code>

<code>        </code><code>//To change body of implemented methods use File | Settings | File Templates.</code>

 三 Mybatis 配置

<code>&lt;</code><code>properties</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"dialect"</code> <code>value</code><code>=</code><code>"mysql"</code><code>/&gt;</code>

<code>&lt;/</code><code>properties</code><code>&gt;</code>

<code>&lt;</code><code>plugins</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>plugin</code> <code>interceptor</code><code>=</code><code>"mybatis.pagination.interceptor.PaginationInterceptor"</code><code>/&gt;</code>

<code>&lt;/</code><code>plugins</code><code>&gt;</code>

四 pom.xml

<code>&lt;</code><code>dependency</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>groupId</code><code>&gt;org.mybatis&lt;/</code><code>groupId</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>artifactId</code><code>&gt;mybatis&lt;/</code><code>artifactId</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>version</code><code>&gt;3.1.1&lt;/</code><code>version</code><code>&gt;</code>

<code>&lt;/</code><code>dependency</code><code>&gt;</code>

 本文轉自 antlove 51CTO部落格,原文連結:http://blog.51cto.com/antlove/1641681