INSERT로 인해 AUTO_INCREMENT된 PK중 최신값 얻기현재 세션(내 연결)에서 마지막으로 생성된 AUTO_INCREMENT 값만 반환됨
❌ 절대 max() 사용 금지: 모든 유저의 데이터 중 가장 큰 값이 반환되므로 안전하지 않음
사용 SQL: SELECT last_insert_id();
last_insert_id()는 세션 단위라서 다른 유저의 insert에 영향을 받지 않음
→ max()보다 안전
public int selectRecentPk() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int pk = 0; // 반환할 PK 값
con = dbManger.getConnection(); // DB 연결
StringBuffer sql = new StringBuffer();
// 현재 세션 기준 마지막 insert된 PK 조회
sql.append("select last_insert_id() as product_id");
try {
pstmt = con.prepareStatement(sql.toString());
rs = pstmt.executeQuery(); // 쿼리 실행
while (rs.next()) {
pk = rs.getInt("product_id"); // 조회된 PK 값 가져오기
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
dbManger.release(rs, pstmt);
}
return pk;
}
/*---------▼ ProductPage.java에서-----------------------------------------------*/
// ProductDAO에게 상품 insert 요청 (DB에 저장)
productDAO.insert(product);
// ✅ 방금 insert된 상품의 PK(primary key) 값 조회
int product_id = productDAO.selectRecentPk();
// ✅ 조회한 PK를 Product 객체에 다시 주입 (객체 상태 완성)
product.setProduct_id(product_id); // ★ 중요: DB와 객체 상태를 일치시킴 ★
왜 방금 insert된 상품의 PK를 Product 객체에 다시 주입할까?
DB에 저장된 실제 상품과 Java의 Product 객체가
동일한 실체임을 보장하려면,
last_insert_id()로 구한 최신 PK를
해당 객체(Product)에도 주입해야 한다.📌 이렇게 해야 이후 연관 작업(insert, update, delete 등)에서도
Product 객체를 DB와 연결된 진짜 데이터로 일관되게 활용할 수 있다.👉 즉, "이 객체 = 방금 DB에 저장된 상품" 으로써의 정체성이 확립된다.
모든 상품 목록 가져오기 ( 상위카테고리 + 하위카테고리 + 상품 JOIN )
public List<Product> selectAll() {
Connection con = dbManger.getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
// 배열 대신 List 사용 → ResultSet을 앞뒤로 이동할 필요 없음, 크기 미지정 가능
List<Product> list = new ArrayList<>();
StringBuffer sql = new StringBuffer();
// ✅ INNER JOIN을 이용한 3테이블 조인
// (topcategory ↔ subcategory ↔ product 순서로 연결)
// color, size, img는 상세보기에서 보여주기 때문에 여기서는 제외
sql.append("select ");
sql.append("t.topcategory_id, top_name, ");
sql.append("s.subcategory_id, sub_name, ");
sql.append("product_id, product_name, brand, price, discount, introduce, detail ");
sql.append("from topcategory t ");
sql.append("inner join subcategory s on t.topcategory_id = s.topcategory_id ");
sql.append("inner join product p on s.subcategory_id = p.subcategory_id");
try {
pstmt = con.prepareStatement(sql.toString());
rs = pstmt.executeQuery(); // 쿼리 실행
while (rs.next()) {
// 상품 객체 생성 및 값 주입
Product product = new Product();
product.setProduct_id(rs.getInt("product_id"));
product.setProduct_name(rs.getString("product_name"));
product.setBrand(rs.getString("brand"));
product.setPrice(rs.getInt("price"));
product.setDiscount(rs.getInt("discount"));
product.setIntroduce(rs.getString("introduce"));
product.setDetail(rs.getString("detail"));
// 하위카테고리 객체 생성
SubCategory subcategory = new SubCategory();
subcategory.setSubcategory_id(rs.getInt("subcategory_id")); // "s.subcategory_id" ❌ 아님
subcategory.setSub_name(rs.getString("sub_name"));
// 상위카테고리 객체 생성 → 하위카테고리에 주입
TopCategory topcategory = new TopCategory();
topcategory.setTopcategory_id(rs.getInt("topcategory_id")); // "t.topcategory_id" ❌ 아님
topcategory.setTop_name(rs.getString("top_name"));
subcategory.setTopCategory(topcategory);
// 상품에 하위카테고리 포함시켜 연관관계 구성
product.setSubcategory(subcategory);
// 리스트에 추가
list.add(product);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
dbManger.release(rs, pstmt);
}
return list;
}
| JOIN 종류 | 의미 | 누락 시 처리 방식 |
|---|---|---|
| INNER JOIN | 공통 데이터만 조회 | 매칭 안 되면 제외 |
| LEFT OUTER JOIN | 왼쪽 테이블 전부 + 매칭 | 오른쪽 NULL 채움 |
| RIGHT OUTER JOIN | 오른쪽 테이블 전부 + 매칭 | 왼쪽 NULL 채움 |