상세 컨텐츠

본문 제목

[1.2] DAO의 분리

토비의스프링

by kwanghyup 2020. 7. 30. 12:51

본문

 

커넥션 만들기의 추출

 

UserDao의 관심사항 

 

UserDao의 add()메소드 하나에서만 적어도 세 가지 관심사항을 발견할 수 있다.

 

1. DB와 연결을 위한 커넥션을 어떻게 가지고 올 것인가

2. 사용자 등록을 위해 DB에 보낼 SQl문장을 담은 Statement만들고 실행하는 것

3. 작업을  끝낸 후 리소스 반환 

 

메소드 중복 추출 

 

커넥션을 가져오는 중복된 코드를 분리해보자. 

package springbook.user.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import springbook.user.domain.User;

public class UserDao {
	
	private Connection getConnection() throws ClassNotFoundException, SQLException {
		Class.forName("com.mysql.cj.jdbc.Driver");
		String url = "jdbc:mysql://localhost:3306/tobiespring?characterEncoding=utf8&serverTimezone=UTC";
		Connection c = DriverManager.getConnection(url,"root","12345678");
		return c;
	}
	
	public void add(User user) throws ClassNotFoundException, SQLException {
		Connection c= getConnection();
		
		String sql = "insert into users values(?,?,?)";
		PreparedStatement ps = c.prepareStatement(sql);
		ps.setString(1, user.getId());
		ps.setString(2, user.getName());
		ps.setString(3, user.getPassword());
		
		ps.executeUpdate();
		
		ps.close();
		c.close();
	}
	
	public User get(String id) throws ClassNotFoundException, SQLException {
		Connection c= getConnection();
		
		String sql = "select * from users where id = ?";
		PreparedStatement ps = c.prepareStatement(sql);
		ps.setString(1,id);
		
		ResultSet rs = ps.executeQuery(); 
		rs.next(); 
		User user = new User(); 
		user.setId(rs.getString("id"));
		user.setName(rs.getString("name"));
		user.setPassword(rs.getString("password"));
		
		rs.close();
		ps.close();
		c.close();
		
		return user;
	}
	
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
	
		UserDao dao = new UserDao();
		
		User user = new User();
		user.setId("whiteship");
		user.setName("백기선");
		user.setPassword("married");
		
		dao.add(user);
		
		System.out.println(user.getId() +" 등록성공");
				
	}
	
}

검증을 하기 전에 users 테이블에 있는 모든 사용자 정보를 삭제해야한다. 

 

 

DB커넥션 만들기의 독립 

 

UserDao를 고객사에게 소스 코드를 공개하지 않고 제공하는 방법에 대하여 알아보자. 

각각의 고객사는 각자가 원하는 DB 커넥션 생성방식을 적용해가면서 UserDao를 사용하길 원한다고 하자.

 

1. 상속을 통한 확장 

 

UserDao에서 메소드의 구현부를 제거하고

getConnection()메소드를 추상메소드를 만든다. 

(UserDao클래스 역시 추상클래스이다.)

 

각각의 고객사는 이 추상클래스를 상속하여

추상메소드로 선언했던 getConnection()메소드를

원하는 방식대로 구현하여 사용한다. 

 

package springbook.user.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import springbook.user.domain.User;

public abstract class UserDao {
	
	public abstract Connection getConnection() throws ClassNotFoundException, SQLException;
	
	public void add(User user) throws ClassNotFoundException, SQLException {
		Connection c= getConnection();
		
		String sql = "insert into users values(?,?,?)";
		PreparedStatement ps = c.prepareStatement(sql);
		ps.setString(1, user.getId());
		ps.setString(2, user.getName());
		ps.setString(3, user.getPassword());
		
		ps.executeUpdate();
		
		ps.close();
		c.close();
	}
	
	public User get(String id) throws ClassNotFoundException, SQLException {
		Connection c= getConnection();
		
		String sql = "select * from users where id = ?";
		PreparedStatement ps = c.prepareStatement(sql);
		ps.setString(1,id);
		
		ResultSet rs = ps.executeQuery(); 
		rs.next(); 
		User user = new User(); 
		user.setId(rs.getString("id"));
		user.setName(rs.getString("name"));
		user.setPassword(rs.getString("password"));
		
		rs.close();
		ps.close();
		c.close();
		
		return user;
	}		
}

 

NUserDao ( DUserDao 동일한 패턴)

package springbook.user.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class NUserDao extends UserDao{
	
	@Override
	public Connection getConnection() throws ClassNotFoundException, SQLException {
		System.out.println("NUserDao 사용 ");
		Class.forName("com.mysql.cj.jdbc.Driver");
		String url = "jdbc:mysql://localhost:3306/tobiespring?characterEncoding=utf8&serverTimezone=UTC";
		Connection c = DriverManager.getConnection(url,"root","12345678");
		return c;
	}

}

 

DB를 초기화한 다음 테스트를 실행해보자. 

DUserDao도 같은 방식으로 테스트 한다. 

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    NUserDao dao = new NUserDao(); 

    User user = new User();
    user.setId("whiteship");
    user.setName("백기선");
    user.setPassword("married");

    dao.add(user);

    System.out.println(user.getId() + " 등록성공");
}

 

 

 

'토비의스프링' 카테고리의 다른 글

[1.6] 싱글톤 레지스트리와 오브젝트 스코프  (0) 2020.10.27
[1.5]Spring IoC  (0) 2020.10.27
[1.4] 제어의 역전  (0) 2020.10.27
[1.3] DAO의 확장  (0) 2020.10.27
[1.1] 초난감DAO  (0) 2020.07.30

관련글 더보기

댓글 영역