| DTO(Data Transfer Object) | - 값을 묶어서 전달하는 용도의 객체 - DB에 데이터를 전달하거나, 가져올 때 사용 → DB 특정 테이블의 한 행의 데이터를 저장할 수 있는 형태로 class 작성 |
| DAO(Data Access Object) | |
| JDBCTemplate | JDBC 관련 작업을 위한 코드를 미리 작성해서 제공하는 클래스 - getConnection() + AutoCommit false - commit() / rollback() - 각종 close() |
| Service | - 비지니스 로직 처리 - DB에 CRUD 후 결과 반환 받기 + DML 성공 여부에 따른 트랜잭션 제어 처리(commit/rollback) → commit/rollback에는 Connection 객체가 필요하기 때문에 Connection 객체를 Service에서 생성 후 Dao에 전달하는 형식의 코드를 작성하게 됨 |
[dto]
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
private int userNo;
private String userId;
private String userPw;
private String userName;
private String enrollDate;
// -> enrollDate는 왜 java.sql.Date가 아니라 String인가??
// -> DB 조회 시 날짜 데이터를 원하는 형태의 문자열로
// 변환하여 조회할 예정 -> TO_CHAR() 이용
}
[common]
package edu.kh.jdbc.common;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/* Template : 양식, 주형, 본을 뜨기 위한 틀
* -> "미리 만들어뒀다"를 의미
*
* JDBCTemplate :
* JDBC 관련 작업을 위한 코드를
* 미리 작성해서 제공하는 클래스
*
* - getConnection() + AutoCommit false
* - commit() / rollback()
* - 각종 close()
*
* ***** 중요 *****
* 어디서든 JDBCTemplate 클래스를
* 객체로 만들지 않고도 메서드를 사용할 수 있도록 하기 위해
* 모든 메서드를 public static 으로 선언
* */
public class JDBCTemplate {
// 필드
private static Connection conn = null;
// -> static 메서드에서 사용 가능한 필드는 static 필드만 가능
// 메서드
/**
* 호출 시 Connection 객체를 생성해서 반환하는 메서드
* @return conn
*/
public static Connection getConnection() {
try {
// 이전에 참조하던 Connection 객체가 존재하고
// 아직 close된 상태가 아니라면
if(conn != null && !conn.isClosed()) {
return conn; // 새로 만들지 않고 기존 Connection 반환
}
/* DB 연결을 위한 정보들을 별도 파일에 작성하여
* 읽어오는 형식으로 코드를 변경!!!
*
* 이유 1 : Github에 코드 올리면 해킹하세요~ 뜻이라
* 보안적인 측면에서 코드를 직접 보지 못하게함
*
* 이유 2 : 혹시라도 연결하는 DB 정보가 변경될 경우
* Java 코드가 아닌
* 읽어오는 파일의 내용을 수정하면 되기 때문에
* Java 코드 수정 x -> 추가 컴파일 필요 x
* --> 개발 시간 단축!!
*/
/* driver.xml 파일 내용 읽어오기 */
// 1. Properties 객체 생성
// - Map의 자식 클래스
// - K, V가 모두 String 타입
// - xml파일 입출력을 쉽게 할 수 있는 메서드 제공
Properties prop = new Properties();
// 2. Properties 메서드를 이용해서
// driver.xml 파일 내용을 읽어와 prop 에 저장
String filePath = "driver.xml";
// 프로젝트 폴더 바로 아래 driver.xml 파일
// driver.xml 파일의 내용을 prop에 저장하겠다
prop.loadFromXML(new FileInputStream(filePath));
// prop에 저장된 값(driver.xml 에서 읽어온 값)을 이용해
// Connection 객체 생성하기
// prop.getProperty("KEY") : KEY가 일치하는 Value를 반환
Class.forName( prop.getProperty("driver") );
String url = prop.getProperty("url");
String userName = prop.getProperty("userName");
String password = prop.getProperty("password");
conn = DriverManager.getConnection(url, userName, password);
// 만들어진 Connection에 AutoCommit 끄기
conn.setAutoCommit(false);
}catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// ----------------------------------
/* 트랜잭션 제어 처리 메서드 (commit, rollback) */
/**
* 전달 받은 커넥션에서 수행한 SQL을 COMMIT하는 메서드
* @param conn
*/
public static void commit(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 전달 받은 커넥션에서 수행한 SQL을 Rollback하는 메서드
* @param conn
*/
public static void rollback(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
// ---------------------------------------------------
/**
* 전달 받은 커넥션을 close(자원 반환)하는 메서드
* @param conn
*/
public static void close(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 전달 받은 Statement를 close(자원 반환)하는 메서드
* + PreparedStatement도 close 처리 가능!!
* 왜?? PreparedStatement가 Statement의 자식이기 때문에!!
* (다형성 업캐스팅)
* @param stmt
*/
public static void close(Statement stmt) {
try {
if(stmt != null && !stmt.isClosed()) stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 전달 받은 ResultSet을 close(자원 반환)하는 메서드
* @param rs
*/
public static void close(ResultSet rs) {
try {
if(rs != null && !rs.isClosed()) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
[service]
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;
// Service : 비지니스 로직 처리
// - DB에 CRUD 후 결과 반환 받기
// + DML 성공 여부에 따른 트랜잭션 제어 처리(commit/rollback)
// --> commit/rollback에는 Connection 객체가 필요하기 때문에
// Connection 객체를 Service에서 생성 후
// Dao에 전달하는 형식의 코드를 작성하게 됨
public class UserService {
// 필드
private UserDao dao = new UserDao();
// 메서드
/**
* 전달 받은 아이디와 일치하는 User 정보 반환
* @param input 입력된 아이디
* @return 아이디가 일치하는 회원 정보, 없으면 null
*/
public User selectId(String input) {
// 커넥션 생성
Connection conn = JDBCTemplate.getConnection();
// Dao 메서드 호출 후 결과 반환 받기
User user = dao.selectId(conn, input);
// 다 쓴 커넥션 닫기
JDBCTemplate.close(conn);
return user; // DB 조회 결과 반환
}
}
[dao]
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 edu.kh.jdbc.common.JDBCTemplate;
import edu.kh.jdbc.dto.User;
// 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을 이용해 DB에 접근하여
* 전달 받은 아이디와 일치하는 User 정보 조회하기
* @param conn : Service에서 생성한 Connection 객체
* @param input : View에서 입력 받은 아이디
* @return
*/
public User selectId(Connection conn, String input) {
User user = null; // 결과 저장용 변수
try {
// SQL 작성
String sql = "SELECT * FROM TB_USER WHERE USER_ID = ?";
// PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?(placeholder)에 알맞은 값 대입
pstmt.setString(1, input);
// SQL 수행 후 결과 반환 받기
rs = pstmt.executeQuery();
// 조회 결과가 있을 경우
// -> 중복되는 아이디가 없을 경우
// 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);
// Connection 객체는 Service에서 close!!!!!!!
}
return user; // 결과 반환(생성된 User 또는 null)
}
}
[run]
package edu.kh.jdbc.run;
import edu.kh.jdbc.common.JDBCTemplate;
import edu.kh.jdbc.view.UserView;
public class UserRun {
public static void main(String[] args) {
System.out.println(JDBCTemplate.getConnection());
UserView view = new UserView();
view.test();
}
}'BackEnd > Java' 카테고리의 다른 글
| [JDBC]JDBC 기초 (PreparedStatement) (0) | 2024.09.02 |
|---|---|
| [JDBC] JDBC 기초 작성방법 (0) | 2024.09.02 |
| [Servlet/JSP]Redirect(재 요청) (0) | 2024.08.16 |
| [Servlet/JSP]Forward(요청 위임) (0) | 2024.08.16 |
| [Servlet/JSP]Dynamic Web Project의 폴더 구조 및 연습하기 (0) | 2024.08.16 |