repository package : 실제로 DB에 접근하는 Persistence Layer
Service와 DB를 연결하는 고리의 역할을 한다.
SQL 문을 사용하여 DB에 접근한 후 적절한 API를 제공한다.
public class UsersDAO {
public static boolean addUsers(UsersDTO user) throws SQLException{
실행 코드 ...
}
}
→ DB에서 데이터를 얻어 Service나 Controller 등으터 보낼 때 사용하는 객체를 말한다.
DB의 데이터가 Presentation Logic Tier로 넘어오면 DTO의 모습으로 오고간다.
로직을 갖고 있지 않는 순수한 데이터 객체이다.
** VO vs DTO
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UsersDTO {
private int id;
....
}
domain package - 실제 DB의 테이블과 매칭될 클래스, 최대한 외부에서 Entity 클래스의 getter method를 사용하지 않도록 해당 클래스 안에서 필요한 로직 method을 구현한다.
** Entity Class와 DTO를 분리하는 이유?
즉 DTO는 Domain Model을 복사한 형태로, 다양한 Presentation Logic을 추가한 정도로 사용하며 Domain Model 객체는 Persistent만을 위해서 사용한다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class UsersEntity {
@Id
@Column(length = 20)
private String id;
.....
}
해당 요청 url에 따라 적절한 view와 mapping 처리
적절한 ResponseEntity(DTO)를 body에 담아 Client에 반환
@WebServlet("/home")
public class HomeController extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
...
}
}
Business Logic을 처리한다.
DAO로 DB에 접근하고 DTO로 데이터를 전달받은 다음, 비지니스 로직을 처리해 적절한 데이터를 반환한다.
public class Service {
public static void notExistUser(String id) throws NotExistException, SQLException{
UsersDTO user = UsersDAO.getUser(id);
if(user == null){
throw new NotExistException("검색하신 User은 존재하지 않습니다.");
}
}
}
@Entity가 붙은 클래스는 JPA가 관리하는 것으로, 엔티티라고 불린다.
**final 클래스, enum, interface, inner class 에는 사용할 수 없음
엔티티와 매핑할 테이블을 지정, 생략 시 매핑한 엔티티 이름을 테이블 이름으로 사용
JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원
클래스의 매핑 정보와 데이터베이스 방언을 사용하여 데이터베이스 스키마 생성
애플리케이션 실행 시점에 데이터베이스 테이블을 자동으로 생성
사용
//스키마 자동 생성 기능 사용을 위해 persistence.xml에 속성 추가
<property name="hibernate.hbm2ddl.auto" value="create" />c
속성
create: 기존 테이블을 삭제하고 새로 생성(DROP + CREATE)
create-drop : CREATE 속성에 추가로 애플리케이션을 종료할 때 생성한 DDL을 제거(DROP + CREATE + DROP)
update : DB 테이블과 엔티티 매핑 정보를 비교해서 변경 사항만 수정
validate: DB 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 애플리케이션을 실행하지 않음.DDL을 수행하지 않음
none: 자동 생성 기능을 사용하지 않음
주의
개발 초기 단계는 create 또는 update
초기화 상태로 자동화된 테스트를 진행하는 개발자 환경과 CI서버는 create 또는 create-drop
테스트 서버는 update 또는 validate
스테이징과 운영 서버는 validate 또는 none
// Before
@Column(name="role_type")
private RoleType roleType;
//After
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
객체 필드를 테이블 컬럼에 매핑
@Column(nullable = false)
private String name;
@Column(unique = true)
private String joinDate;
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;
@Column(length = 400)
private Strin infor;
@Column(precision = 10, scale = 2)
private BigDecimal data;
자바의 enum 타입을 매핑할 때 사용
EnumType.STRING : enum 이름을 데이터베이스에 저장
(default. EnumType.ORDINAL)날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용
@Temporal(TemporalType.DATE) // 날짜
private Date date;
@Temporal(TemporalType.TIME) // 시간
private Date time;
@Temporal(TemporalType.TIMESTAMP) // 날짜와 시간
private Date dateAndTime;
속성
TemporalType.DATE : 날짜, 데이터베이스 data 타입과 매핑 (2020-12-18)
TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑 (23:36:33)
TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑 (2020-12-18 23:36:33) → (default. TemporalType은 필수로 지정)
@Temporal 을 생략하면 자바의 Date와 가장 유사한 timestamp로 정의
이 필드는 매핑하지 않음데이터베이스에 저장하지 않고 조회하지도 않음객체에 임시로 어떤 값을 보관하고 싶을 때 사용
Reference
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html