Persistence layer client code
✅ Diagram
✅ Product Entity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String productNumber;
@Enumerated(EnumType.STRING)
private ProductType type;
@Enumerated(EnumType.STRING)
private ProductSellingStatus sellingStatus;
private String name;
private int price;
@Builder
public Product(String productNumber, ProductType type, ProductSellingStatus sellingStatus, String name, int price) {
this.productNumber = productNumber;
this.type = type;
this.sellingStatus = sellingStatus;
this.name = name;
this.price = price;
}
}
✅ Base Entity
- for documenting entity created, modified time
1
2
3
4
5
6
7
8
9
10
@MappedSuperclass
@Getter
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
private LocalDateTime createdDateTime;
@LastModifiedDate
private LocalDateTime modifiedDateTime;
}
✅ Controller
1
2
3
4
5
6
7
8
9
10
@RequiredArgsConstructor
@RestController
public class ProductController {
private final ProductService productService;
@GetMapping("api/v1/products/selling")
public List<ProductResponse> getSellingProducts(){
return productService.getSellingProducts();
}
}
✅ Service
1
2
3
4
5
6
7
8
9
10
11
12
13
@RequiredArgsConstructor
@Service
public class ProductService {
private final ProductRepository productRepository;
public List<ProductResponse> getSellingProducts(){
List<Product> products = productRepository.findAllBySellingStatusIn(ProductSellingStatus.forDisplay());
return products.stream()
.map(ProductResponse::of)
.collect(Collectors.toList());
}
}
✅ DTO ProductResponse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Getter
public class ProductResponse {
private Long id;
private String productNumber;
private ProductType type;
private ProductSellingStatus sellingStatus;
private String name;
private int price;
@Builder
private ProductResponse(Long id, String productNumber, ProductType type, ProductSellingStatus sellingStatus, String name, int price) {
this.id = id;
this.productNumber = productNumber;
this.type = type;
this.sellingStatus = sellingStatus;
this.name = name;
this.price = price;
}
public static ProductResponse of(Product product) {
return ProductResponse.builder()
.id(product.getId())
.productNumber(product.getProductNumber())
.type(product.getType())
.sellingStatus(product.getSellingStatus())
.name(product.getName())
.price(product.getPrice())
.build();
}
}
✅ Repository
1
2
3
4
5
6
7
8
9
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
/**
* select *
* from product
* where selling_status IN ('SELLING', 'HOLD');
*/
List<Product> findAllBySellingStatusIn(List<ProductSellingStatus> sellingStatuses);
}
✅ data.sql
1
2
3
4
insert into product(product_number, type, selling_status, name, price)
values ('001', 'HANDMADE', 'SELLING', 'americano', 4000),
('002', 'HANDMADE', 'HOLD', 'latte', 4500),
('003', 'BAKERY', 'STOP_SELLING', 'croissant', 3500);
✅ application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
spring:
profiles:
default: local
datasource:
url: jdbc:h2:mem:~/cafeKioskApplication
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: none
---
spring:
config:
activate:
on-profile: local
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true
defer-datasource-initialization: true # (2.5~) Hibernate ??? ?? data.sql ??
h2:
console:
enabled: true
---
spring:
config:
activate:
on-profile: test
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true
sql:
init:
mode: never # do not want to use data.sql for testing
✅
1
This post is licensed under CC BY 4.0 by the author.