25.03.19 (수) 27일차 JDBC

허배령·2025년 3월 19일

괴발개발 TIL

목록 보기
33/54

Run 클래스

package edu.kh.jdbc.run;

import edu.kh.jdbc.view.UserView;

public class Run {

	public static void main(String[] args) {

		UserView view = new UserView();
		view.test();
	}
}

User 클래스

package edu.kh.jdbc.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

// DTO (Data Transfer Object - 데이터 전송 객체)
// : 값을 묶어서 전달하는 용도의 객체

// -> DB에 데이터를 묶어서 전달하거나,
//	DB에서 조회한 결과를 가져올 때 사용 (데이터 교환을 위한 객체)

// == DB 특정 테이블의 한 행의 데이터를 
// 저장할 수 있는 형태로 class 작성

// lombok : 자바 코드에서 반복적으로 작성해야 하는 코드(보일러플레이트코드)를
//			자동으로 완성해주는 라이브러리
@Getter
@Setter
@NoArgsConstructor	// 기본 생성자
@AllArgsConstructor // 모든필드 초기화용 매개변수 생성자
@ToString
public class User {
	private int userNo; // DB에선 언더바, JAVA에선 카멜케이스
	private String userId;
	private String userPw;
	private String userName;
	private String enrollDate;
// -> enrollDate를 왜 java.sql.Date 타입이 아니라 String으로 했는가?
// -> DB 조회 시 날짜 데이터를 원하는 형태의 문자열로
//	  변환하여 조회할 예정 -> TO_CHAR() 이용
	
// getter/setter
// 생성자들
// toString()..
// 보일러 플레이트 코드
}

UserView 클래스

package edu.kh.jdbc.view;

import java.util.Scanner;

import edu.kh.jdbc.dto.User;
import edu.kh.jdbc.service.UserService;

// View : 사용자와 직접 상호작용하는 화면(UI)를 담당,
// 입력을 받고 결과를 출력하는 역할
public class UserView {
	
	// 필드
	private Scanner sc = new Scanner(System.in);
	private UserService service = new UserService();
	// view가 Service의 메서드를 활용해 줘야 하기 때문에
	
	// 메서드
	/**
	 * JDBCTemplate 사용 테스트
	 */
	public void test() {
		
		// 입력된 ID와 일치하는 USER 정보 조회
		System.out.print("ID 입력 : ");
		String input = sc.next();
		
		// 서비스 호출 후 결과 반환 받기
		User user = service.selectId(input);
		
		// 결과에 따라 사용자에게 보여줄 응답화면 결정
		if(user == null) {
			System.out.println("없음");
		} else {
			System.out.println(user);
		}
    }    
}

UserService 클래스

package edu.kh.jdbc.service;

import java.sql.Connection;

import edu.kh.jdbc.common.JDBCTemplate;
import edu.kh.jdbc.dao.UserDAO;
import edu.kh.jdbc.dto.User;

// (Model 중 하나)Service : 비즈니스 로직을 처리하는 계층.
// 데이터를 가공하고 트랜잭션(commit, rollback) 관리 수행 << 비즈니스 로직
public class UserService {
	
	// 필드
	private UserDAO dao = new UserDAO();
	// Service가 DAO의 메서드를 활용해줘야 하기 때문에

	
	// 메서드
	/** 전달 받은 아이디와 일치하는 User 정보 반환 서비스
	 * @param input (입력된 아이디)
	 * @return 아이디가 일치하는 회원 정보가 담긴 User객체, 없으면 null 반환
	 */
	public User selectId(String input) { //User는 참조형
		
		// 1. 커넥션 생성
		Connection conn = JDBCTemplate.getConnection();
		
		// 2. 데이터 가공 (할게 없으면 넘어감)
		
		// 3. DAO 메서드 호출 결과 반환
		User user = dao.selectId(conn, input);
		
		// 4. DML(commit / rollback)
		
		// 5. 다 쓴 커넥션 자원 반환
		JDBCTemplate.close(conn);
		
		// 6. 결과를 View에게 리턴
		
		return user; // View 클래스의 selectId로 리턴
	}
}

UserDAO 클래스

package edu.kh.jdbc.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

// import static : 지정된 경로에 존재하는 static 구문을 모두 얻어와
// 클래스명, 메서드명()이 아닌 메서드명() 만 작성해도 호출 가능하게 함.
import static edu.kh.jdbc.common.JDBCTemplate.*;
import edu.kh.jdbc.dto.User;

// (Model 중 하나) DAO (Data Access Object)
// 데이터가 저장된 곳에 접근하는 용도의 객체
// -> DB에 접근하여 Java에서 원하는 결과를 얻기 위해
// SQL을 수행하고 결과를 반환 받는 역할
public class UserDAO {

	// 필드
	// DB 접근 관련한 JDBC 객체 참조 변수 미리 선언
	private Statement stmt = null;
	private PreparedStatement pstmt = null;
	private ResultSet rs = null;
	// Connection은 Service에서
	
	
	// 메서드
	
	/** 전달받은 Connection을 이용해서 DB에 접근하여
	 * 전달받은 아이디(input)와 일치하는 User 정보를 DB 조회하기
	 * @param conn : Service에서 생성한 Connection 객체
	 * @param input : View에서 입력받은 아이디
	 * @return 아이디가 일치하는 회원의 User 또는 null
	 */
	public User selectId(Connection conn, String input) {

		// 1. 결과 저장용 변수 선언
		User user = null;
		
		try {
		
			// 2. SQL 작성
			String sql = "SELECT * FROM TB_USER WHERE USER_ID =?";
			
			// 3. PreparedStatenebt 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			// 4. ? (위치홀더) 에 알맞은 값 세팅
			pstmt.setString(1, input);
			
			// 5. SQL 수행 후 결과 반환 받기
			rs = pstmt.executeQuery();
			
			// 6. 조회 결과가 있을 경우
			// + 중복 되는 아이디가 없다고 가정
			// -> 1행만 조회되기 때문에 while문 보다는 if를 사용하는게 효과적
			if(rs.next()) {
				// 첫 행에 데이터가 존재한다면
				// 각 커럼의 값 얻어오기
				int userNo = rs.getInt("USER_NO");
				String userId = rs.getString("USER_ID");
				String userPw = rs.getString("USER_PW");
				String userName = rs.getString("USER_NAME");
				// java.sql.Date
				Date enrollDate = rs.getDate("ENROLL_DATE");
				
				// 조회된 컬럼값을 이용해서 User 객체 생성
				user = new User(userNo, userId, userPw, userName,
					    enrollDate.toString());
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			
			// 사용한 JDBC 객체 자원 반환(close)
			// JDBCTemplate.close(rs);
			// JDBCTemplate.close(pstmt);
			close(rs);
			close(pstmt); // import static 해서 생략
			
			// Connection 객체는 생성된 Service에서 close!
		}
		
		return user; // 결과 반환 (생성된 User 객체 또는 null)
		// Service 클래스의 selectId로 리턴
	}
}
profile
인생은 변수

0개의 댓글