Skip to content

Commit dce604d

Browse files
author
Frank
committed
studying ssm
1 parent ccadfba commit dce604d

6 files changed

Lines changed: 251 additions & 29 deletions

File tree

simple-spring-memcached/src/main/java/sample/di/business/domain/Product.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ public int getPrice() {
2222
return price;
2323
}
2424

25+
public void setName(String name) {
26+
this.name = name;
27+
}
28+
29+
public void setPrice(int price) {
30+
this.price = price;
31+
}
32+
2533
@Override
2634
public String toString() {
2735
return "Product= [name=" + name + ", price=" + price + "]";

simple-spring-memcached/src/main/java/sample/di/business/service/ProductService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,15 @@ public interface ProductService {
1313

1414
void addProduct(Product product);
1515

16+
void changeProduct(String productName, int overridePrice);
17+
18+
List<Product> resetPriceForAllProducts();
19+
1620
List<Integer> getIncrementValue(List<Integer> nums, int incrementValue);
21+
22+
List<Product> updatePriceForGivenProductName(List<String> nameList, int overridePrice);
23+
24+
List<Product> getAllProductsFromMemory();
25+
26+
Product getProductFromMemory(String name);
1727
}

simple-spring-memcached/src/main/java/sample/di/business/service/ProductServiceImpl.java

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,46 @@ public int getPrice(String name) {
6464

6565
public void addProduct(Product product) {
6666
log.debug("addProduct : Product : {}", product);
67+
// 측정 시작
68+
StopWatch sw = new StopWatch();
69+
sw.start();
70+
6771
productDao.addProduct(product);
72+
73+
// 측정 종료
74+
sw.stop();
75+
76+
System.out.format("Seconds=%1$s, value=%2$s%n",
77+
sw.getTotalTimeSeconds(), product);
78+
}
79+
80+
public void changeProduct(String productName, int overridePrice) {
81+
log.debug("changeProduct : productName : {} : overridePrice : {}", overridePrice);
82+
// 측정 시작
83+
StopWatch sw = new StopWatch();
84+
sw.start();
85+
86+
productDao.changeProduct(productName, overridePrice);
87+
88+
// 측정 종료
89+
sw.stop();
90+
System.out.format("Seconds=%1$s, value=%2$s%n",
91+
sw.getTotalTimeSeconds(), productName);
92+
}
93+
94+
public List<Product> resetPriceForAllProducts() {
95+
log.debug("resetPriceForAllProducts");
96+
// 측정 시작
97+
StopWatch sw = new StopWatch();
98+
sw.start();
99+
100+
List<Product> value = productDao.resetPriceForAllProducts();
101+
// 측정 종료
102+
sw.stop();
103+
104+
System.out.format("Seconds=%1$s, value=%2$s%n",
105+
sw.getTotalTimeSeconds(), value);
106+
return value;
68107
}
69108

70109
@Override
@@ -74,7 +113,6 @@ public List<Integer> getIncrementValue(List<Integer> nums, int incrementValue) {
74113
StopWatch sw = new StopWatch();
75114
sw.start();
76115

77-
78116
List<Integer> value = productDao.getIncrementValue(nums, incrementValue);
79117

80118
// 측정 종료
@@ -84,4 +122,55 @@ public List<Integer> getIncrementValue(List<Integer> nums, int incrementValue) {
84122
sw.getTotalTimeSeconds(), value);
85123
return value;
86124
}
125+
126+
public List<Product> updatePriceForGivenProductName(List<String> nameList, int overridePrice) {
127+
log.debug("updatePriceForGivenProductName : nameList : {}", nameList);
128+
// 측정 시작
129+
StopWatch sw = new StopWatch();
130+
sw.start();
131+
132+
List<Product> value = productDao.updatePriceForGivenProductName(nameList, overridePrice);
133+
134+
// 측정 종료
135+
sw.stop();
136+
137+
System.out.format("Seconds=%1$s, value=%2$s%n",
138+
sw.getTotalTimeSeconds(), value);
139+
return value;
140+
}
141+
142+
@Override
143+
public List<Product> getAllProductsFromMemory() {
144+
log.debug("getAllProductsFromMemory");
145+
// 측정 시작
146+
StopWatch sw = new StopWatch();
147+
sw.start();
148+
149+
List<Product> value = productDao.getAllProductsFromMemory();
150+
151+
// 측정 종료
152+
sw.stop();
153+
154+
System.out.format("Seconds=%1$s, value=%2$s%n",
155+
sw.getTotalTimeSeconds(), value);
156+
return value;
157+
}
158+
159+
@Override
160+
public Product getProductFromMemory(String name) {
161+
log.debug("getProductFromMemory : name : {}", name);
162+
// 측정 시작
163+
StopWatch sw = new StopWatch();
164+
sw.start();
165+
166+
Product product = productDao.getProductFromMemory(name);
167+
168+
// 측정 종료
169+
sw.stop();
170+
171+
System.out.format("Seconds=%1$s, value=%2$s%n",
172+
sw.getTotalTimeSeconds(), product);
173+
174+
return product;
175+
}
87176
}

simple-spring-memcached/src/main/java/sample/di/dataaccess/ProductDao.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,15 @@ public interface ProductDao {
1313

1414
void addProduct(Product product);
1515

16+
void changeProduct(String productName, int overridePrice);
17+
18+
List<Product> resetPriceForAllProducts();
19+
1620
List<Integer> getIncrementValue(List<Integer> nums, int incrementValue);
21+
22+
List<Product> updatePriceForGivenProductName(List<String> nameList, int overridePrice);
23+
24+
List<Product> getAllProductsFromMemory();
25+
26+
Product getProductFromMemory(String name);
1727
}

simple-spring-memcached/src/main/java/sample/di/dataaccess/ProductDaoImpl.java

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package sample.di.dataaccess;
22

3-
import com.google.code.ssm.api.ParameterValueKeyProvider;
4-
import com.google.code.ssm.api.ReadThroughAssignCache;
5-
import com.google.code.ssm.api.ReadThroughMultiCache;
6-
import com.google.code.ssm.api.ReadThroughSingleCache;
3+
import com.google.code.ssm.api.*;
74
import org.springframework.stereotype.Repository;
85
import sample.di.business.domain.Product;
96

@@ -19,47 +16,87 @@ public class ProductDaoImpl implements ProductDao {
1916
// RDB의 대체
2017
private Map<String, Product> storage = new HashMap<String, Product>();
2118

22-
@ReadThroughAssignCache(namespace = "area", assignedKey="all")
19+
@ReadThroughAssignCache(namespace = "area", assignedKey = "all")
2320
public List<Product> findAllProducts() {
2421
slowly(); // 고의로 지연시킴
25-
List<Product> productList = new ArrayList<>();
26-
2722
return storage.values().stream().collect(Collectors.toList());
2823
}
2924

3025
@ReadThroughSingleCache(namespace = "area")
3126
public Product findProduct(@ParameterValueKeyProvider String name) {
32-
// public Product findProductByReadThroughSingleCache(String name) {
3327
slowly(); // 고의로 지연시킴
3428
return storage.get(name);
3529
}
3630

3731
@ReadThroughMultiCache(namespace = "area")
3832
public List<Integer> getIncrementValue(@ParameterValueKeyProvider List<Integer> nums, int incrementValue) {
33+
slowly(); // 고의로 지연시킴
3934
return nums.stream().map(x -> x + incrementValue).collect(Collectors.toList());
4035
}
4136

42-
// @ReadThroughSingleCache(namespace = "area")
37+
@ReadThroughSingleCache(namespace = "area")
4338
public int getPrice(@ParameterValueKeyProvider String name) {
4439
slowly(); // 고의로 지연시킴
4540
return storage.get(name).getPrice();
4641
}
4742

48-
/**
49-
* value : 캐싱 이름
50-
* key : 인자의 프로퍼티
51-
*
52-
* @param product
53-
* @CacheEvict : 키에 해당하는 캐시가 있으면 삭제하고 데이터를 읽어들이면 캐싱함
54-
*/
55-
//@CacheEvict(value = "product", allEntries = true) 모든 캐시 엔트리 삭제
56-
// @CacheEvict(value = "area", key = "#product.name")
57-
// @InvalidateAssignCache(namespace = "area", assignedKey = "product.name")
58-
// @UpdateAssignCache(namespace = "area")
59-
public void addProduct(Product product) {
43+
public void addProduct(@ParameterValueKeyProvider Product product) {
6044
storage.put(product.getName(), product);
6145
}
6246

47+
@ReturnDataUpdateContent
48+
@UpdateAssignCache(namespace = "area", assignedKey = "all")
49+
public List<Product> resetPriceForAllProducts() {
50+
slowly(); // 고의로 지연시킴
51+
return storage.values().stream()
52+
.map(product -> {
53+
product.setPrice(0);
54+
return product;
55+
}).collect(Collectors.toList());
56+
}
57+
58+
@UpdateSingleCache(namespace = "area")
59+
public void changeProduct(@ParameterValueKeyProvider String productName, @ParameterDataUpdateContent int overridePrice) {
60+
slowly(); // 고의로 지연시킴
61+
Product product = storage.get(productName);
62+
product.setPrice(overridePrice);
63+
storage.replace(productName, product);
64+
}
65+
66+
@ReturnDataUpdateContent
67+
@UpdateMultiCache(namespace = "area")
68+
public List<Product> updatePriceForGivenProductName(@ParameterValueKeyProvider List<String> nameList, @ParameterDataUpdateContent int overridePrice) {
69+
slowly(); // 고의로 지연시킴
70+
List<Product> result = new ArrayList<>();
71+
Product product;
72+
73+
for (String name : nameList) {
74+
product = storage.get(name);
75+
product.setPrice(overridePrice);
76+
result.add(product);
77+
}
78+
79+
return result;
80+
}
81+
82+
@InvalidateAssignCache(namespace = "area", assignedKey = "all")
83+
public List<Product> getAllProductsFromMemory() {
84+
slowly(); // 고의로 지연시킴
85+
return storage.values().stream().collect(Collectors.toList());
86+
}
87+
88+
@InvalidateSingleCache(namespace = "area")
89+
public Product getProductFromMemory(@ParameterValueKeyProvider String name) {
90+
slowly(); // 고의로 지연시킴
91+
return storage.get(name);
92+
}
93+
94+
// @InvalidateMultiCache(namespace = "area")
95+
// public List<Integer> getIncrementValue(@ParameterValueKeyProvider List<Integer> nums, int incrementValue) {
96+
// slowly(); // 고의로 지연시킴
97+
// return nums.stream().map(x -> x + incrementValue).collect(Collectors.toList());
98+
// }
99+
63100
private void slowly() {
64101
try {
65102
Thread.sleep(3000L);

simple-spring-memcached/src/test/java/sample/di/business/service/ProductServiceImplTest.java

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package sample.di.business.service;
22

3+
import lombok.extern.slf4j.Slf4j;
34
import net.rubyeye.xmemcached.exception.MemcachedException;
45
import org.junit.Test;
56
import org.junit.runner.RunWith;
@@ -16,6 +17,7 @@
1617

1718
import static org.junit.Assert.*;
1819

20+
@Slf4j
1921
@RunWith(SpringJUnit4ClassRunner.class)
2022
@ContextConfiguration(locations = "classpath:applicationContext-cache.xml")
2123
public class ProductServiceImplTest {
@@ -29,6 +31,27 @@ public void getPrice() {
2931
assertEquals(100, productService.getPrice("microsoft"));
3032
}
3133

34+
@Test
35+
public void updatePriceForGivenProductName() {
36+
productService.addProduct(new Product("microsoft1", 100));
37+
productService.addProduct(new Product("microsoft2", 100));
38+
productService.addProduct(new Product("microsoft3", 100));
39+
List<String> names = new ArrayList<>(Arrays.asList("microsoft1", "microsoft3"));
40+
List<Product> result = productService.updatePriceForGivenProductName(names, 500);
41+
assertEquals(2, result.size());
42+
}
43+
44+
@Test
45+
public void resetPriceForAllProducts() {
46+
productService.addProduct(new Product("microsoft", 100));
47+
productService.addProduct(new Product("sony", 100));
48+
productService.resetPriceForAllProducts();
49+
List<Product> productList = productService.findAllProducts();
50+
for (Product product : productList) {
51+
assertEquals(0, product.getPrice());
52+
}
53+
}
54+
3255
@Test
3356
public void testReadThroughAssignCache() {
3457
this.executeWithMemcachedFlush(productService, () -> {
@@ -60,16 +83,61 @@ public void testReadThroughMultiCache() {
6083

6184
@Test
6285
public void testUpdateAssignCache() {
86+
this.executeWithMemcachedFlush(productService, () -> {
87+
productService.addProduct(new Product("microsoft", 100));
88+
productService.addProduct(new Product("sony", 100));
89+
productService.resetPriceForAllProducts();
90+
productService.resetPriceForAllProducts();
91+
});
92+
}
6393

94+
@Test
95+
public void testUpdateSingleCache() {
96+
this.executeWithMemcachedFlush(productService, () -> {
97+
Product product = new Product("microsoft", 100);
98+
productService.addProduct(product);
99+
productService.changeProduct(product.getName(), 500);
100+
productService.changeProduct(product.getName(), 1000);
101+
});
64102
}
65103

66-
// * @UpdateAssignCache
67-
//* @UpdateSingleCache
68-
//* @UpdateMultiCache
69-
// Invalidate
70-
//* @InvalidateAssignCache
71-
//* @InvalidateSingleCache
72-
//* @InvalidateMultiCache
104+
@Test
105+
public void testUpdateMultiCache() {
106+
this.executeWithMemcachedFlush(productService, () -> {
107+
productService.addProduct(new Product("microsoft1", 100));
108+
productService.addProduct(new Product("microsoft2", 100));
109+
productService.addProduct(new Product("microsoft3", 100));
110+
List<String> names = new ArrayList<>(Arrays.asList("microsoft1", "microsoft3"));
111+
productService.updatePriceForGivenProductName(names, 1000);
112+
productService.updatePriceForGivenProductName(names, 500);
113+
});
114+
}
115+
116+
@Test
117+
public void testInvalidateAssignCache() {
118+
this.executeWithMemcachedFlush(productService, () -> {
119+
productService.addProduct(new Product("microsoft", 100));
120+
productService.findAllProducts(); //cached 됨
121+
productService.getAllProductsFromMemory(); //cache에서 삭제됨
122+
});
123+
}
124+
125+
@Test
126+
public void testInvalidateSingleCache() {
127+
this.executeWithMemcachedFlush(productService, () -> {
128+
productService.addProduct(new Product("microsoft", 100));
129+
productService.findProduct("microsoft"); //cache됨
130+
productService.getProductFromMemory("microsoft"); //cache에서 삭제됨
131+
});
132+
}
133+
134+
135+
@Test
136+
public void testInvalidateMultiCache() { //todo: 여기서부터 작업하면 됨
137+
this.executeWithMemcachedFlush(productService, () -> {
138+
productService.addProduct(new Product("microsoft", 100));
139+
});
140+
}
73141

74142

75143
private void executeWithMemcachedFlush(ProductService productService, Runnable r) {

0 commit comments

Comments
 (0)