TIL 2021.05.17 [Spring/JdbcTemplate]

kyukim·2021년 5월 17일
0

TIL

목록 보기
127/279

JDBC Template

DAO란?

Data Access Object. 데이터베이스의 데이터에 접근하기 위해 생성하는 객체.

DAO는 그럼 Entity랑 다른 점은 무엇인가

Entity는 테이블과 1:1 매칭되는 객체.
DAO는 직접적으로 데이터를 읽고 쓰는 등 디비와 상호작용이 일어나는 객체. Spring Boot에서는 Repository가 이를 대신했다.

JdbcTemplate을 배우니까 느낀게 지금까지 Spring Data JDBC에서 썼던 Entity 클래스들은 위에서 정의한대로 단순히 테이블과 1:1 매칭되는 객체였다.

처음에는 Entity가 어노테이션에 의해서 자동으로 디비와 상호작용하는 건 줄 알았는데, 엄밀히 말하면 Repository와 상호작용하는 것이었다. 그런데 Spring Data JDBC를 쓰지 않고 Spring JDBC를 쓴다면 Repository를 직접 구현해야한다. 이때, DAO를 생성해주는 거다.

DAO VS Repository

  • DDD에서 나온 컨셉이 Repository
  • 개념적 차이: 레포지토리는 Aggregate root 에서 나온 것, DAO는 테이블 단위에서 나온 것

CRUD

insert

	@Test
	@DisplayName("쿼리 안에 직접 데이터를 적어서 insert 확인")
	void insert() {
		String query = "INSERT INTO user Values(null, 'kyu', 'kim')";
		int updated = this.jdbcTemplate.update(query);
		assertThat(updated).isEqualTo(1);
	}

	@Test
	@DisplayName("쿼리에 데이터를 주입하고 insert 확인")
	void insertWithPreparedStatement() {
		String query = "INSERT INTO user Values(?, ?, ?)";
		int updated = this.jdbcTemplate.update(query, null, "kyu", "kim");
		assertThat(updated).isEqualTo(1);
	}

null로 주는건 id가 auto_increment인데 insert할때 null로 줘야 수동으로 pk를 삽입안해도 되는 것 같다.
자세한 건 더 알아봐야 함.

retrive

특정한 객체 타입을 찾으려면 그에 맞는 mapper가 있어야한다.

그리고, 찾는 것이 하나의 객체이냐 하나의 컬럼의 데이터냐 여러개의 컬럼의 데이터냐에 따라 하는방법이 다르다.

object

먼저, Entity 하나 생성해준다.

public class User {
	private Long id;
	prviate String name;

	// getter and setter
}

그리고 Mapper를 생성해준다.

public class UserMapper implements RowMapper<User> {

    @Override
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        User employee = new User();
        employee.setId(rs.getLong("id"));
        employee.setFirstName(rs.getString("first_name"));
        employee.setLastName(rs.getString("last_name"));
        return employee;
    }
}

예를 들어서 findById를 구현하고 싶다면 UserDao에 이런 메서드를 생성해주면 된다

    public User findById(Long id) {
        String sql = "SELECT * FROM user WHERE id = ?";
        UserMapper userMapper = new UserMapper();

        return jdbcTemplate.queryForObject(sql, new Object[]{id}, userMapper);
    }

아니면 Mapper를 바로 메서드안에다가 생성해줄 수도 있다.

    public User findById(Long id) {
        String sql = "SELECT * FROM user WHERE id = ?";

        RowMapper<User> userMapper = new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet rs, int rowNum) throws SQLException {
                User user = new User();
                user.setId(rs.getLong("id"));
                user.setFirstName(rs.getString("first_name"));
                user.setLastName(rs.getString("last_name"));
                return user;
            }
        };

        return jdbcTemplate.queryForObject(sql, new Object[]{id}, userMapper);
    }

근데 Mapper를 일회용으로 쓰진 않을거기 때문에 역시 따로 클래스로 빼주는게 좋을듯하다.

profile
제 생각이 담긴 블로그입니다

2개의 댓글

comment-user-thumbnail
2021년 5월 18일

오 큐~ JdbcTemplate 잘 정리하셨네요ㅎㅎㅎ 매일 til 잘 읽고있는데 오랜만에 댓글 남겨봅니다😆

1개의 답글