Skip to content

Commit 5ce03e8

Browse files
Adding Spring Boot cache implementation
1 parent e21d171 commit 5ce03e8

File tree

9 files changed

+283
-9
lines changed

9 files changed

+283
-9
lines changed

.gitignore

+5-9
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44
# Log file
55
*.log
66

7-
# BlueJ files
8-
*.ctxt
9-
10-
# Mobile Tools for Java (J2ME)
11-
.mtj.tmp/
12-
137
# Package Files #
148
*.jar
159
*.war
@@ -19,6 +13,8 @@
1913
*.tar.gz
2014
*.rar
2115

22-
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23-
hs_err_pid*
24-
replay_pid*
16+
# Generated Sources
17+
target
18+
19+
# IDE Files
20+
.idea

pom.xml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>3.1.2</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
12+
<groupId>com.bootcamptoprod</groupId>
13+
<artifactId>spring-boot-cache-management</artifactId>
14+
<version>0.0.1-SNAPSHOT</version>
15+
16+
<name>spring-boot-cache-management</name>
17+
<description>A simple Spring Boot app showcasing how we can create our own endpoints to manage the cache</description>
18+
19+
<properties>
20+
<java.version>17</java.version>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-actuator</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-cache</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-web</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-data-jpa</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>com.h2database</groupId>
42+
<artifactId>h2</artifactId>
43+
<scope>runtime</scope>
44+
</dependency>
45+
46+
<dependency>
47+
<groupId>org.springframework.boot</groupId>
48+
<artifactId>spring-boot-starter-test</artifactId>
49+
<scope>test</scope>
50+
</dependency>
51+
</dependencies>
52+
53+
<build>
54+
<plugins>
55+
<plugin>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-maven-plugin</artifactId>
58+
</plugin>
59+
</plugins>
60+
</build>
61+
62+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.bootcamptoprod.cache.management.Entity;
2+
3+
import jakarta.persistence.*;
4+
5+
@Entity
6+
@Table(name = "Product")
7+
public class Product {
8+
@Id
9+
@GeneratedValue(strategy = GenerationType.IDENTITY)
10+
private Long id;
11+
private String name;
12+
private double price;
13+
private boolean available;
14+
15+
public Product() {
16+
}
17+
18+
public Long getId() {
19+
return id;
20+
}
21+
22+
public void setId(Long id) {
23+
this.id = id;
24+
}
25+
26+
public String getName() {
27+
return name;
28+
}
29+
30+
public void setName(String name) {
31+
this.name = name;
32+
}
33+
34+
public double getPrice() {
35+
return price;
36+
}
37+
38+
public void setPrice(double price) {
39+
this.price = price;
40+
}
41+
42+
public boolean isAvailable() {
43+
return available;
44+
}
45+
46+
public void setAvailable(boolean available) {
47+
this.available = available;
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.bootcamptoprod.cache.management;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.cache.annotation.EnableCaching;
6+
import org.springframework.scheduling.annotation.EnableScheduling;
7+
8+
@SpringBootApplication
9+
@EnableCaching
10+
@EnableScheduling
11+
public class SpringBootCacheManagementApplication {
12+
13+
public static void main(String[] args) {
14+
SpringApplication.run(SpringBootCacheManagementApplication.class, args);
15+
}
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.bootcamptoprod.cache.management.controller;
2+
3+
import com.bootcamptoprod.cache.management.Entity.Product;
4+
import com.bootcamptoprod.cache.management.service.ProductService;
5+
import org.springframework.web.bind.annotation.*;
6+
7+
import java.util.List;
8+
9+
@RestController
10+
@RequestMapping("/api/products")
11+
public class ProductController {
12+
13+
private final ProductService productService;
14+
15+
public ProductController(ProductService productService) {
16+
this.productService = productService;
17+
}
18+
19+
@GetMapping
20+
public List<Product> getAllProducts() {
21+
return productService.getAllProducts();
22+
}
23+
24+
@GetMapping("/{productId}")
25+
public Product getProductById(@PathVariable long productId) {
26+
return productService.getProductById(productId);
27+
}
28+
29+
@PostMapping
30+
public Product addProduct(@RequestBody Product product) {
31+
return productService.updateProduct(product);
32+
}
33+
34+
@PutMapping("/{productId}")
35+
public Product updateProduct(@PathVariable long productId, @RequestBody Product product) {
36+
product.setId(productId);
37+
return productService.updateProduct(product);
38+
}
39+
40+
@DeleteMapping("/{productId}")
41+
public void deleteProduct(@PathVariable long productId) {
42+
productService.deleteProduct(productId);
43+
}
44+
45+
@GetMapping("/details/{productId}")
46+
public Product getProductDetails(@PathVariable long productId) {
47+
Product product = new Product();
48+
product.setId(productId);
49+
return productService.getProductDetails(product);
50+
}
51+
52+
@GetMapping("/price-check")
53+
public Product getProductWithPriceCheck(@RequestParam long productId) {
54+
return productService.getProductWithPriceCheck(productId);
55+
}
56+
57+
@PostMapping("/clear-cache")
58+
public void clearProductCache() {
59+
productService.clearProductCache();
60+
}
61+
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.bootcamptoprod.cache.management.repository;
2+
3+
4+
import com.bootcamptoprod.cache.management.Entity.Product;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
public interface ProductRepository extends JpaRepository<Product, Long> {
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.bootcamptoprod.cache.management.service;
2+
3+
import com.bootcamptoprod.cache.management.Entity.Product;
4+
import com.bootcamptoprod.cache.management.repository.ProductRepository;
5+
import org.springframework.cache.annotation.CacheEvict;
6+
import org.springframework.cache.annotation.CachePut;
7+
import org.springframework.cache.annotation.Cacheable;
8+
import org.springframework.cache.annotation.Caching;
9+
import org.springframework.scheduling.annotation.Scheduled;
10+
import org.springframework.stereotype.Service;
11+
12+
import java.util.List;
13+
14+
@Service
15+
public class ProductService {
16+
17+
public static final String PRODUCTS_CACHE_KEY = "products";
18+
19+
private final ProductRepository productRepository;
20+
21+
public ProductService(ProductRepository productRepository) {
22+
this.productRepository = productRepository;
23+
}
24+
25+
@Cacheable(value = "products", key = "#root.target.PRODUCTS_CACHE_KEY")
26+
public List<Product> getAllProducts() {
27+
return productRepository.findAll();
28+
}
29+
30+
@Cacheable(value = "products", key = "#productId", condition = "#productId > 0")
31+
public Product getProductById(long productId) {
32+
return productRepository.findById(productId).orElse(null);
33+
}
34+
35+
@CachePut(value = "products", key = "#product.id")
36+
public Product updateProduct(Product product) {
37+
Product updatedProduct = productRepository.save(product);
38+
return updatedProduct;
39+
}
40+
41+
@CacheEvict(value = "products", key = "#productId")
42+
public void deleteProduct(long productId) {
43+
productRepository.deleteById(productId);
44+
}
45+
46+
@Caching(
47+
cacheable = {@Cacheable(value = "products", key = "#product.id")},
48+
evict = {@CacheEvict(value = "recentProducts", allEntries = true)}
49+
)
50+
public Product getProductDetails(Product product) {
51+
// Logic to fetch detailed product information
52+
return productRepository.findById(product.getId()).orElse(null);
53+
}
54+
55+
@Cacheable(value = "products", key = "#productId", unless = "#result.price < 100")
56+
public Product getProductWithPriceCheck(long productId) {
57+
return productRepository.findById(productId).orElse(null);
58+
}
59+
60+
@CacheEvict(value = "products", allEntries = true)
61+
public void clearProductCache() {
62+
System.out.println("Product cache was cleared successfully");
63+
}
64+
65+
@CacheEvict(value = "products", allEntries = true)
66+
@Scheduled(fixedRateString = "43200000")
67+
public void clearProductsCache() {
68+
System.out.println("Clearing products cache");
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
management.endpoints.web.exposure.include=*
2+
logging.level.org.springframework.cache=TRACE
3+
spring.jpa.defer-datasource-initialization=true
4+
spring.cache.cache-names=products

src/main/resources/data.sql

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
INSERT INTO product (name, price, available) VALUES ('Product A', 150.0, true);
2+
INSERT INTO product (name, price, available) VALUES ('Product B', 200.0, true);
3+
INSERT INTO product (name, price, available) VALUES ('Product C', 80.0, false);
4+
INSERT INTO product (name, price, available) VALUES ('Product D', 70.0, false);
5+
INSERT INTO product (name, price, available) VALUES ('Product E', 54.0, true);
6+
INSERT INTO product (name, price, available) VALUES ('Product F', 68.0, true);

0 commit comments

Comments
 (0)