[Java] Java에서 Query문 리팩토링(2)

배지원·2022년 10월 20일
0

실습

목록 보기
3/24

이전에 했던 프로젝트를 추상화 클래스를 사용하여 좀 더 가독성 있게 구현하였다.
이전 프로젝트 : https://velog.io/@qowl880/Java-Java%EC%97%90%EC%84%9C-Query%EB%AC%B8-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%811

1. 중복 코드 추상화 사용

  • DB는 mysql, oracle 등 여러가지 종류와 다른 유저 정보를 가지고 있기 때문에 각 DB에 맞게 설정을 해줘야 한다. 따라서 DB설정하는 중복된 코드를 분리를 시키는데 추상화를 사용하여 쉽게 가져다 사용할 수 있도록 구현했다.

  • 해당 프로젝트에서는 MYSQL만을 사용하고 서로 다른 유저 정보와 AWS, Local 주소를 가지고 구분하였다.

1. 메인 클래스

    public abstract Connection makeConnection() throws SQLException;
    // DB를 여러개 동시에 사용하는 경우 각 DB에 연결시켜야 하므로 추상화 클래스를 상속받아
    // 원하는 DB로 연결시키는 방식에 사용
  • 이처럼 중복되는 메서드를 추상화 하여 다른 클래스에서 쉽게 변경할 수 있도록 함

2. AWS 주소

public class AWSUserDaoImpl extends UserDaoAbstract{
    @Override
    public Connection makeConnection() throws SQLException {
        Map<String,String> env = System.getenv();       // 아래의 값들은 해킹 위험이 있으므로 코드상에 데이터를 넣지말고
        // 왼쪽 위에 메뉴바에서 망치 옆에 프로젝트를 눌러 edit configurations를 누르고
        // environments variables를 눌러 값을 입력해 준다.
        String dbHost = env.get("DB_HOST");         // DB 호스트 번호(AWS 주소) 가져옴
        String dbUser = env.get("DB_USER");             // DB 호스트 이름  가져옴
        String dbPassword = env.get("DB_PASSWORD");     // DB 비밀번호  가져옴

        Connection conn = DriverManager.getConnection(dbHost,dbUser,dbPassword);
        
        // 외부에서 주소와 호스트정보 비밀번호 입력
        
        return conn;
    }
}
  • 추상화 클래스를 상속받아 추상화 메서드를 수정을 할 수 있다.
  • AWS에 해당하는 주소와 호스트 이름, 비밀번호를 설정하여 이 값을 메인 클래스로 반환해줌

3. Local 주소

public class LocalUserDaoImpl extends UserDaoAbstract{
    @Override
    public Connection makeConnection() throws SQLException {
        Map<String,String> env = System.getenv();       // 아래의 값들은 해킹 위험이 있으므로 코드상에 데이터를 넣지말고
        // 왼쪽 위에 메뉴바에서 망치 옆에 프로젝트를 눌러 edit configurations를 누르고
        // environments variables를 눌러 값을 입력해 준다.

        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306"
                ,"root","12345678");
        // Local 저장소는 데이터를 코드상에 입력해도 해커가 털어가기 힘들다.

        return conn;
    }
}
  • Local에 해당하는 주소와 호스트 이름, 비밀번호를 설정하여 이 값을 메인 클래스로 반환해줌

2. CODE

1. 추상화 클래스(메인 클래스)

public abstract class UserDaoAbstract {

    public abstract Connection makeConnection() throws SQLException;
    // DB를 여러개 동시에 사용하는 경우 각 DB에 연결시켜야 하므로 추상화 클래스를 상속받아
    // 원하는 DB로 연결시키는 방식에 사용

    public void add(User user) throws ClassNotFoundException {

        try{
            // db 연결(호스트,이름,비밀번호)
            Connection conn = makeConnection();     // 설정들을 모아둔 메서드 호출

            PreparedStatement ps =  conn.prepareStatement("INSERT INTO users(id,name,password) VALUES(?,?,?)");
            ps.setString(1,user.getId());        // mysql 테이블로 값 insert
            ps.setString(2,user.getName());
            ps.setString(3,user.getPassword());

            ps.executeUpdate();     // ctrl + enter 즉, mysql에서 번개모양을 눌러 최신화 한다는 느낌
            ps.close();
            conn.close();
            System.out.println("데이터가 insert 됬습니다.");

        }catch (SQLException e){
            throw new RuntimeException(e);
        }

    }

    public User select(String id) throws SQLException, ClassNotFoundException {

        try {
            Connection conn = makeConnection();
            PreparedStatement ps = conn.prepareStatement("SELECT id,name,password FROM users WHERE id = ?");
            ps.setString(1, id);     // id는 get(String id)로 받은 id
            ResultSet rs = ps.executeQuery();   // 쿼리문을 저장함 insert문과 달리 excuteQuery() 사용
            // rs에는 쿼리 실행 결과가 담겨져 있다. (select * from users where id = 1;)
            rs.next();

            // User 생성자를 통해 쿼리문에 id값을 넣어 찾은 id, name,password 값을 저장한다.
            User user = new User(rs.getString("id"), rs.getString("name"), rs.getString("password"));
            rs.close();
            ps.close();
            conn.close();
            return user;
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }


   public static void main(String[] args) throws ClassNotFoundException, SQLException {
        AWSUserDaoImpl userDao = new AWSUserDaoImpl();	// AWS에 해당하는 값을 가져옴
        LocalUserDaoImpl localuserDao = new LocalUserDaoImpl();	// Local에 해당하는 값을 가져옴
        userDao.add(new User("7","Ruru","1234qwer"));   // user로 값을 받아 DTO에 저장한 후 mysql로 데이터 보냄(AWS DB에 해당하는 값)
        System.out.println(userDao.select("1"));
    }
 
}

2. AWS 클래스

public class AWSUserDaoImpl extends UserDaoAbstract{
    @Override
    public Connection makeConnection() throws SQLException {
        Map<String,String> env = System.getenv();       // 아래의 값들은 해킹 위험이 있으므로 코드상에 데이터를 넣지말고
        // 왼쪽 위에 메뉴바에서 망치 옆에 프로젝트를 눌러 edit configurations를 누르고
        // environments variables를 눌러 값을 입력해 준다.
        String dbHost = env.get("DB_HOST");         // DB 호스트 번호(AWS 주소) 가져옴
        String dbUser = env.get("DB_USER");             // DB 호스트 이름  가져옴
        String dbPassword = env.get("DB_PASSWORD");     // DB 비밀번호  가져옴

        Connection conn = DriverManager.getConnection(dbHost,dbUser,dbPassword);
        
        // 외부에서 주소와 호스트정보 비밀번호 입력
        
        return conn;
    }
}

3. Local 클래스

public class LocalUserDaoImpl extends UserDaoAbstract{
    @Override
    public Connection makeConnection() throws SQLException {
        Map<String,String> env = System.getenv();       // 아래의 값들은 해킹 위험이 있으므로 코드상에 데이터를 넣지말고
        // 왼쪽 위에 메뉴바에서 망치 옆에 프로젝트를 눌러 edit configurations를 누르고
        // environments variables를 눌러 값을 입력해 준다.

        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306"
                ,"root","12345678");
        // Local 저장소는 데이터를 코드상에 입력해도 해커가 털어가기 힘들다.

        return conn;
    }
}
profile
Web Developer

0개의 댓글