浏览代码

修复批量操作未清空二级缓存.

https://github.com/baomidou/mybatis-plus/issues/1781
聂秋秋 5 年之前
父节点
当前提交
f97407c19f

+ 14 - 4
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

@@ -17,6 +17,7 @@ package com.baomidou.mybatisplus.extension.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.enums.SqlMethod;
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
@@ -27,6 +28,7 @@ import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
 import org.apache.ibatis.binding.MapperMethod;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
+import org.apache.ibatis.reflection.ExceptionUtil;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -313,11 +315,19 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         Class<T> tClass = currentModelClass();
         SqlHelper.clearCache(tClass);
         SqlSessionFactory sqlSessionFactory = SqlHelper.sqlSessionFactory(tClass);
-        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
+        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
+        try {
             fun.accept(sqlSession);
-        } catch (RuntimeException ex) {
-            MyBatisExceptionTranslator myBatisExceptionTranslator = new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true);
-            throw Objects.requireNonNull(myBatisExceptionTranslator.translateExceptionIfPossible(ex));
+            sqlSession.commit();
+        } catch (Throwable t) {
+            sqlSession.rollback();
+            Throwable unwrapped = ExceptionUtil.unwrapThrowable(t);
+            if (unwrapped instanceof RuntimeException) {
+                MyBatisExceptionTranslator myBatisExceptionTranslator
+                    = new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true);
+                throw Objects.requireNonNull(myBatisExceptionTranslator.translateExceptionIfPossible((RuntimeException) unwrapped));
+            }
+            throw new MybatisPlusException(unwrapped);
         }
     }
 }

+ 25 - 14
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/CacheTest.java → mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/CacheTest.java

@@ -1,10 +1,10 @@
-package com.baomidou.mybatisplus.test.h2;
+package com.baomidou.mybatisplus.test.h2.cache;
 
 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 com.baomidou.mybatisplus.test.h2.cache.service.ICacheService;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.MethodOrderer;
 import org.junit.jupiter.api.Test;
@@ -14,47 +14,58 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
+import java.util.Collections;
+
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 @ExtendWith(SpringExtension.class)
 @ContextConfiguration(locations = {"classpath:h2/spring-cache-h2.xml"})
 class CacheTest {
 
     @Autowired
-    private CacheMapper cacheMapper;
+    private ICacheService cacheService;
 
     @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<>());
+        IPage<CacheModel> cacheModelIPage1 = cacheService.page(new Page<>(1, 3), new QueryWrapper<>());
+        IPage<CacheModel> cacheModelIPage2 = cacheService.page(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<>());
+        IPage<CacheModel> cacheModelIPage3 = cacheService.page(new Page<>(2, 3), new QueryWrapper<>());
         Assertions.assertEquals(cacheModelIPage1.getTotal(), cacheModelIPage3.getTotal());
         Assertions.assertEquals(cacheModelIPage3.getRecords().size(), 2);
-        IPage<CacheModel> cacheModelIPage4 = cacheMapper.selectPage(new Page<>(2, 3, false), new QueryWrapper<>());
+        IPage<CacheModel> cacheModelIPage4 = cacheService.page(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<>());
+        IPage<CacheModel> cacheModelIPage5 = cacheService.page(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));
+        IPage<CacheModel> cacheModelIPage6 = cacheService.page(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));
+        IPage<CacheModel> cacheModelIPage7 = cacheService.page(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));
+        IPage<CacheModel> cacheModelIPage8 = cacheService.page(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));
+        cacheModelIPage8 = cacheService.page(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));
+        IPage<CacheModel> cacheModelIPage9 = cacheService.page(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));
+        cacheModelIPage9 = cacheService.page(new Page<>(1, 3, true), new QueryWrapper<CacheModel>().ge("id", 3L));
         Assertions.assertEquals(cacheModelIPage9.getTotal(), 3L);
         Assertions.assertEquals(cacheModelIPage9.getRecords().size(), 3);
     }
 
+    @Test
+    void testCleanBatchCache() {
+        CacheModel model = new CacheModel("靓仔");
+        cacheService.save(model);
+        cacheService.getById(model.getId());
+        cacheService.updateBatchById(Collections.singletonList(new CacheModel(model.getId(), "旺仔")));
+        Assertions.assertEquals(cacheService.getById(model.getId()).getName(),"旺仔");
+    }
+
 }

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

@@ -16,11 +16,15 @@
 package com.baomidou.mybatisplus.test.h2.cache.model;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 @TableName(value = "cache")
 public class CacheModel implements Serializable {
 
@@ -28,4 +32,7 @@ public class CacheModel implements Serializable {
 
     private String name;
 
+    public CacheModel(String name) {
+        this.name = name;
+    }
 }

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/service/ICacheService.java

@@ -0,0 +1,8 @@
+package com.baomidou.mybatisplus.test.h2.cache.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.test.h2.cache.model.CacheModel;
+
+public interface ICacheService extends IService<CacheModel> {
+
+}

+ 12 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/service/impl/CacheServiceImpl.java

@@ -0,0 +1,12 @@
+package com.baomidou.mybatisplus.test.h2.cache.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.test.h2.cache.mapper.CacheMapper;
+import com.baomidou.mybatisplus.test.h2.cache.model.CacheModel;
+import com.baomidou.mybatisplus.test.h2.cache.service.ICacheService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CacheServiceImpl extends ServiceImpl<CacheMapper, CacheModel> implements ICacheService {
+
+}