Sfoglia il codice sorgente

分页二级缓存支持.

nieqiuqiu 5 anni fa
parent
commit
03959cd84a

+ 34 - 7
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/executor/MybatisCachingExecutor.java

@@ -15,9 +15,9 @@
  */
  */
 package com.baomidou.mybatisplus.core.executor;
 package com.baomidou.mybatisplus.core.executor;
 
 
-import com.baomidou.mybatisplus.core.metadata.CachePage;
-import com.baomidou.mybatisplus.core.metadata.CachePageResult;
+import com.baomidou.mybatisplus.core.metadata.PageList;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import org.apache.ibatis.cache.Cache;
 import org.apache.ibatis.cache.Cache;
 import org.apache.ibatis.cache.CacheKey;
 import org.apache.ibatis.cache.CacheKey;
 import org.apache.ibatis.cache.TransactionalCacheManager;
 import org.apache.ibatis.cache.TransactionalCacheManager;
@@ -115,23 +115,50 @@ public class MybatisCachingExecutor implements Executor {
                 ensureNoOutParams(ms, boundSql);
                 ensureNoOutParams(ms, boundSql);
                 Object result = tcm.getObject(cache, key);
                 Object result = tcm.getObject(cache, key);
                 if (result == null) {
                 if (result == null) {
-                    result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                     if (page != null) {
                     if (page != null) {
+                        CacheKey countCacheKey = null;
+                        if (page.isSearchCount()) {
+                            // 这里的执行sql为原select语句,标准一点的是需要将此转换为count语句当做缓存key的,留做当优化把.
+                            countCacheKey = buildCountCacheKey(ms, boundSql, parameterObject);
+                        }
+                        // 切勿将这提取至上方,如果先查的话,需要提前将boundSql拷贝一份
+                        result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                         List<E> records = (List<E>) result;
                         List<E> records = (List<E>) result;
-                        CachePage<E> cachePage = new CachePage<>(records, page.getTotal());
                         page.setRecords(records);
                         page.setRecords(records);
-                        tcm.putObject(cache, key, cachePage);
-                        return new CachePageResult((cachePage));
+                        tcm.putObject(cache, key, records);
+                        if (countCacheKey != null) {
+                            tcm.putObject(cache, countCacheKey, page.getTotal());
+                        }
+                        return new PageList(records, page.getTotal());
                     } else {
                     } else {
+                        result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                         tcm.putObject(cache, key, result); // issue #578 and #116
                         tcm.putObject(cache, key, result); // issue #578 and #116
+                        return (List<E>) result;
+                    }
+                } else {
+                    Long count;
+                    if (page != null) {
+                        if (page.isSearchCount()) {
+                            CacheKey cacheKey = buildCountCacheKey(ms, boundSql, parameterObject);
+                            count = (Long) tcm.getObject(cache, cacheKey);
+                            return new PageList((List) result, count);
+                        }
+                        return new PageList((List) result, 0L);
+                    } else {
+                        return (List<E>) result;
                     }
                     }
                 }
                 }
-                return page != null ? new CachePageResult((CachePage) result) : (List<E>) result;
             }
             }
         }
         }
         return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
         return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
     }
     }
 
 
+    private CacheKey buildCountCacheKey(MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) {
+        BoundSql sourceSql = new BoundSql(mappedStatement.getConfiguration(), boundSql.getSql(), boundSql.getParameterMappings(), boundSql.getParameterObject());
+        MappedStatement build = new MappedStatement.Builder(mappedStatement.getConfiguration(), mappedStatement.getId() + StringPool.DOT + "count", mappedStatement.getSqlSource(), mappedStatement.getSqlCommandType()).build();
+        return createCacheKey(build, parameterObject, RowBounds.DEFAULT, sourceSql);
+    }
+
     @Override
     @Override
     public List<BatchResult> flushStatements() throws SQLException {
     public List<BatchResult> flushStatements() throws SQLException {
         return delegate.flushStatements();
         return delegate.flushStatements();

+ 0 - 46
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/CachePage.java

@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
- * <p>
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * <p>
- * https://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.baomidou.mybatisplus.core.metadata;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 缓存分页数据(二级缓存)
- *
- * @author nieqiuqiu
- * @since 3.2.1
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public final class CachePage<T> implements Serializable {
-
-    /**
-     * 记录数
-     */
-    private List<T> records;
-
-    /**
-     * 总数
-     */
-    private long total;
-
-}

+ 11 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/CachePageResult.java → mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/PageList.java

@@ -20,6 +20,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.EqualsAndHashCode;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.List;
 
 
 /**
 /**
  * 受限于SqlSession#selectList(java.lang.String, java.lang.Object)
  * 受限于SqlSession#selectList(java.lang.String, java.lang.Object)
@@ -30,8 +31,16 @@ import java.util.ArrayList;
 @Data
 @Data
 @AllArgsConstructor
 @AllArgsConstructor
 @EqualsAndHashCode(callSuper = true)
 @EqualsAndHashCode(callSuper = true)
-public final class CachePageResult extends ArrayList {
+public final class PageList<T> extends ArrayList<T> {
 
 
-    private CachePage cachePage;
+    /**
+     * 记录数
+     */
+    private List<T> records;
+
+    /**
+     * 总数
+     */
+    private long total;
 
 
 }
 }

+ 5 - 7
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperMethod.java

@@ -15,8 +15,7 @@
  */
  */
 package com.baomidou.mybatisplus.core.override;
 package com.baomidou.mybatisplus.core.override;
 
 
-import com.baomidou.mybatisplus.core.metadata.CachePage;
-import com.baomidou.mybatisplus.core.metadata.CachePageResult;
+import com.baomidou.mybatisplus.core.metadata.PageList;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.binding.BindingException;
 import org.apache.ibatis.binding.BindingException;
 import org.apache.ibatis.binding.MapperMethod;
 import org.apache.ibatis.binding.MapperMethod;
@@ -95,11 +94,10 @@ public class MybatisMapperMethod {
                         }
                         }
                         assert page != null;
                         assert page != null;
                         result = executeForIPage(sqlSession, args);
                         result = executeForIPage(sqlSession, args);
-                        if (result instanceof CachePageResult) {
-                            CachePageResult cachePageResult = (CachePageResult) result;
-                            CachePage cachePage = cachePageResult.getCachePage();
-                            page.setRecords(cachePage.getRecords());
-                            page.setTotal(cachePage.getTotal());
+                        if (result instanceof PageList) {
+                            PageList pageList = (PageList) result;
+                            page.setRecords(pageList.getRecords());
+                            page.setTotal(pageList.getTotal());
                             result = page;
                             result = page;
                         } else {
                         } else {
                             List list = (List<Object>) result;
                             List list = (List<Object>) result;

+ 12 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/CacheTest.java

@@ -31,6 +31,18 @@ class CacheTest {
         IPage<CacheModel> cacheModelIPage3 = cacheMapper.selectPage(new Page<>(2, 3), new QueryWrapper<>());
         IPage<CacheModel> cacheModelIPage3 = cacheMapper.selectPage(new Page<>(2, 3), new QueryWrapper<>());
         Assertions.assertEquals(cacheModelIPage1.getTotal(), cacheModelIPage3.getTotal());
         Assertions.assertEquals(cacheModelIPage1.getTotal(), cacheModelIPage3.getTotal());
         Assertions.assertEquals(cacheModelIPage3.getRecords().size(), 2);
         Assertions.assertEquals(cacheModelIPage3.getRecords().size(), 2);
+        IPage<CacheModel> cacheModelIPage4 = cacheMapper.selectPage(new Page<>(2, 3, false), new QueryWrapper<>());
+        Assertions.assertEquals(cacheModelIPage4.getTotal(), 0L);
+        Assertions.assertEquals(cacheModelIPage4.getRecords().size(), 2);
+        IPage<CacheModel> cacheModelIPage5 = cacheMapper.selectPage(new Page<>(2, 3, true), new QueryWrapper<>());
+        Assertions.assertEquals(cacheModelIPage5.getTotal(), cacheModelIPage3.getTotal());
+        Assertions.assertEquals(cacheModelIPage5.getRecords().size(), 2);
+        IPage<CacheModel> cacheModelIPage6 = cacheMapper.selectPage(new Page<>(1, 3, true), new QueryWrapper<CacheModel>().ge("id", 2L));
+        Assertions.assertEquals(cacheModelIPage6.getTotal(), 4);
+        Assertions.assertEquals(cacheModelIPage6.getRecords().size(), 3);
+        IPage<CacheModel> cacheModelIPage7 = cacheMapper.selectPage(new Page<>(1, 3, false), new QueryWrapper<CacheModel>().ge("id", 2L));
+        Assertions.assertEquals(cacheModelIPage7.getTotal(), 0L);
+        Assertions.assertEquals(cacheModelIPage7.getRecords().size(), 3);
     }
     }
 
 
 }
 }