Connection → DB 와의 연결 통로
PreparedStatement → SQL 을 DB 에 전달 (파라미터 바인딩, SQL 인젝션 방지)
ResultSet → SELECT 결과를 담는 그릇
저번에 배운 내용의 복습이다.
2단원에서 만든 shop DB 와 product 테이블을 그대로 사용합니다.
-- 테이블이 없다면 아래를 실행하세요
create database shop2;
USE shop2;
CREATE TABLE IF NOT EXISTS product2 (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
price INT NOT NULL,
stock INT DEFAULT 0,
description VARCHAR(200)
);
-- 기존 데이터 확인
SELECT * FROM product2;
INSERT 연습
package ch03;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ProductInsert {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/shop2?serverTimezone=Asia/Seoul";
String user = System.getenv("DB_USER");
String pwd = System.getenv("DB_PASSWORD");
// insert 쿼리 구문을 미리 Strin으로 만들어 두자
// 텍스트블록 문법 JDK 13이후 사용 가능
String sql = """
INSERT INTO product2(name, price, stock, description)
values( ? , ? , ? , ? )
""";
try (Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, "애플 에어팟 프로");
pstmt.setInt(2, 329000);
pstmt.setInt(3, 10);
pstmt.setString(4, "최신 무선 이어폰");
int rows = pstmt.executeUpdate();
System.out.println(rows + " 개의 상품이 추가 되었습니다.");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
pstmt.set으로 ?에 값을 넣는 모습이다.
pstmt.executeUpdate(); 이걸 사용하면 적용된 총 행수를 출력한다.
SELECT 연습 1
package ch03;
import java.sql.*;
public class ProductSelectAll {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/shop2?serverTimezone=Asia/Seoul";
String user = System.getenv("DB_USER");
String pwd = System.getenv("DB_PASSWORD");
// insert 쿼리 구문을 미리 Strin으로 만들어 두자
// 텍스트블록 문법 JDK 13이후 사용 가능
String sql = """
SELECT * FROM product2
""";
try (Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
ResultSet rs = pstmt.executeQuery();
System.out.println("== 전체 상품 목록 조회");
while (rs.next()) {
String output = """
ID: %3d | %-20s | %,7d원 | 재고 : %3d개
""".formatted(
rs.getInt("id"),
rs.getString("name"),
rs.getInt("price"),
rs.getInt("stock")
);
// 참고로 텍스트 블록 문법은 자동으로 \n이 들어가 있다.
System.out.print(output);
}
} catch (SQLException e) {
System.out.println("오류 : " + e.getMessage());
}
}
}
ResultSet rs = pstmt.executeQuery(); 이문은 int rows = pstmt.executeUpdate();
이거와 다르게 집합결과를 반환한다. 하지만 집합결과는 한줄씩 들고와야한다.
그래가지고 rs.next()로 한줄씩 들고오는 모습이다.
SELECT 연습 2
package ch03;
import java.sql.*;
public class ProductSelectByPrice {
public static void main(String[] args) {
// 상품이 1만원 ~ 10만원 사이의 상품을 출력 하시오
// shop DB 사용 product 테이블 사용
// 가격 오름차순 정렬
String url = "jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Seoul";
String user = System.getenv("DB_USER");
String pwd = System.getenv("DB_PASSWORD");
// insert 쿼리 구문을 미리 Strin으로 만들어 두자
// 텍스트블록 문법 JDK 13이후 사용 가능
int minPrice = 10000;
int maxPrice = 100000;
String sql = """
SELECT * FROM product WHERE price BETWEEN ? AND ? ORDER BY price ASC
""";
try (Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, minPrice);
pstmt.setInt(2, maxPrice);
ResultSet rs = pstmt.executeQuery();
int count = 0;
System.out.println("== 전체 상품 목록 조회");
while (rs.next()) {
count++;
String output = """
ID: %3d | %-20s | %,7d원 | 재고 : %3d개
""".formatted(
rs.getInt("id"),
rs.getString("name"),
rs.getInt("price"),
rs.getInt("stock")
);
// 참고로 텍스트 블록 문법은 자동으로 \n이 들어가 있다.
System.out.print(output);
}
System.out.println(count + " 행의 결과를 받았습니다");
} catch (SQLException e) {
System.out.println("오류 : " + e.getMessage());
}
}
}
Update 연습
package ch03;
import java.sql.*;
public class ProductUpdate {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/shop2?serverTimezone=Asia/Seoul";
String user = System.getenv("DB_USER");
String pwd = System.getenv("DB_PASSWORD");
// UPDATE - name, 가격을 수정하는 쿼리를 진행할 예정
// 텍스트블록 문법 JDK 13이후 사용 가능
String sql = """
update product2
set price = ?
where name = ?
""";
int newPrice = 500000;
String targetName = "애플 에어팟 프로";
try (Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, newPrice);
pstmt.setString(2, targetName);
System.out.println("== 상품 가격 수정 : 타켓상품 : " + targetName);
int rows = pstmt.executeUpdate();
if (rows > 0) {
System.out.println(rows + "개의 상품 가격이 수정되었습니다.");
} else {
System.out.println("수정할 상품을 찾지 못했습니다.");
}
} catch (SQLException e) {
System.out.println("오류 : " + e.getMessage());
}
}
}
setInt()를 쓸 수 있는 이유는 텍스트 블록이라서가 아니라, PreparedStatement의 ? 자리에 값을 바인딩하는 방식이기 때문이야.
텍스트 블록때문에 쓸 수 있는 줄 알았는데 텍스트 블록은 여러줄을 편하게 쓸 수있다.
원래는 \n을써서 한줄을 띄워적어야 하지만 텍스트 블록은 그냥 바로 띄어서 쓸 수 있다.
DELETE 연습
package ch03;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ProductDelete {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/shop2?serverTimezone=Asia/Seoul";
String user = System.getenv("DB_USER");
String pwd = System.getenv("DB_PASSWORD");
// UPDATE - name, 가격을 수정하는 쿼리를 진행할 예정
// 텍스트블록 문법 JDK 13이후 사용 가능
String sql = """
delete from product2 where id = ?
""";
int targetId = 2;
try (Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, targetId);
System.out.println("== 상품 가격 수정 : 타켓상품ID : " + targetId);
int rows = pstmt.executeUpdate();
if (rows > 0) {
System.out.println(rows + "개의 상품이 삭제 되었습니다.");
} else {
System.out.println("삭제할 상품을 찾지 못했습니다.");
}
} catch (SQLException e) {
System.out.println("오류 : " + e.getMessage());
}
}
}
setInt의 변수의 값을 넣고 있다. set을 할때는 java의 변수만 넣을 수 있다.
sql의 컬럼값을 넣는게 아니다.