먼저, 테이블 만들어야 함.
기존에 h2에 member 테이블은 만들었었음. 그걸로 함.
먼저 DB에 들어갈 객체를 만들어 놓음
@Data
public class Member {
private String memberId;
private int money;
public Member() {
}
public Member(String memberId, int money) {
this.memberId = memberId;
this.money = money;
}
}
그 다음 Repository라는 디렉토리를 만듦. 리포지토리가 DB와 소통하는 친구임.
@Slf4j
public class MemberRepositoryV0 {
public Member save(Member member) throws SQLException {
String sql = "insert into member(member_id, money) values(?,?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
return member;
}catch (SQLException e){
log.error("db error = {}",e);
throw e;
}finally {
close(con,pstmt, null);
}
}
private void close(Connection con, Statement stmt, ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
log.info("error", e);
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
log.info("error",e);
}
}
if(con != null){
try {
con.close();
} catch (SQLException e) {
log.info("error",e);
}
}
}
private Connection getConnection(){
return DBConnectionUtil.getConnection();
}
}
save 먼저 만들어 봄.
쿼리를 만듦. 저렇게 ?, ? 물음표의 순서에 바인딩 할 수 있음.
커넥션 얻고, (아마 나중에는 저것도 생성자 주입 받을 듯.)
PreparedStatement가 Statement의 자손인데, 바인딩 기능까지 추가된 거임. values(" + member.getMemberId + "," 이런 식은 인젝션 공격에 취약할 수 있다고 함.
PreparedStatement 써서 바인딩 하는 게 안전하다고 함.
먼저 커넥션부터 얻고,(커넥션은 그냥 우리가 만들었던 커넥션 유틸 사용.) 그 다음 그 커넥션으로부터 PreparedStatement를 가져오는 거임. 대문 열고, 소문 들어간 느낌.
가져오면서 저렇게 con.preparedStatement(sql) 해 주면 sql 정보가 들어간 PreparedStatement를 반환해 주고,
preparedStatement.setString(인덱스, 값)
인데 우선은 저 setString, setInt() 등 여러가지 지원함.심지어 오브젝트 까지 지원함.
참고로 인덱스는 1번부터 시작임.
이 인덱스는 몇번째 ?이냐임.
테이블에 정의해 뒀던 타입대로 잘 넣어 주고,
preparedStatement.excuteUpdate() 로 업데이트를 실행함. 이 순간이 쿼리를 DB에 날려 DB가 그걸 받고 쿼리를 실행하는 거임.
여기선 Exception이 터져도 딱히 할 수 있는게 없다. 그냥 로그로 남긴다.
close는 들어갈 때 대문, 소문열고 들어갔으니, 나갈때는 역순으로 소문, 대문닫고 나가야 함.
안 닫으면 계속 연결상태로 있을 수 있음. 누수의 한 종류임. 그래서 try하든 catch 하든 무조건 실행하는 finally에서 닫음.
close도 괜히 Exception 터져서 뒤엣것들 못닫게 하지 않기 위해 다 try catch로 처리 함.
public class MemberRepositoryV0Test {
MemberRepositoryV0 repository = new MemberRepositoryV0();
@Test
public void crud() throws SQLException {
Member member = new Member("spring",13000);
Member savedMember = repository.save(member);
}
}
테스트.
repository.save(객체) DB에 잘 들어감.
'스프링 > 5. 스프링 DB-1' 카테고리의 다른 글
7. 수정, 삭제 (0) | 2023.09.28 |
---|---|
6. 조회 (0) | 2023.09.27 |
4. DB에 연결 (0) | 2023.09.26 |
3. JDBC 최신기술 (0) | 2023.09.26 |
2. JDBC (0) | 2023.09.26 |