DataBase
[H2 DB] insert시 auto increment인 sequence 값을 바로 받아 오는 법
bkuk
2023. 3. 28. 09:49
DAO 메서드
지금까지 DAO(Data Access Object) 클래스의 메서드를 아래와 같이 설계해왔다.
public void insert( Ans ans ) { ... }
public Ans select(String answerId ) { ... }
public List<Ans> selectAll(String questionId) { ... }
테이블 구조
DTO(Data Transfer Object) 클래스인 Ans의 테이블 구조는 아래와 같다.
CREATE TABLE ANSWERS (
answerId bigint auto_increment,
writer varchar(30) NOT NULL,
contents varchar(5000) NOT NULL,
createdDate timestamp NOT NULL,
questionId bigint NOT NULL,
PRIMARY KEY (answerId)
);
사용 컨트롤러
이를 사용하는 컨트롤러(Controller)를 살펴보자.
Ans 객체를 생성 후, AnsDao 클래스를 통해 DB에 접근해 insert를 진행한 것을 볼 수 있다.
public class CreateAnsController implements Controller {
@Override
public String execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
[..생략..]
Ans ans = new Ans(
user.getUserId(),
req.getParameter("contents"),
req.getParameter("questionId") );
AnsDao ansDao = new AnsDao();
ansDao.insert(ans);
return "redirect:/";
}
}
기존 insert 메서드()
Dao 클래스의 insert 메서드는 아래와 같다.
여기서 컬럼 answerId에 대해서는 auto increment 속성을 부여함으로써, DB에 insert 된 후 select 하기 전까지는 알 수 없다.
public void insert( Ans ans ) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
String sql = "INSERT INTO ANSWERS (writer, contents, createdDate, questionId) VALUES (?, ?, now(), ?)";
jdbcTemplate.update(
sql,
ans.getWriter(),
ans.getContents(),
ans.getQuestionId()
);
}
변경 insert 메서드()
하지만, 여기서 ResultSet을 통해 해당 값을 가져올 수 있다.
public void update(PreparedStatementCreator psc, KeyHolder holder) {
try (Connection conn = ConnectionManager.getConnection()) {
PreparedStatement ps = psc.createPreparedStatement(conn);
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
holder.setId(rs.getLong(1));
}
rs.close();
} catch (SQLException e) {
throw new DataAccessException(e);
}
}
추가 DTO 클래스(Key Holder 클래스)
위를 보면 알 수 있듯이, KeyHolder라는 클래스를 파라미터로 갖는 메서드로 확인할 수 있다.
해당 클래스 구조는 아래와 같다.
package next.model;
public class Result {
private boolean status;
private String message;
private Result(boolean status) {
this(status, "");
}
private Result(boolean status, String message) {
this.status = status;
this.message = message;
}
public static Result ok() {
return new Result(true);
}
public static Result fail(String message) {
return new Result(false, message);
}
public boolean isStatus() {
return status;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "Result [status=" + status + ", message=" + message + "]";
}
}