나중엔 JPA나 MyBatis 배우면 이걸 쓸 예정
JDBC란?
자바에서 데이터베이스에 접근할 수 있게 해주는 Java의 Library로 실제 DB 접근하기 위해선 벤더 사 별로 다른 JDBC Driver(.jar 파일)를 활용하고, Java에선 JDBC Interface를 통해 동일한 코드로 각기 다른 DB를 접근 할 수 있는 Interface
MySQL에서 제공하는 Java-DB간 연결을 위한
Connect j를 다운받아 적용하고 (Mysql 홈페이지 회원가입 필요)
프로젝트 properties에 해당 라이브러리를 추가해주면 된다.
DB연동시 한글이 깨지기도 하니 미리 이클립스 인코딩을 UTF-8로 맞춰주자
JDBC 사용 객체
Class.forName()
문자열 형태로 전달된 클래스를 JVM으로 로드해주는 기능
ex)
Class.forName(“com.mysql.cj.jdbc.Driver”);
DriverManager
JDBC드라이버를 통하여 Connection을 만드는 역할
직접 객체 생성이 불가능하고 getConnection() 메소드를 사용하여 객체 생성 가능
ex)
DriverManager.getConnection(“JDBC형식 URL”, ”계정”, ”비밀번호”);
JDBC 형식 URL
jdbc:oracle:thin:[hostname][:port]:dbname
ex)
jdbc:mysql://localhost:3306/jdbc
Connection
특정 데이터 원본과 연결된 Connection(연결상태), Connection객체의 createStatement() 메소드를 호출하여
Statement객체를 생성 필요 SQL문장을 실행시키기 전에 우선 Connection 객체가 있어야 함
<Connection 객체명>. createStatement();
객체 사용 완료 후 반드시 닫아 줘야 함
<Connection 객체명>.close();
Statement
데이터베이스 연결을 한 후 실제 SQL문을 수행하기 위한 객체 Connection클래스의 createStatement() 메소드를
호출하여 생성됨 생성된 Statement객체로 질의문장을 String객체에 담아 인자로 전달
executeQuery(),executeUpdate() 메소드를 호출하여 SQL 질의 수행
<Statement 객체명>.executeQuery() <Statement 객체명>.executeUpdate()
객체 사용 완료 후 반드시 닫아 줘야 함
<Statement 객체명>.close();
executeQuery()메소드
ResultSet을 반환하는 SQL 문에 사용하는 메소드로 주로 SELECT문을 이용하는 조회에 사용
executeUpdate() 메소드
SELECT를 제외한 DML(INSERT, UPDATE, DELETE)과 DDL(CREATE, DROP, ALTER)구문을 수행하기 위한 메소드로 DML을 수행한 경우 영향 받은 행의 수를 반환하고, DDL을 수행한 경우 0을 반환
PreparedStatement
데이터베이스 연결을 한 후 실제 SQL문을 수행하기 위한 객체 Connection클래스의 prepareStatement() 메소드를 호출하여 생성됨 SQL문장이 미리 컴파일 되고 실행 시간 동안 인수 값을 위한 공간을 확보한다는 점에서 Statement와 다름 각 인수에 대해 위치 홀더(?)를 사용해 SQL문장을 정의할 수 있게 함
String 빌더나 API로 대체는 가능하지만... 이걸 쓰면 동적으로 데이터를 처리하기 쉬워짐
위치 홀더(?)
SQL문장에 나타나는 토큰으로 SQL구문이 실행되기 전에 실제 값으로 대체되어야 함
ex)
<PreparedStatement객체명>.setString(위치,값)
ex2)
try{
String query = “INSERT INTO MEMBER VALUES(?, ?)”;
pstmt = conn.prepareStatement(query);
pstmt.setString(1, id);
pstmt.setString(2, password);
pstmt.excuteUpdate();
} catch(SQLException e){
e.printStackTrace();
}
ResultSet
SELECT문을 사용한 질의 성공 시 반환되는 객체로 실제 질의에 대한 결과를 조회 가능, Statement로 SQL질의에 의해 생성된 테이블을 담아서 사용하며 커서(cursor)로 특정 행에 대한 참조를 조작, 만일 Result row의 결과가 0인 경우 조회 될 수 없음
< ResultSet객체명 >.next();
커서가 위치한 행의 데이터 사용
< ResultSet객체명 >.getString(<컬럼명|인덱스>);
객체 사용 완료 후 반드시 닫아 줘야 함
< ResultSet객체명 >.close();
예시코드
[Member.java]
package com.multi.ex02.preparedstatement;
import java.util.Date;
public class Member {
int no;
String id;
String pwd;
String name;
String gender;
int age;
String email;
String phone;
String address;
String hobby;
Date birthday;
Date enrolldate;
@Override
public String toString() {
return "Member [no=" + no + ", id=" + id + ", pwd=" + pwd + ", name=" + name + ", gender=" + gender + ", age="
+ age + ", email=" + email + ", phone=" + phone + ", address=" + address + ", hobby=" + hobby
+ ", birthday=" + birthday + ", enrolldate=" + enrolldate + "]";
}
public Member() {
super();
}
public Member(int no, String id, String pwd, String name, String gender, int age, String email, String phone,
String address, String hobby, Date birthday, Date enrolldate) {
super();
this.no = no;
this.id = id;
this.pwd = pwd;
this.name = name;
this.gender = gender;
this.age = age;
this.email = email;
this.phone = phone;
this.address = address;
this.hobby = hobby;
this.birthday = birthday;
this.enrolldate = enrolldate;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getEnrolldate() {
return enrolldate;
}
public void setEnrolldate(Date enrolldate) {
this.enrolldate = enrolldate;
}
}
[PreparedStatementBasic.java]
package com.multi.ex02.preparedstatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class PreparedStatementBasic {
public static Connection conn = null;
public static PreparedStatement pstmt = null; // ★★★★★
public static ResultSet rs = null;
public static String driverClass = "com.mysql.cj.jdbc.Driver";
public static String url = "jdbc:mysql://localhost:3306/jdbc";
public static String user = "user";
public static String password = "1234";
public static void main(String[] args) {
try {
Class.forName(driverClass);
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);
List<Member> list = selectAll();
print(list);
System.out.println("select one 호출");
String id = "user1";
Member m = selectOne(id);
System.out.println(m);
System.out.println("select one 끝");
// 회원가입 할 멤버 생성
Calendar c = Calendar.getInstance();
c.set(2000, 10, 9); // 2000년 '11'월 9일생
m = new Member(0, "test6", "1234","이길동","M", 26, "lee@test.com",
"01012345678","서울시 강남구", "야구", c.getTime(), null);
insert(m);
list = selectAll();
print(list);
update(m.getId(), "김길동");
list = selectAll();
print(list);
delete(m.getId());
list = selectAll();
print(list);
// conn.commit(); // 수동으로 commit 명령을 내리는 방법
conn.rollback(); // commit 이후에 실행된 명령을 모두 돌리는 코드
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(rs != null && rs.isClosed() == false) {
rs.close();
}
if(pstmt != null && pstmt.isClosed() == false) {
pstmt.close();
}
if(conn != null && conn.isClosed() == false) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
private static void print(List<Member> list) {
System.out.println("------------------ MEMBER -----------------------");
list.forEach((v) -> System.out.println(v));
System.out.println("-------------------------------------------------\n");
}
public static List<Member> selectAll() throws SQLException {
String sql = "SELECT * FROM MEMBER";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
List<Member> list = new ArrayList<>();
while(rs.next()) {
int no = rs.getInt("mno"); // 컬럼명으로 맞춰서 가져와야한다!
String id = rs.getString("id");
String pwd = rs.getString("password"); // pwd -> password 맵핑 필요!
String name = rs.getString("name");
String gender = rs.getString("gender");
int age = rs.getInt("age");
String email = rs.getString("email");
String phone = rs.getString("phone");
String address = rs.getString("address");
String hobby = rs.getString("hobby");
Date birthday = rs.getDate("birthday");
Date enrolldate = rs.getTimestamp("enrolldate"); // 시간 + 날짜
Member m = new Member(no, id, pwd, name, gender, age, email, phone, address, hobby, birthday, enrolldate);
list.add(m);
}
pstmt.close();
rs.close();
return list;
}
private static Member selectOne(String memberId) throws SQLException {
// PreparedStatement 사용방법 정리
// 1. 반만 완성된 쿼리를 작성, '?'를 통해 나중에 문자열이 주입될 부분을 채워야한다.
String sql = "SELECT * FROM MEMBER WHERE ID = ? ORDER BY ? DESC";
pstmt = conn.prepareStatement(sql); // 쿼리가 준비된 상태로, 현재까지는 DB의 요청하지 않음!
// 2. ?를 사용자의 입력으로 변경 ※ 주의 : DB index는 1부터 시작한다.
pstmt.setString(1, memberId); // 첫번째 ?를 사용자 id로 교체
pstmt.setString(2, "name"); // 두번째 ?자를 "name"으로 교체
// 3. 실행
// pstmt.executeQuery(sql); // 금지!! 기존에 셋팅한 sql, setString의 정보가 초기화됨!
rs = pstmt.executeQuery(); // 옳은 방법!
Member m = null;
if(rs.next()) {
// select *로 가져오는 경우, 컬럼의 선언 순번대로 가져옵니다.
int count = 1;
int no = rs.getInt(count++);
String id = rs.getString(count++);
String pwd = rs.getString(count++);
String name = rs.getString(count++);
String gender = rs.getString(count++);
int age = rs.getInt(count++);
String email = rs.getString(count++);
String phone = rs.getString(count++);
String address = rs.getString(count++);
String hobby = rs.getString(count++);
Date birthday = rs.getDate(count++);
Date enrolldate = rs.getTimestamp(count++);
m = new Member(no, id, pwd, name, gender, age, email, phone, address, hobby, birthday, enrolldate);
}
pstmt.close();
rs.close();
return m;
}
private static void insert(Member m) throws SQLException {
System.out.println("Insert 시작!");
String sql = "INSERT INTO MEMBER VALUES(default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, default)";
pstmt = conn.prepareStatement(sql);
// int count = 1; // count 활용해도 된다!
pstmt.setString(1, m.getId());
pstmt.setString(2, m.getPwd());
pstmt.setString(3, m.getName());
pstmt.setString(4, m.getGender());
pstmt.setInt(5, m.getAge());
pstmt.setString(6, m.getEmail());
pstmt.setString(7, m.getPhone());
pstmt.setString(8, m.getAddress());
pstmt.setString(9, m.getHobby());
pstmt.setDate(10, new java.sql.Date(m.getBirthday().getTime()));
int result = pstmt.executeUpdate();
if(result > 0 ) {
System.out.println("insert 성공");
} else {
System.out.println("insert 실패");
}
System.out.println("Insert 종료\n");
}
private static void update(String id, String name) throws SQLException {
System.out.println("Update 시작!!");
String sql = "update member set name = ? where id = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, id);
int result = pstmt.executeUpdate();
if(result > 0) { // 0보다 커야 성공!
System.out.println("Update 성공!");
} else {
System.out.println("Update 실패.");
}
System.out.println("Update 종료\n");
}
private static void delete(String id) throws SQLException {
System.out.println("delete 시작!!");
String sql = "delete from member where id = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
int result = pstmt.executeUpdate();
if(result > 0) { // 0보다 커야 성공!
System.out.println("delete 성공!");
} else {
System.out.println("delete 실패.");
}
System.out.println("delete 종료\n");
}
}
'자바' 카테고리의 다른 글
제네릭 (0) | 2023.12.19 |
---|---|
[Java] JDBC MVC (0) | 2023.11.30 |
[Java] I/O 입출력 (0) | 2023.11.23 |
[Java] Collections - Map (0) | 2023.11.23 |
[Java] Collections - List (0) | 2023.11.22 |