VO 객체 (Value Object)
- 특정 테이블의 한 행을 매핑하는 클래스
- 테이블을 표현하는 클래스~! (테이블 ➔ 클래스)
ORM
(클래스 ➔ 테이블)
UserVO.java
package org.scoula.jdbc_ex.domain;
// VO객체 만들기
@Data
@NoArgsConstructor // 기본 생성자
@AllArgsConstructor // 전체 생성자
public class UserVO {
// 컬럼들..~
private String id;
private String password;
private String name;
private String role;
}
DAO 클래스 (Data Access Object)
- 데이터베이스에 접근하여 실질적인 데이터베이스 연동 작업을 담당하는 클래스
- 테이블이 대한 CRUD 연산 처리
- 인터페이스 정의 후 구현 클래스 작성
- 제일 많은 시간이 걸림
UserDao.java - 인터페이스
package org.scoula.jdbc_ex.dao;
public interface UserDao {
// 회원 등록
int create(UserVO user) throws SQLException;
// 회원 목록 조회
List<UserVO> getList() throws SQLException;
// 회원 정보 조회
Optional<UserVO> get(String id) throws SQLException;
// 회원 수정
int update(UserVO user) throws SQLException;
// 회원 삭제
int delete(String id) throws SQLException;
}
UserDaoImpl.java
public class UserDaoImpl implements UserDao{
Connection conn = JDBCUtil.getConnection();
// USERS 테이블 관련 SQL 명령어
private String USER_LIST = "SELECT * FROM USERS"; // * : UserVO로 맵핑시켜야 함.~
private String USER_GET = "SELECT * FROM USERS WHERE ID = ?";
private String USER_INSERT = "INSERT INTO USERS VALUES (?, ?, ?, ?)";
private String USER_UPDATE = "UPDATE USERS SET NAME = ?, ROLE = ? WHERE ID = ?";
private String USER_DELETE = "DELETE FROM USERS WHERE ID = ?";
// 회원 등록
@Override
public int create(UserVO user) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement(USER_INSERT)) {
pstmt.setString(1, user.getId());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getName());
pstmt.setString(4, user.getRole());
return pstmt.executeUpdate();
}
}
// 목록보기, 상세보기에서 이용함~
private UserVO map(ResultSet rs) throws SQLException {
UserVO user = new UserVO();
user.setId(rs.getString("ID"));
user.setPassword(rs.getString("PASSWORD"));
user.setName(rs.getString("NAME"));
user.setRole(rs.getString("ROLE"));
return user; // VO 객체 리턴~
}
// 회원 목록 조회
@Override
public List<UserVO> getList() throws SQLException {
// 데이터가 없으면 빈 리스트라도 리턴해야 함 - Null(x) -> 후속 작업으로 루프 돌려야 해서~
List<UserVO> userList = new ArrayList<UserVO>();
Connection conn = JDBCUtil.getConnection();
try (PreparedStatement pstmt = conn.prepareStatement(USER_LIST);
ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
UserVO user = map(rs);
userList.add(user);
}
}
return userList;
}
// 회원 정보 조회
@Override
public Optional<UserVO> get(String id) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement(USER_GET)) {
pstmt.setString(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return Optional.of(map(rs)); // UserVO, Optional 데이터가 있음
}
}
}
return Optional.empty(); // if문 벗어남..~ 데이터 없다,,~ Null~
// Optional 데이터가 있는지 없는지 확신 x -> Optional.ofNullable(a);
}
// 회원 수정
@Override
public int update(UserVO user) throws SQLException {
Connection conn = JDBCUtil.getConnection();
try (PreparedStatement pstmt = conn.prepareStatement(USER_UPDATE)) {
pstmt.setString(1, user.getId());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getName());
pstmt.setString(4, user.getRole());
return pstmt.executeUpdate();
}
}
// USERS 테이블 관련 CRUD 메서드
// 회원 삭제
@Override
public int delete(String id) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement(USER_DELETE)) {
pstmt.setString(1, id);
return pstmt.executeUpdate();
}
}
}
UserDaoImplTest.java
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class UserDaoImplTest {
UserDao dao = new UserDaoImpl();
@AfterAll // 테스트가 끝날 때마다 JDBC유틸 close
static void tearDown() {
JDBCUtil.close();
}
@Test
@DisplayName("User 등록")
@Order(1)
void create() throws SQLException {
UserVO user = new UserVO("gamza", "gamza123", "감자", "ADMIN");
int count = dao.create(user);
Assertions.assertEquals(1, count);
}
@Test
@DisplayName("UserDao User 목록 추출")
@Order(2)
void getList() throws SQLException {
List<UserVO> list = dao.getList();
for (UserVO vo: list) {
System.out.println(vo);
}
}
@Test
@DisplayName("특정 User 1건 추출")
@Order(3)
void get() throws SQLException {
// orElseThrow : 데이터가 있으면 리턴, 없으면 예외 던지기
UserVO user = dao.get("gamza").orElseThrow(NoSuchFieldError::new);
// Null이 아니어야 한다~ 하지만 위에서 Null이면 이미 예외 던짐ㅋ 여기선 사실 필요 X
Assertions.assertNotNull(user);
}
@Test
@DisplayName("User 정보 수정")
@Order(4)
void update() throws SQLException {
UserVO user = dao.get("gamza").orElseThrow(NoClassDefFoundError::new);
user.setName("왕감자");
int count = dao.update(user);
Assertions.assertEquals(1, count);
}
@Test
@DisplayName("User 삭제")
@Order(5)
void delete() throws SQLException {
int count = dao.delete("gamza");
Assertions.assertEquals(1, count);
}
}