Spring으로 DB 다루기

강서진·2024년 1월 4일
0

Spring

목록 보기
7/18
post-custom-banner

두번째 필수강의 ch3. 14강

Spring으로 DB에 정보를 저장하고 수정해보는 작업을 하기 위해 User 모델을 생성한다. user_info 테이블과 동일한 멤버변수들을 가지고, getter, setter, 생성자, toString, equals와 hashcode 메서드들을 가진다.

public class User {
    private String id;
    private String pwd;
    private String name;
    private String email;
    private Date birth;
    private String sns;
    private Date reg_date;
    
    ...

Test 클래스에 그대로 insert 메서드를 만든다. 먼저 Connection 객체를 만들고, PreparedStatement를 사용해 sql문을 작성해준다. 이 때 sql문을 전부 string에 저장하는 것이 아니라, 입력받을 값 부분은 ?로 표시하고, PreparedStatement의 setter들을 사용하여 매개변수로 받은 객체에서 정보값을 받아온다.

sql문을 그대로 작성했던 Statement와 달리 PreparedStatement는 SQL Injection 공격을 방어할 수 있고, 쌍따옴표와 따옴표를 사용할 필요가 없어 훨씬 가독성이 좋다. 또, 재사용성이 개선되어 성능이 올라간다는 장점이 있다.

	public int insertUser(User user) throws Exception{
        Connection conn = ds.getConnection();

//        String sql = "insert into user_info values ('asdf', '1111', 'kim', 'aaa@aaa.com', '2022-12-02', 'twitter', now())";
        String sql = "insert into user_info values (?,?,?,?,?,?,now())";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setString(1, user.getId());
        preparedStatement.setString(2, user.getPwd());
        preparedStatement.setString(3,user.getName());
        preparedStatement.setString(4, user.getEmail());
        preparedStatement.setDate(5, new java.sql.Date(user.getBirth().getTime()));
        preparedStatement.setString(6,user.getSns());

        int rowCount = preparedStatement.executeUpdate(); // insert, delete, update에 사용
        
        return rowCount;
    }

따로 예외를 try-catch 문으로 잡거나 connection을 닫는 작업까지는 포함하지 않았다.

다음으로 insertUser를 테스트하는 메서드를 작성한다.

	@Test
    public void testInsertUser() throws Exception{
        User user = new User("asdf", "1111","kim","aaa@aaa.com",new Date(),"twitter",new Date());
        int rowCount = insertUser(user);

        assertTrue(rowCount==1);
    }

테스트를 순조롭게 통과한 것을 볼 수 있다.

실제로 테이블에도 잘 저장되었다.


테이블에 저장된 데이터를 전부 지우는 deleteAll도 만들어본다.

	public void deleteAll() throws Exception{
        Connection conn = ds.getConnection();
        String sql = "delete from user_info ";

        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        preparedStatement.executeUpdate();
    }

이 deleteAll을 testInsertUser에 넣어, 같은 user 객체를 계속 입력했을 때 테스트가 통과하는지를 통해 deleteAll 메서드가 잘 작동하는지 확인할 수 있다.
연속으로 user 객체를 수정하지 않고 테스트를 돌려도 통과하는 것을 통해 deleteAll이 잘 작동하는 것을 확인하였다.


다음으로 selectUser를 만들어본다.
Select 쿼리는 excuteUpdate가 아닌 executeQuery를 사용한다.

	public User selectUser(String id) throws Exception{
        Connection conn = ds.getConnection();
        String sql = "select * from user_info where id= ? ";

        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setString(1,id);
        ResultSet resultSet = preparedStatement.executeQuery();

        if(resultSet.next()){
            User user = new User();
            user.setId(resultSet.getString(1));
            user.setPwd(resultSet.getString(2));
            user.setName(resultSet.getString(3));
            user.setEmail(resultSet.getString(4));
            user.setBirth(new Date(resultSet.getDate(5).getTime()));
            user.setSns(resultSet.getString(6));
            user.setReg_date(new Date(resultSet.getTimestamp(7).getTime()));
            return user;
        }
        return null;
    }

Primary Key인 id를 받아 일치하는 id를 가진 row를 ResultSet으로 전달한다. ResultSet에 내용이 있으면 User 객체에 정보값을 set하여 해당 user 객체를 반환하고, 없으면 null을 반환한다.

	@Test
    public void testSelectUser() throws Exception{
        User user = selectUser("asdf");

        assertTrue(user.getId().equals("asdf"));
    }

테스트 클래스 내부에 있는 DataSource ds는 인스턴스 변수로, 클래스 내부의 인스턴스 매서드들은 해당 인스턴스를 공유할 수 있다. 그러나 JUnit은 메서드 하나하나를 별도의 객체에서 실행을 시키기 때문에 테스트 메서드들은 같은 ds를 공유하지 않는다.

"asdf" 아이디를 가진 User 객체를 select하고, 그 user의 id가 "asdf"와 일치하는지 테스트를 돌려본다.
그런데 db에 "asdf"라는 id의 user가 없으면 테스트는 실패한다. 따라서 deleteAll을 진행하고, insertUser로 "asdf" user를 입력한 다음 selectUser를 실행해보도록 한다.

@Test
    public void testSelectUser() throws Exception{
        deleteAll();
        insertUser(new User(
        	"asdf", "1111","kim","aaa@aaa.com",new Date(),"twitter",new Date()));
        User user = selectUser("asdf");

        assertTrue(user.getId().equals("asdf"));
    }


테스트가 성공한 것을 확인할 수 있었다.


post-custom-banner

0개의 댓글