浏览代码

缓存key值生成增加isSearchCount.

nieqiuqiu 5 年之前
父节点
当前提交
27576239a7

+ 3 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/executor/AbstractBaseExecutor.java

@@ -61,11 +61,14 @@ public abstract class AbstractBaseExecutor extends BaseExecutor {
                 IPage<?> page = (IPage) optional.get().getValue();
                 offset = page.getCurrent();
                 limit = page.getSize();
+                //折磨人的小妖精,只能当缓存条件了,避免缓存错误命中.
+                cacheKey.update(page.isSearchCount());
             }
         } else if (parameterObject instanceof IPage) {
             IPage<?> page = (IPage) parameterObject;
             offset = page.getCurrent();
             limit = page.getSize();
+            cacheKey.update(page.isSearchCount());
         }
         cacheKey.update(offset);
         cacheKey.update(limit);

+ 37 - 5
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/executor/MybatisCachingExecutor.java

@@ -27,9 +27,11 @@ import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.executor.ExecutorException;
 import org.apache.ibatis.mapping.*;
 import org.apache.ibatis.reflection.MetaObject;
+import org.apache.ibatis.session.Configuration;
 import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 import org.apache.ibatis.transaction.Transaction;
+import org.apache.ibatis.type.TypeHandlerRegistry;
 
 import java.sql.SQLException;
 import java.util.List;
@@ -119,7 +121,7 @@ public class MybatisCachingExecutor implements Executor {
                         CacheKey countCacheKey = null;
                         if (page.isSearchCount()) {
                             // 这里的执行sql为原select语句,标准一点的是需要将此转换为count语句当做缓存key的,留做当优化把.
-                            countCacheKey = getCountCacheKey(ms, boundSql, parameterObject);
+                            countCacheKey = getCountCacheKey(ms, boundSql, parameterObject, RowBounds.DEFAULT);
                         }
                         // 切勿将这提取至上方,如果先查的话,需要提前将boundSql拷贝一份
                         result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
@@ -139,7 +141,7 @@ public class MybatisCachingExecutor implements Executor {
                     Long count;
                     if (page != null) {
                         if (page.isSearchCount()) {
-                            CacheKey cacheKey = getCountCacheKey(ms, boundSql, parameterObject);
+                            CacheKey cacheKey = getCountCacheKey(ms, boundSql, parameterObject, RowBounds.DEFAULT);
                             count = (Long) tcm.getObject(cache, cacheKey);
                             return new PageList((List) result, count);
                         }
@@ -165,10 +167,40 @@ public class MybatisCachingExecutor implements Executor {
             .build();
     }
 
-    private CacheKey getCountCacheKey(MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) {
-        BoundSql sourceSql = new BoundSql(mappedStatement.getConfiguration(), boundSql.getSql(), boundSql.getParameterMappings(), boundSql.getParameterObject());
+    private CacheKey getCountCacheKey(MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject, RowBounds rowBounds) {
+        Configuration configuration = mappedStatement.getConfiguration();
+//        BoundSql sourceSql = new BoundSql(mappedStatement.getConfiguration(), boundSql.getSql(), boundSql.getParameterMappings(), boundSql.getParameterObject());
         MappedStatement statement = buildCountMappedStatement(mappedStatement);
-        return createCacheKey(statement, parameterObject, RowBounds.DEFAULT, sourceSql);
+        CacheKey cacheKey = new CacheKey();
+        cacheKey.update(statement.getId());
+        cacheKey.update(rowBounds.getOffset());
+        cacheKey.update(rowBounds.getLimit());
+        cacheKey.update(boundSql.getSql());
+        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
+        TypeHandlerRegistry typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
+        // mimic DefaultParameterHandler logic
+        for (ParameterMapping parameterMapping : parameterMappings) {
+            if (parameterMapping.getMode() != ParameterMode.OUT) {
+                Object value;
+                String propertyName = parameterMapping.getProperty();
+                if (boundSql.hasAdditionalParameter(propertyName)) {
+                    value = boundSql.getAdditionalParameter(propertyName);
+                } else if (parameterObject == null) {
+                    value = null;
+                } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
+                    value = parameterObject;
+                } else {
+                    MetaObject metaObject = configuration.newMetaObject(parameterObject);
+                    value = metaObject.getValue(propertyName);
+                }
+                cacheKey.update(value);
+            }
+        }
+        if (configuration.getEnvironment() != null) {
+            // issue #176
+            cacheKey.update(configuration.getEnvironment().getId());
+        }
+        return cacheKey;
     }
 
     @Override

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

@@ -43,6 +43,18 @@ class CacheTest {
         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);
+        IPage<CacheModel> cacheModelIPage8 = cacheMapper.selectPage(new Page<>(1, 3, false), new QueryWrapper<CacheModel>().ge("id", 3L));
+        Assertions.assertEquals(cacheModelIPage8.getTotal(), 0L);
+        Assertions.assertEquals(cacheModelIPage8.getRecords().size(), 3);
+        cacheModelIPage8 = cacheMapper.selectPage(new Page<>(1, 3, false), new QueryWrapper<CacheModel>().ge("id", 3L));
+        Assertions.assertEquals(cacheModelIPage8.getTotal(), 0L);
+        Assertions.assertEquals(cacheModelIPage8.getRecords().size(), 3);
+        IPage<CacheModel> cacheModelIPage9 = cacheMapper.selectPage(new Page<>(1, 3, true), new QueryWrapper<CacheModel>().ge("id", 3L));
+        Assertions.assertEquals(cacheModelIPage9.getTotal(), 3L);
+        Assertions.assertEquals(cacheModelIPage9.getRecords().size(), 3);
+        cacheModelIPage9 = cacheMapper.selectPage(new Page<>(1, 3, true), new QueryWrapper<CacheModel>().ge("id", 3L));
+        Assertions.assertEquals(cacheModelIPage9.getTotal(), 3L);
+        Assertions.assertEquals(cacheModelIPage9.getRecords().size(), 3);
     }
 
 }