[TIL] CRUD Code Shadowing Round 1
This article summarizes the process of configuring a domain model using JPA Entity, Lombok, and Repository.
한국어 원문은 여기에서 볼 수 있습니다.
[TIL] CRUD Code Shadowing Round 1
Entity
@Entity annotation
- Indicates that this class is a class that maps to a DB table.
- JPA dependency must be added -> This class is recognized as a table through JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'(build.gradle) - JPA sees this object and performs INSERT / UPDATE / SELECT
@Getter annotation
- Automatically generate getter methods for all fields
- Available through Lombok library
@Table(name = "products")
- Specify table name directly
- By default, the class name is followed, but the DB table name can be forcefully specified through the annotation above.
@NoArgsConstructor(access = AccessLevel.PROTECTED)
- Creates a default constructor, but restricts access.
- JPA requires a default constructor when creating an object, but I use protected because I want to prevent anyone from using new Product().
- JPA can be used, but cannot be freely created externally -> It feels like a JPA-only constructor.
- Available through Lombok library
Why do you need a default constructor?
- It is absolutely necessary because JPA creates objects through ‘reflection’.
- How JPA works
1 2 3
Product p = Product.class.newInstance(); // 기본 생성자 호출 p.setName(...); p.setPrice(...);
- Feels like the above code when taking data out of DB
- JPA does not use a constructor like new Product(name, price),
- Create an empty object first -> put the value later -> Therefore, default constructor required, only public or protected
- The default constructor is the path that is called when creating an empty object
- Create an empty object with the default constructor -> Fill the fields with values
- Since the framework does not know the entire class structure, it creates a default constructor and fills it in using reflection.
@Id: PK (Primary Key) designation, representative value of the table
@GeneratedValue: Automatically generate ID
- IDENTITY STRATEGY (
strategy = GenerationType.IDENTITY)- DB automatically increases (auto increment)
- You do not need to enter the ID when inserting.
- DB automatically adds it.
constructor
1
2
3
4
public Product(String name, Integer price) {
this.name = name;
this.price = price;
}
- Create our own constructor
- The default constructor is for JPA, the above constructor is for business ex)
new Product("콜라", 2000);: Meaningful creation
update method
1
2
3
4
public void update(String name, Integer price) {
this.name = name;
this.price = price;
}
- Why not use a setter and use it like the code above?
- It is dangerous to overuse setters in JPA.
- Setter problem: Intermediate state can be broken, and only the value is changed without logic (because fields are modified one by one)
- It is dangerous to overuse setters in JPA.
- Advantages of update method: Change at once, verification logic can be added later
DTO
- DTO is used to receive data coming from client to server.
1. RequestDto
@Getter
- Automatic creation of getter -> Used because the value must be taken out from controller / service
@NoArgsConstructor
- Automatic creation of default constructor -> Required when Spring converts from JSON to object
- Like JPA, Spring also uses the method of ‘creating an empty object first and then inserting values’.
@NotBlank
- String only
- When it cannot be null, “” is not an empty string, or is not a space “ “
@NotNull
- Only nulls are prohibited
- 0 is allowed
@Min
- Minimum value limit ex)
@Min(0): means the price must be greater than 0
jakarta.validation.constraints
- Validation annotation package
- Must be imported to use
@NotBlank,@NotNull,@Min, etc. - Add
implementation 'org.springframework.boot:spring-boot-starter-validation'to build.gradle
Difference between DTO (Data Transfer Object) and Entity
- DTO: Object for moving data
- Receiving request data, sending response data, passing data between layers
- A bundle of values received as a request, rather than a true object that stores the product.
- Entity: Object directly mapped to DB table
- JPA connects and manages DB tables
-> DTO is for the outside world, Entity is for internal DB management.
2. ResponseDto
@Getter
- Automatic creation of getter -> Required when taking out response data
Why is ### field finalized?
- Once you enter the value, it can never be changed. -> To lock the response data so that it cannot be modified.
constructor
1
2
3
4
5
public ProductResponse(Product product) {
this.id = product.getId();
this.name = product.getName();
this.price = product.getPrice();
}
- Entity -> DTO conversion
- Action flow
- Remove
product.getId(),product.getName(), andproduct.getPrice()from the inside of the entity retrieved from the DB (Product product of the entity) and place them in the DTO.
- Remove
- Because the Entity should not be returned as is.
- If you return the Entity as is,
- DB structure exposed as is
- All unnecessary fields are removed.
- There is a security risk
- Difficult to change structure
- Convert to DTO -Select and send only the necessary values
- API structure can be freely designed
- Entity protected
- If you return the Entity as is,
Difference between requestDto and responseDto
-RequestDto
- Client -> Server
- For input
- With validation ex)
@NotNull - No relation to DB yet -ResponseDto
- Server -> Client
- For output
- Processed data
- Entity-based