瀏覽代碼

处理分页二级缓存.

nieqiuqiu 5 年之前
父節點
當前提交
dfab3982ff

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

@@ -16,6 +16,7 @@
 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.CachePage;
+import com.baomidou.mybatisplus.core.metadata.CachePageResult;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.cache.Cache;
 import org.apache.ibatis.cache.Cache;
 import org.apache.ibatis.cache.CacheKey;
 import org.apache.ibatis.cache.CacheKey;
@@ -116,14 +117,16 @@ public class MybatisCachingExecutor implements Executor {
                 if (result == null) {
                 if (result == null) {
                     result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                     result = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                     if (page != null) {
                     if (page != null) {
-                        page.setRecords((List<E>) result);
-                        tcm.putObject(cache, key, page);
-                        return new CachePage<>(page);
+                        List<E> records = (List<E>) result;
+                        CachePage<E> cachePage = new CachePage<>(records, page.getTotal());
+                        page.setRecords(records);
+                        tcm.putObject(cache, key, cachePage);
+                        return new CachePageResult((cachePage));
                     } else {
                     } else {
                         tcm.putObject(cache, key, result); // issue #578 and #116
                         tcm.putObject(cache, key, result); // issue #578 and #116
                     }
                     }
                 }
                 }
-                return page != null ? new CachePage<E>((IPage<E>) result) : (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);

+ 17 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/CachePage.java

@@ -17,19 +17,30 @@ package com.baomidou.mybatisplus.core.metadata;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 
-import java.util.ArrayList;
+import java.io.Serializable;
+import java.util.List;
 
 
 /**
 /**
- * @param <T>
+ * 缓存分页数据(二级缓存)
+ *
  * @author nieqiuqiu
  * @author nieqiuqiu
+ * @since 3.2.1
  */
  */
 @Data
 @Data
+@NoArgsConstructor
 @AllArgsConstructor
 @AllArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-public class CachePage<T> extends ArrayList {
+public final class CachePage<T> implements Serializable {
 
 
-    private IPage<T> page;
+    /**
+     * 记录数
+     */
+    private List<T> records;
+
+    /**
+     * 总数
+     */
+    private long total;
 
 
 }
 }

+ 37 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/CachePageResult.java

@@ -0,0 +1,37 @@
+/*
+ * 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.EqualsAndHashCode;
+
+import java.util.ArrayList;
+
+/**
+ * 受限于SqlSession#selectList(java.lang.String, java.lang.Object)
+ *
+ * @author nieqiuqiu
+ * @since 3.2.1
+ */
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public final class CachePageResult extends ArrayList {
+
+    private CachePage cachePage;
+
+}

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

@@ -16,6 +16,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.CachePage;
+import com.baomidou.mybatisplus.core.metadata.CachePageResult;
 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;
@@ -94,9 +95,12 @@ public class MybatisMapperMethod {
                         }
                         }
                         assert page != null;
                         assert page != null;
                         result = executeForIPage(sqlSession, args);
                         result = executeForIPage(sqlSession, args);
-                        if (result instanceof CachePage) {
-                            CachePage cachePage = (CachePage) result;
-                            result = cachePage.getPage();
+                        if (result instanceof CachePageResult) {
+                            CachePageResult cachePageResult = (CachePageResult) result;
+                            CachePage cachePage = cachePageResult.getCachePage();
+                            page.setRecords(cachePage.getRecords());
+                            page.setTotal(cachePage.getTotal());
+                            result = page;
                         } else {
                         } else {
                             List list = (List<Object>) result;
                             List list = (List<Object>) result;
                             result = page.setRecords(list);
                             result = page.setRecords(list);

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

@@ -0,0 +1,36 @@
+package com.baomidou.mybatisplus.test.h2;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.test.h2.cache.mapper.CacheMapper;
+import com.baomidou.mybatisplus.test.h2.cache.model.CacheModel;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(locations = {"classpath:h2/spring-cache-h2.xml"})
+class CacheTest {
+
+    @Autowired
+    private CacheMapper cacheMapper;
+
+    @Test
+    void testPageCache() {
+        IPage<CacheModel> cacheModelIPage1 = cacheMapper.selectPage(new Page<>(1, 3), new QueryWrapper<>());
+        IPage<CacheModel> cacheModelIPage2 = cacheMapper.selectPage(new Page<>(1, 3), new QueryWrapper<>());
+        Assertions.assertEquals(cacheModelIPage1.getTotal(), cacheModelIPage2.getTotal());
+        Assertions.assertEquals(cacheModelIPage1.getRecords().size(), cacheModelIPage2.getRecords().size());
+        IPage<CacheModel> cacheModelIPage3 = cacheMapper.selectPage(new Page<>(2, 3), new QueryWrapper<>());
+        Assertions.assertEquals(cacheModelIPage1.getTotal(), cacheModelIPage3.getTotal());
+        Assertions.assertEquals(cacheModelIPage3.getRecords().size(), 2);
+    }
+
+}

+ 1 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2KeyGeneratorTest.java

@@ -19,7 +19,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 @ExtendWith(SpringExtension.class)
 @ExtendWith(SpringExtension.class)
-@ContextConfiguration(locations = {"classpath:h2/spring-keygenerator-test-h2.xml"})
+@ContextConfiguration(locations = {"classpath:h2/spring-keygenerator-h2.xml"})
 class H2KeyGeneratorTest {
 class H2KeyGeneratorTest {
 
 
     @Autowired
     @Autowired

+ 51 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/CacheConfig.java

@@ -0,0 +1,51 @@
+/*
+ * 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.test.h2.cache;
+
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.type.EnumOrdinalTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+@Configuration
+@MapperScan("com.baomidou.mybatisplus.test.h2.cache.mapper")
+public class CacheConfig {
+
+    @Bean("mybatisSqlSession")
+    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
+        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
+        sqlSessionFactory.setDataSource(dataSource);
+        MybatisConfiguration configuration = new MybatisConfiguration();
+        configuration.setJdbcTypeForNull(JdbcType.NULL);
+        configuration.setMapUnderscoreToCamelCase(true);
+        configuration.setDefaultExecutorType(ExecutorType.REUSE);
+        configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
+        configuration.setCacheEnabled(true);
+        sqlSessionFactory.setConfiguration(configuration);
+        PaginationInterceptor pagination = new PaginationInterceptor();
+        sqlSessionFactory.setPlugins(pagination);
+        return sqlSessionFactory.getObject();
+    }
+
+}

+ 25 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/mapper/CacheMapper.java

@@ -0,0 +1,25 @@
+/*
+ * 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.test.h2.cache.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.h2.cache.model.CacheModel;
+import org.apache.ibatis.annotations.CacheNamespace;
+
+@CacheNamespace
+public interface CacheMapper extends BaseMapper<CacheModel> {
+
+}

+ 31 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/model/CacheModel.java

@@ -0,0 +1,31 @@
+/*
+ * 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.test.h2.cache.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@TableName(value = "cache")
+public class CacheModel implements Serializable {
+
+    private Long id;
+
+    private String name;
+
+}

+ 10 - 0
mybatis-plus/src/test/resources/cache/init.ddl.sql

@@ -0,0 +1,10 @@
+CREATE TABLE IF NOT EXISTS  cache (
+	id BIGINT(20) NOT NULL,
+	name VARCHAR(30) NULL DEFAULT NULL ,
+	PRIMARY KEY (id)
+);
+insert into cache values (1,'a');
+insert into cache values (2,'b');
+insert into cache values (3,'c');
+insert into cache values (4,'d');
+insert into cache values (5,'e');

+ 15 - 0
mybatis-plus/src/test/resources/h2/spring-cache-h2.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+    <context:component-scan base-package="com.baomidou.mybatisplus.test.h2.cache"/>
+
+    <bean class="com.baomidou.mybatisplus.test.h2.cache.CacheConfig"/>
+
+    <bean class="com.baomidou.mybatisplus.test.h2.config.DBConfig">
+        <property name="locationPattern" value="classpath:/cache/*.sql"/>
+    </bean>
+</beans>

+ 0 - 0
mybatis-plus/src/test/resources/h2/spring-keygenerator-test-h2.xml → mybatis-plus/src/test/resources/h2/spring-keygenerator-h2.xml