진취적 삶
8.4 JdbcTemplate 을 이용한 쿼리 실행 본문
8.4.1 JdbcTemplate 생성
public class AppCtx {
@Bean(destroyMethod = "close")
public DataSource dataSource(){
DataSource ds = new DataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost/spring5fs?characterEncoding=utf8");
ds.setUsername("spring5");
ds.setPassword("spring5");
ds.setInitialSize(2);
ds.setMaxActive(10);
ds.setTestWhileIdle(true);
ds.setMinEvictableIdleTimeMillis(1000*60*3); //3분
ds.setTimeBetweenEvictionRunsMillis(1000*10);
return ds;
}
@Bean
public MemberDao memberDao() {
return new MemberDao(dataSource());
}
...
}
8.4.2 JdbcTemplate 을 이용한 조회 쿼리 실행
jdbcTemplate 클래스는 SELECT 쿼리 실행을 위한 query() 메서드 제공
query() 메서드는 sql 파라미터로 전달받은 쿼리를 실행하고 RowMapper를 이용해서
ResultSet 의 결과를 자바 객체로 변환
public Member selectByEmail(String email ) {
List<Member> results = jdbcTemplate.query(
"select * from MEMBER where EMAIL = ?",
new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet rs,int rowNum) throws SQLException{
Member member = new Member(
rs.getString("EMAIL"),
rs.getString("PASSWORD"),
rs.getString("NAME"),
rs.getTimestamp("REGDATE").toLocalDateTime());
member.setId(rs.getLong("ID"));
return member;
}
},
email);
return results.isEmpty() ? null :results.get(0);
}
메소드 뽑아내서 중복 방지
private JdbcTemplate jdbcTemplate;
public class MemberRowMapper implements RowMapper<Member>{
@Override
public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
Member member = new Member(
rs.getString("EMAIL"),
rs.getString("PASSWORD"),
rs.getString("NAME"),
rs.getTimestamp("REGDATE").toLocalDateTime());
member.setId(rs.getLong("ID"));
return member;
}
}
public MemberDao(DataSource dataSource) {
this.jdbcTemplate= new JdbcTemplate(dataSource);
}
public Member selectByEmail(String email ) {
List<Member> results = jdbcTemplate.query(
"select * from MEMBER where EMAIL = ?",
new MemberRowMapper(),email);
return results.isEmpty() ? null :results.get(0);
}
public Collection<Member> selectAll(){
List<Member> results = jdbcTemplate.query(
"select * from MEMBER",
new MemberRowMapper());
return results;
}
8.4.3 결과가 1행인경우 사용
public int count() {
Integer count = jdbcTemplate.queryForObject(
"select count(*) from MEMBER", Integer.class);
return count;
}
queryForObject () 메서드는 쿼리 실행 결과 행이 한 개인 경우에 사용할수 있는 메서드
결과 행이 한개가 아니라면 query() 메서드를 사용해야 한다.
8.4.4 JdbcTemplate 을 이용한 변경 쿼리 실행
INSERT , UPDATE ,DELETE 쿼리는 update() 메서드 사용
public void update(Member member) {
jdbcTemplate.update(
"update MEMBER set NAME = ?, PASSWORD = ? where EMAIL = ?",
member.getName(), member.getPassword(), member.getEmail()
);
}
8.4.5 PreparedStatementCreator를 이용한 쿼리 실행
public void insert(Member member) {
KeyHolder keyHolder =new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement pstmt = con.prepareStatement(
"insert into MEMBER (EMAIL,PASSWORD,NAME,REGDATE)"+
"values(?,?,?,?",new String[] {"ID"});
pstmt.setString(1, member.getEmail());
pstmt.setString(2, member.getPassword());
pstmt.setString(3, member.getName());
pstmt.setTimestamp(4, Timestamp.valueOf(member.getRegisterDateTime()));
return pstmt;
}
},keyHolder);
Number keyValue = keyHolder.getKey();
member.setId(keyValue.longValue());
}
KeyHolder keyHolder =new GeneratedKeyHolder() → 자동 생성된 키값을 구해주는 KeyHolder구현 클래스
update 메서드는 PreparedStatementCreator,keyHolder 를 파라미터로 갖는다.
8.4.5 INSERT 쿼리 실행시 KeyHolder를 이용해서 자동 생성 키 값 구하기
AUTO_INCREMENT와 같은 자동 증가 칼럼을 가진 테이블에 값을 삽입하면 해당 칼럼의 값이
자동으로 생성된다 update() 메서드는 변경된 행의 개수를 리턴할뿐 생성된 키값을 리턴하지는 않는다.
그래서 KeyHolder를 사용
public void insert(Member member) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update((Connection con) -> {
PreparedStatement pstmt = con.prepareStatement(
"INSERT INTO MEMBER (EMAIL, PASSWORD, NAME, REGDATE) VALUES (?, ?, ?, ?)",
new String[] { "ID" }
);
pstmt.setString(1, member.getEmail());
pstmt.setString(2, member.getPassword());
pstmt.setString(3, member.getName());
pstmt.setTimestamp(4, Timestamp.valueOf(member.getRegisterDateTime()));
return pstmt;
}, keyHolder);
Number keyValue = keyHolder.getKey();
member.setId(keyValue.longValue());
}
람다식 사용
'스프링 5 프로그래밍 입문 > 8.DB 연동' 카테고리의 다른 글
8.2 프로젝트 준비 (0) | 2023.09.11 |
---|---|
8.3 DataSource 설정 (0) | 2023.09.11 |
8.5 MemberDao 테스트하기 (0) | 2023.09.11 |
8.6 스프링의 익셉션 변환 처리 (0) | 2023.09.11 |
8.7 트랜잭션 처리 (0) | 2023.09.11 |