본문으로 바로가기

Gradle로 Spring을 해보자 with Intelli J 14 - 제5편 Connection을 interface를 사용해서 분리 해보자






이전 포스트

2015/04/11 - [Web개발/JAVA] - Gradle로 Spring을 해보자 with Intelli J 14 - 제1편 Gradle로 Java Project 생성하기

2015/04/13 - [Web개발/JAVA] - Gradle로 Spring을 해보자 with Intelli J 14 - 제2편 Gradle로 mysql jdbc driver dependency 설정하기

2015/04/13 - [Web개발/JAVA] - Gradle로 Spring을 해보자 with Intelli J 14 - 제3편 MySQL에 DB생성하기

2015/04/13 - [Web개발/JAVA] - Gradle로 Spring을 해보자 with Intelli J 14 - 제4편 mysql db와 연동을 확인 해보자



용어정리

interface(인터페이스) - constructor(생성자)를 이용해 class를 주입 받아서 사용하기 위해 주로 사용한다.

constructor(생성자) - '컨스트럭터'라고도 쓸 것이다. interface를 받아서 전역변수에 저장해주는 역할을 주로 한다.

정의(define) - class, method의 모양을 만들어 주는 것을 '정의'라고 하겠다.

구현 - 내용을 넣어주는 것을 '구현'이라고 하겠다.



토비의 스프링3에서는 인터페이스를 이용해 DB Connection Object를 분리하는 방법에 대해 초반에 아주 자세히 설명한다.


Interface(인터페이스)란 Class가 구체적인 Class이름을 알고 있는 것을 없애기 위해서 필요한게 Interface라고 할 수 있다.



Connection Object를 Interface를 이용해 분리하고자 할 때 먼저 interface에 대해 알아볼 필요가 있다. 내가 전산과 출신이 아니라서 그런지 몰라도 interface에 대한 개념을 이해하고 사용하는데 자바를 처음 접하고 5년이라는 세월이 걸린 것 같다.


인터페이스는 무엇을 '연결해준다'는 의미를 포함하고 있고 java를 포함한 프로그래밍을 할 때는 class에 constructor(생성자)나 setter등을 이용해 class를 넣어주기 위해 사용한다고 보면 된다.


자세한 설명은 인터넷에 나와있으니 찾아보면 될 것 같고 인터페이스는 쓰다보면 이해할 수 있는 아주 오묘한 녀석인 것 같지만 한번 익혀 놓으면 계속 사용할 수 있으니 처음엔 잘 이해가 가지 않더라도 꾸준히 사용하면서 익혀보기 바란다.



이제는 Interface를 이용해 Connection Object를 분리해보도록 하자.


아래 화면은 이전 포스트에서 제대로 작동하던 코드이다.


소스코드는 아래와 같다.

public class UserDao {

public Connection getConnection() throws SQLException, ClassNotFoundException {

Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost/krkdb"
,"root"
,"111111");

return c;
}

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

Connection c = getConnection();

PreparedStatement ps = c.prepareStatement("select * from user where id = ?");
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 SQLException, ClassNotFoundException {
UserDao dao = new UserDao();
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());


}

}



여기에서 getConnection() method를 interface를 이용해 분리를 해볼 것이다.


일단은 전역변수로 ConnectionMaker type의 변수를 선언해주고 해당 변수에 값을 넣어주는 코드가 있는 constructor(컨스트럭터)를 하나 선언 해준다. 



아래 두줄이다.


private ConnectionMaker connectionMaker;

public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}



일단 빨간색이 나온다. ConnectionMaker라는 Class도 Interface도 없기 때문이다. 


Interface를 만들자.


/java/라는 파란색 폴더에서 마우스 우측 클릭 해서 context menu를 호출한다.

New - New Class 를 선택한다.



아래와 같은 화면이 나오는데 Name은 'ConnectionMaker'로 해주고 Kind는 Interface로 해준다.




그리고 엔터를 누르면 아래와 같이 interface가 만들어진다.


만들어진 source code는 아래와 같다.

public interface ConnectionMaker {

}




다시 UserDao.java의 소스코드를 보면 빨간불이 꺼진걸 확인 할 수 있다.



그런데 아직 빨간불이 작은게 하나 남아있다. 아래로 스크롤을 내려보자.


UserDao();에 빨간줄이 가있다. 생성자를 만들어주었고 해당 생성자에는 ConnectionMaker를 넣어주게 되어 있는데 안넣어주어서 에러가 난 것이다.





그러면 저 빨간불을 끄기 위해서는 방금 만든 interface에 어떤 메소드가 들어갈지 모양을 정해주고 구현체를 만들고 해당 interface형으로 Class를 생성하고 생성한 Class를 UserDao를 생성할 때 넣어주어야 한다.


빨간불 끄는 방법을 한번 정리를 해보면


1.interface에 어떤 method가 들어갈지 모양을 정해준다

2.해당 interface의 구현체를 만들어 준다.

3.interface형으로 구현체의 Class를 생성하고

4.Class를 UserDao를 생성할 때 넣어준다.


이렇게 4단계인데 이것도 처음에는 어렵긴 하다. 일단 하나씩 해보자.




1.interface에 어떤 method가 들어갈지 모양을 정해준다.

이걸 해야되는데 interface의 모양이란게 method의 모양을 정해주는 것이라고 할 수 있다.


호출 하면 Connection Object를 Return해준다는 method를 정의만 해준다.


public interface ConnectionMaker {

    public Connection getConnection();

}





2.해당 interface의 구현체를 만들어 준다.

인터페이스를 정의 했으면 해당 인터페이스를 사용하는 Class를 만들어준다.



New - New Class 를 선택한다.



krkdb에 연결하기 위한 Connection을 만들어주는 Interface이므로 KrkConnectionMaker라고 이름 지었다.




일단 Class를 하나 만들었다.


그리고 일단 interface에 있는 Method를 구현 해준다.


public class KrkConnectionMaker implements ConnectionMaker {

@Override
public Connection getConnection() {
return null;
}

}



return이 null인데 UserDao에 있는 getConnection()에 있는 내용을 가지고 와서 붙인다.


public class KrkConnectionMaker implements ConnectionMaker {

@Override
public Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost/krkdb"
, "root"
, "111111");

return c;
}

}


붙여넣어주면 Intelli J IDEA가 SQLException, ClassNotFoundException 익셉션을 붙여야 한다고 경고메세지를 띄운다


alt + enter를 눌러서 exception처리 해주고 interface에도 exception처리를 하겠느냐고 물어보는데 Yes를 누르면 된다.


그러면 Interface도 아래와 같이 바뀐다


public interface ConnectionMaker {

    public Connection getConnection() throws SQLException, ClassNotFoundException;

}






3.interface형으로 구현체의 Class를 생성하고


KrkConnectinoMaker Class를 만들었으니 생성 해보자 이건 은근 간단하다.

public static void main(String[] args) throws SQLException, ClassNotFoundException {

UserDao dao = new UserDao();
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());


}


기존 main method에 아래와 같이 한줄만 추가해주면 된다.


public static void main(String[] args) throws SQLException, ClassNotFoundException {

ConnectionMaker krkConnectionMaker = new KrkConnectionMaker();
UserDao dao = new UserDao();
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());


}








4.Class를 UserDao를 생성할 때 넣어준다.


public static void main(String[] args) throws SQLException, ClassNotFoundException {

ConnectionMaker krkConnectionMaker = new KrkConnectionMaker();
UserDao dao = new UserDao();
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());


}


위 코드에서 생성한 krkConnectionMaker를 UserDao 생성자를 통해 넣어준다.




화면을 보면 빨간줄이 모두 없어진 것을 볼 수 있다.



소스코드는 아래와 같다.


public static void main(String[] args) throws SQLException, ClassNotFoundException {


ConnectionMaker krkConnectionMaker = new KrkConnectionMaker();
UserDao dao = new UserDao(krkConnectionMaker);
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());


}




이제 ConnectionMaker로 getConnection()을 분리 했으니 UserDao에서 getConnection()을 지워준다.


지웠더니 또 빨간색이 뜬다.


getConnection()을 지운 소스코드는 아래와 같다.


    public class UserDao {

private ConnectionMaker connectionMaker;

public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}

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

Connection c = getConnection();

PreparedStatement ps = c.prepareStatement("select * from user where id = ?");
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 SQLException, ClassNotFoundException {

ConnectionMaker krkConnectionMaker = new KrkConnectionMaker();
UserDao dao = new UserDao(krkConnectionMaker);
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());

}

}





userDao의 생성자로 받은 ConnectionMaker의 getConnection()을 호출하는 코드로 변경하자 위 코드의 주황색 부분이다.



 public class UserDao {

private ConnectionMaker connectionMaker;

public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}

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

Connection c = connectionMaker.getConnection();

PreparedStatement ps = c.prepareStatement("select * from user where id = ?");
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 SQLException, ClassNotFoundException {

ConnectionMaker krkConnectionMaker = new KrkConnectionMaker();
UserDao dao = new UserDao(krkConnectionMaker);
User user = dao.select("oceanfog");

System.out.println(user.getName());
System.out.println(user.getId());
System.out.println(user.getPassword());

}

}



전역변수 connectionMaker에서 getConnection()을 호출하게 바꾸었다.




잘 작동 하는지 확인 해보자

ctrl + shift + f10을 눌러서 실행 해보자.




잘 돌아간다.




end.







댓글을 달아 주세요