[Java] JDBC + MVC

JH·2023년 4월 12일

Java

목록 보기
10/21

1. TIL

A. DBUtil, dbproperties

DBUtil을 이용하여 java와 연결하기, 자원반환
Connection 부분의 정보 보안을 위해 DBUtil 파일을 사용함

DAO

public class DeptDAO {
	public static ArrayList<Dept> getAllDept() throws SQLException {
		ArrayList<Dept> allDepts = null;
		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null;
		
		try	{
			conn = DBUtil.getConnection(); // DBUtil 파일로 연결
			stmt = conn.createStatement();
			rset = stmt.executeQuery("SELECT * FROM DEPT");
			
			
			allDepts = new ArrayList<Dept>();
			while(rset.next()) {
				allDepts.add(new Dept(rset.getInt("deptno"), rset.getString("dname"), rset.getString("loc")));
			}
			
		} finally {
			DBUtil.close(rset, stmt, conn); // DBUtil 파일로 자원 반환
		}
			return allDepts;
	}

DBUtil

db.properties를 입력받아 사용함 (보안), DB에서 공통적으로 사용한 것을 모아 놓음

// package, import 생략
public class DBUtil {
	// static 블럭으로 메모리에 올려야함
	static Properties properties = new Properties();
	static {
		try {
//			Class.forName("oracle.jdbc.driver.OracleDriver");
			properties.load(new FileInputStream("db.properties"));
			Class.forName(properties.getProperty("jdbc.driver"));
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// DB 연결 기능 메소드 : getConnection()
	public static Connection getConnection() throws SQLException {
//		return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "ID", "PW");
		return DriverManager.getConnection(properties.getProperty("jdbc.url"), 
											properties.getProperty("jdbc.id"), 
											properties.getProperty("jdbc.pw"));
	}
	
	// DB 자원 반환 메소드 : close(ResultSet rset, Statement stmt, Connection conn)
	public static void close(ResultSet rset, Statement stmt, Connection conn) {
		try {
			if (rset != null) {
				rset.close();
			}
			
			if (stmt != null) {
				stmt.close();
			}
			
			if (conn != null) {
				conn.close();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
    
	// 메소드 오버 로딩, 다형성 때문에 PreaparedStatement를 사용할 수 있음 (Statement 가 부모)
	public static void close(Statement stmt, Connection conn) {
		try {			
			if (stmt != null) {
				stmt.close();
			}
			
			if (conn != null) {
				conn.close();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

db.properties

jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
jdbc.id=ID
jdbc.pw=PW


B. JDBC MVC 🔥

구조

DTO : 객체, Getter, Setter, 생성자, toString 정의

Model - DAO : DB와 직접 연결됨, CRUD

View : 화면 처리

Controller : View와 Service를 연결

Util : DB 설정

exception : 사용자 정의 예외 처리

db.properties : DB 정보 보안


필수 : ojdbc8.jar Build Path추가

DBUtil, db.properties, 일부 DTO, DAO는 생략함
import, getter, setter, 생성자, toString 생략 함

1. DTO

public class BTProjectDTO {
	private String btProjectName; 	// 수혈프로젝트 이름
	private String btProjectId; 	// 수혈프로젝트 id
	private String donorId; 		// 헌혈자
	private String recipientId; 	// 수혈자
	private String btContent; 		// 수혈프로젝트 내용
}

2. View

StartView

public class RunningStartView {

	public static void main(String[] args) {
		BTController controller = BTController.getInstance();
        
		BTProjectDTO btProject = new BTProjectDTO("F-", "bt4", "donor4", "recipient4", "저장확인용");

		System.out.println("=====모든 프로젝트 검색=====");
		controller.allBTProjects();
		
		System.out.println("=====프로젝트 이름으로 프로젝트 검색=====");
		controller.getBTProject("A-");
		
		System.out.println("=====프로젝트 이름으로 해당 프로젝트 내용 수정=====");
		controller.updateBTProject("A-", "New Contents123");
		
		System.out.println("=====프로젝트 이름으로 해당 프로젝트 삭제=====");
		controller.deleteBTProject("B-");
		
		System.out.println("=====프로젝트 저장=====");
		controller.addBTProject(btProject);
	}
}

EndView

public class RunningEndView {
	//모든 프로젝트 출력
	public static void projectListView(ArrayList<BTProjectDTO> allProject){
		int length = allProject.size();
		if( length != 0 ){
			for(int index = 0; index < length; index++){			
				System.out.println("검색정보 " + (index+1) + " - " + allProject.get(index));
			}
		}
	}
		
	//특정 프로젝트 출력 
	public static void projectView(BTProjectDTO project){
		System.out.println(project);		
	}
	
	// 모든 DTO 정보 출력하는 메소드
	public static void allView(Object object){
		System.out.println(object);
	}
	
	//예외 상황 출력
	public static void showError(String message){
		System.out.println(message);	
	}
}

3. Controller

public class BTController {
	private static BTController instance = new BTController();
	private BTService service = BTService.getInstance();
	
	private BTController() {}
	
	public static BTController getInstance() {
		return instance;
	}
	
	// 모든 프로젝트 검색
	public void allBTProjects() {
		try{
			RunningEndView.projectListView(service.getAllBTProjects());
		}catch(SQLException s){
			s.printStackTrace();
			RunningEndView.showError("모든 프로젝트 검색시 에러 발생");
		}
	}
	
	// 특정 프로젝트 검색
	public void getBTProject(String btProjectName) {
		try {
			RunningEndView.projectView(service.getBTProject(btProjectName));
		} catch (SQLException | NotExistException e) {
			
		}
	}
	
	// 특정 프로젝트 업데이트
	public void updateBTProject(String btProjectName, String btProjectContent) {
			try {
				service.updateBTProject(btProjectName, btProjectContent);
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (NotExistException e) {
				e.printStackTrace();
			}
	}
	
	// 특정 프로젝트 삭제
	public void deleteBTProject(String btProjectName) {
		try {
			service.deleteBTProject(btProjectName);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (NotExistException e) {
			e.printStackTrace();
		}
	}
	
	// 프로젝트 저장
	public void addBTProject(BTProjectDTO btProject) {
		try {
			service.addBTProject(btProject);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

4. Service

public class BTService {
	private static BTService instance = new BTService();
	
	private BTService(){}
	public static BTService getInstance(){
		return instance;
	}
	
	//BTProject - CRUD, NPE 예외 처리
	public void notExistBTProject(String btProjectName) throws NotExistException, SQLException{
		BTProjectDTO btProject = BTProjectDAO.getBTProject(btProjectName);
		if(btProject == null){
			throw new NotExistException("검색하진 수혈 정보가 없습니다.");
		}
	}
	
	//모든 BTProject 정보 반환
	public ArrayList<BTProjectDTO> getAllBTProjects() throws SQLException{
		return BTProjectDAO.getAllBTProjects();
	}
	
	//BTProject 이름으로 검색
	public BTProjectDTO getBTProject(String btProjectName) throws SQLException, NotExistException{
		return BTProjectDAO.getBTProject(btProjectName);
	}
	
	//새로운 BTProject 저장
	public boolean addBTProject(BTProjectDTO btProject) throws SQLException{
		return BTProjectDAO.addBTProject(btProject);
	}
	
	//기존 BTProject 수정
	public boolean updateBTProject(String btProjectName, String btProjectContent) throws SQLException, NotExistException{
		notExistBTProject(btProjectName);
		return BTProjectDAO.updateBTProject(btProjectName, btProjectContent);
	}
	
	//BTProject 삭제
	public boolean deleteBTProject(String btProjectName) throws SQLException, NotExistException{
		notExistBTProject(btProjectName);
		return BTProjectDAO.deleteBTProject(btProjectName);
	}
// DonorDTO, RecipientDTO CRUD 생략

5. Model (DAO)

public class BTProjectDAO {
	// 프로젝트 저장
	public static boolean addBTProject(BTProjectDTO btProject) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		try {
			con = DBUtil.getConnection();
			pstmt = con.prepareStatement("insert into bt_project values(?, ?, ?, ?, ?)");
			pstmt.setString(1, btProject.getBtProjectName());
			pstmt.setString(2, btProject.getBtProjectId());
			pstmt.setString(3, btProject.getDonorId());
			pstmt.setString(4, btProject.getRecipientId());
			pstmt.setString(5, btProject.getbtContent());

			int result = pstmt.executeUpdate();

			if (result == 1) {
				return true;
			}
		} finally {
			DBUtil.close(con, pstmt);
		}
		return false;
	}
	
	// 프로젝트 아이디로 프로젝트 내용 수정
		public static boolean updateBTProject(String btProjectName, String btProjectContent) throws SQLException {
			Connection con = null;
			PreparedStatement pstmt = null;
			
			try {
				con = DBUtil.getConnection();

				pstmt = con.prepareStatement("update bt_project set bt_content=? where bt_project_name=?");
				pstmt.setString(1, btProjectContent);
				pstmt.setString(2, btProjectName);
				
				int result = pstmt.executeUpdate();
				
				if (result == 1) {
					return true;
				}
				
			} finally {
				DBUtil.close(con, pstmt);
			}
			return false;
		}

	// 프로젝트 이름으로 프로젝트 삭제
	public static boolean deleteBTProject(String btProjectName) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		try {
			con = DBUtil.getConnection();
			pstmt = con.prepareStatement("delete from bt_project where bt_project_name=?");
			pstmt.setString(1, btProjectName);
			int result = pstmt.executeUpdate();
			if (result == 1) {
				return true;
			}
		} finally {
			DBUtil.close(con, pstmt);
		}
		return false;
	}

	// 프로젝트 이름으로 프로젝트 검색
	public static BTProjectDTO getBTProject(String btProjectName) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		BTProjectDTO blood_transfusionUser = null;

		try {
			con = DBUtil.getConnection();
			pstmt = con.prepareStatement("select * from bt_project where bt_project_name=?");
			pstmt.setString(1, btProjectName);
			rset = pstmt.executeQuery();
						
			if(rset.next()) {
				blood_transfusionUser = new BTProjectDTO(rset.getString(1),
															rset.getString(2),
															rset.getString(3),
															rset.getString(4),
															rset.getString(5)
															);
			}
			
		} finally {
			DBUtil.close(con, pstmt, rset);
		}
		return blood_transfusionUser;
	}
	

	// 모든 수혈 프로젝트 검색
	public static ArrayList<BTProjectDTO> getAllBTProjects() throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		ArrayList<BTProjectDTO> list = null;
		
		try {
			con = DBUtil.getConnection();
			pstmt = con.prepareStatement("select * from bt_project");
			rset = pstmt.executeQuery();
			
			list = new ArrayList<BTProjectDTO>();
			while(rset.next()) { // 컬럼 이름이나 Index로 가져올 수 있음
				list.add(new BTProjectDTO(rset.getString(1),
											rset.getString(2),
											rset.getString(3),
											rset.getString(4),
											rset.getString(5)
											));
			}
		} finally {
			DBUtil.close(con, pstmt, rset);
		}
		return list;		
	}
}


2. 에러

JDBC의 업데이트 작업 중 NullPointException이 발생함, try ~ catch 처리도 했고 값이 null도 아니였다.

결론은 Connection 에서 password가 잘못되었을 경우에도 NPE가 발생한다는 것이였다.

코드가 길어지고 로직도 많아져서 타입에 대한 예외를 자주 마주침, 파라미터로 보낸 타입과 받을 때의 타입 유무 체크가 필수적임


3. 보완 해야 할 것

오랜만에 다시 java로 돌아오니 낯설다.
DB까지의 연결이 끝났으니 이 기본 구조는 눈으로 손으로 익혀야 추후 학습에서 왜 사용했지를 알게 된다고함

코드를 적으면서 따라가다보니 마지막 DAO까지 오게되면 무엇으로 시작해서 무엇으로 끝날지 설계하고 작업하면 예외나 추가적인 작업을 줄일 수 있을 것으로 예상됨


4. 느낀점

처음엔 못 따라갈 것 같다가 하다보면 따라가는게 놀랍다.
그저 계속 써보면서 익혀야겠다.

profile
잘해볼게요

0개의 댓글