zhou-hao před 5 roky
rodič
revize
5262ed6b52

+ 13 - 0
hsweb-commons/hsweb-commons-crud/pom.xml

@@ -25,6 +25,12 @@
             <optional>true</optional>
         </dependency>
 
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-concurrent-cache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>io.projectreactor</groupId>
             <artifactId>reactor-core</artifactId>
@@ -78,6 +84,13 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>28.0-jre</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>io.r2dbc</groupId>
             <artifactId>r2dbc-h2</artifactId>

+ 61 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java

@@ -0,0 +1,61 @@
+package org.hswebframework.web.crud.service;
+
+import org.hswebframework.ezorm.rdb.mapping.ReactiveUpdate;
+import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
+import org.hswebframework.web.cache.ReactiveCache;
+import org.reactivestreams.Publisher;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Collection;
+
+public interface EnableCacheReactiveCrudService<E, K> extends ReactiveCrudService<E, K> {
+
+    ReactiveCache<E> getCache();
+
+    @Override
+    default Mono<E> findById(Mono<K> publisher) {
+        return publisher.flatMap(id -> {
+            return this.getCache()
+                    .mono("id:" + id)
+                    .onCacheMissResume(ReactiveCrudService.super.findById(Mono.just(id)));
+        });
+    }
+
+    @Override
+    default Mono<Integer> updateById(K id, Mono<E> entityPublisher) {
+        return ReactiveCrudService.super.updateById(id, entityPublisher)
+                .doFinally(i -> getCache().evict("id:" + id).subscribe());
+    }
+
+    @Override
+    default Mono<SaveResult> save(Publisher<E> entityPublisher) {
+        return ReactiveCrudService.super.save(entityPublisher)
+                .doFinally(i -> getCache().clear().subscribe());
+    }
+
+    @Override
+    default Mono<Integer> insert(Publisher<E> entityPublisher) {
+        return ReactiveCrudService.super.insert(entityPublisher)
+                .doFinally(i -> getCache().clear().subscribe());
+    }
+
+    @Override
+    default Mono<Integer> insertBatch(Publisher<? extends Collection<E>> entityPublisher) {
+        return ReactiveCrudService.super.insertBatch(entityPublisher)
+                .doFinally(i -> getCache().clear().subscribe());
+    }
+
+    @Override
+    default Mono<Integer> deleteById(Publisher<K> idPublisher) {
+        return Flux.from(idPublisher)
+                .doOnNext(id -> this.getCache().evict("id:" + id).subscribe())
+                .as(ReactiveCrudService.super::deleteById);
+    }
+
+    @Override
+    default ReactiveUpdate<E> createUpdate() {
+        return ReactiveCrudService.super.createUpdate()
+                .onExecute(s -> s.doFinally((__) -> getCache().clear().subscribe()));
+    }
+}

+ 41 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/GenericReactiveCacheSupportCrudService.java

@@ -0,0 +1,41 @@
+package org.hswebframework.web.crud.service;
+
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.web.cache.ReactiveCache;
+import org.hswebframework.web.cache.ReactiveCacheManager;
+import org.hswebframework.web.cache.supports.UnSupportedReactiveCache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+
+public abstract class GenericReactiveCacheSupportCrudService<E, K> implements EnableCacheReactiveCrudService<E, K> {
+
+    @Autowired
+    private ReactiveRepository<E, K> repository;
+
+    @Override
+    public ReactiveRepository<E, K> getRepository() {
+        return repository;
+    }
+
+    @Autowired(required = false)
+    private ReactiveCacheManager cacheManager;
+
+    protected ReactiveCache<E> cache;
+
+
+    @Override
+    public ReactiveCache<E> getCache() {
+        if (cache != null) {
+            return cache;
+        }
+        if (cacheManager == null) {
+            return cache = UnSupportedReactiveCache.getInstance();
+        }
+
+        return cache = cacheManager.getCache(getCacheName());
+    }
+
+    public String getCacheName() {
+        return this.getClass().getSimpleName();
+    }
+}

+ 2 - 1
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveCrudService.java

@@ -34,7 +34,8 @@ public interface ReactiveCrudService<E, K> {
 
     @Transactional(readOnly = true)
     default Mono<E> findById(Mono<K> publisher) {
-        return getRepository().findById(publisher);
+        return getRepository()
+                .findById(publisher);
     }
 
     @Transactional(readOnly = true)

+ 62 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/GenericReactiveCacheSupportCrudServiceTest.java

@@ -0,0 +1,62 @@
+package org.hswebframework.web.crud.service;
+
+import org.hswebframework.web.cache.ReactiveCacheManager;
+import org.hswebframework.web.crud.TestApplication;
+import org.hswebframework.web.crud.entity.TestEntity;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import static org.junit.Assert.*;
+
+@SpringBootTest(classes = TestApplication.class, args = "--hsweb.cache.type=guava")
+@RunWith(SpringRunner.class)
+public class GenericReactiveCacheSupportCrudServiceTest {
+
+    @Autowired
+    private TestCacheEntityService entityService;
+
+    @Test
+    public void test() {
+
+        TestEntity entity = TestEntity.of("test2",100);
+
+        entityService.insert(Mono.just(entity))
+                .as(StepVerifier::create)
+                .expectNext(1)
+                .verifyComplete();
+
+        entityService.findById(Mono.just(entity.getId()))
+                .map(TestEntity::getId)
+                .as(StepVerifier::create)
+                .expectNext(entity.getId())
+                .verifyComplete();
+
+        entityService.getCache()
+                .getMono("id:".concat(entity.getId()))
+                .map(TestEntity::getId)
+                .as(StepVerifier::create)
+                .expectNext(entity.getId())
+                .verifyComplete();
+
+        entityService.createUpdate()
+                .set("age",120)
+                .where("id",entity.getId())
+                .execute()
+                .as(StepVerifier::create)
+                .expectNext(1)
+                .verifyComplete();
+
+        entityService.getCache()
+                .getMono("id:".concat(entity.getId()))
+                .switchIfEmpty(Mono.error(NullPointerException::new))
+                .as(StepVerifier::create)
+                .expectError(NullPointerException.class)
+                .verify();
+    }
+
+}

+ 9 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/TestCacheEntityService.java

@@ -0,0 +1,9 @@
+package org.hswebframework.web.crud.service;
+
+import org.hswebframework.web.crud.entity.TestEntity;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TestCacheEntityService extends GenericReactiveCacheSupportCrudService<TestEntity,String> {
+
+}