KH

230320 (JDBC)

十月 2023. 3. 20. 09:54

 
MVC 패턴

// eclipse 내 했던 과제를 보면 알 수 있다.

 

M model

:: 데이터와 관련된 부분
// model.vo , model.dao
 vo (데이터 임시저장공간) : 변수, 클래스에 관련 // 기능에 관련된 것 말고 데이터 저장 용
비즈니스 로직

dao (데이터와 직접 교류 / DB랑 연결) : Stream // 데이터를 쓰고 읽는.. (입출력 클래스) 

service : dao를 보조하는 역할 // (Controller ⇔ service ⇔ dao)
 

V view

:: 눈에 보이는 화면
println처럼 화면(출력)에 출력하는 것
 

C controller

1. model-view 연결 (데이터 전달, 전달받기)
 view에서 받아온 값을 controller를 거쳐 model에게 전달
2. 결과 값을 가지고 어느 페이지에 연결할 지,
 어떤 view로 나타낼 지의 결정권은 controller에 있음
 
View 에서 View로 넘어갈 때도 Controller를 거치도록 하자.

 

run / (model)vo, dao, service / view / controller / JDBCTemplate
 


〈JDBC〉 

// 짜여져 있는 틀이 분명함
 

+)

DB까지 접근할 수 있는 길을 Connection이라 한다.

 

Connection.createStatement() : Statement 객체 반환

Connection.preparedStatement() : PreparedStatement 객체 반환
 
▽ DB와 Query를 전달하는 클래스는 (우체부)
statement → CreateStatement()
preparedStatement → prepareStatement()
 
*Statement, PreparedStatement의 차이

· CreateStatement : 쿼리에 모든 값이 완벽히 채워져 있을 때 (완전)

 ≫ 완전해서 중간에 값을 채워넣을 필요 없고, 매개변수로 query를 받지 않음!
 ≫ 어차피 완성되어 있는 것이라 최종적으로 보내기만 하면 됨
· PreparedStatement : 모든 값이 완벽히 채워져있지 않을 때 (불완전) ex) ? (위치홀더 쓸 때?)
 ≫ 비워진 곳을 채워야 하니 매개변수로 query를 먼저 받아줘야 함.
 ≫ 객체 만들 때부터 쿼리를 전달 ▼

PreparedStatement pstmt = conn.prepareStatement(query);

 
▼ 하지만 쿼리를 실제로 전달해주는 메소드는
① DQL
(SELECT 문을 DB에 전달하려면)
excuteQuery() 메소드 이용
그러면 Result Set 반환
② DML
(INSERT UPDATE DELETE는)
excuteUpdate() 메소드 이용

 
 결과에 대한 으로는
DQL / Select, excuteQuery()에 대한 반환 값은 ResultSet
DML / excuteUpdate()에 대한 반환 값은 int일 것. (행 수)

 

*하지만 SELECT COUNT(*) FROM EMP; 인 경우

개수(int)가 반환되기 때문에 ResultSet이 int가 된다.

(이런 여러 경우의 수가 있다는 것 알아야 함)

 

또한 SELECT는 괜찮지만, 

DML(INSERT, UPDATE, DELETE)는 DB를 수정하는 것이기 때문에

꼭 확정(Commit)지어주어야 한다!! → 트랜잭션 처리

 


순서

1. Class.forName()을 통한 드라이버 등록
2. DriverManager.getConnection()를 통해 DB 계정 연결, Connection 객체 반환

ex) conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "SCOTT", "SCOTT");

3. 쿼리문 작성
4. Statement, PreparedStatement 두 가지 객체(클래스)를 통한 쿼리문 전달 후 반환값 받기

 (위치홀더 (?)를 이용해 인자를 채워넣을 때는 PreparedStatement 사용.)

 → 정확히는 executeQuery, executeUpdate() 를 통해.
5. 활용할 수 있는 객체에 옮겨담기
6. 자원 반납 

 

✔ CreateStatement() 는 전달만 하면 돼서 query 인자를 처음부터 받지 않음.
stmt = conn.createStatement();
rset = stmt.executeQuery(query);

 

✔ Preparestatement()는 미리 query를 받아 빈 값을 채워넣는 과정이 필요.

1)
// stmt = conn.createStatement();
pstmt = conn.prepareStatement(query); // 비워진 곳을 채워야 하니 먼저 query를 받음
pstmt.setInt(1, empNo); // 빈 1번 구멍에 넣을 것, 내가 전달받은 empNo를
// rset = stmt.executeQuery(query);
rset = pstmt.executeQuery();

2)
String query = "INSERT INTO EMP VALUES(?, ?, ?, ?, SYSDATE, ?, ?, ?)";
// HIREDATE는 DB에서 해당 날짜로 들어가기 때문에 SYSDATE

pstmt = conn.prepareStatement(query);

pstmt.setInt(1, emp.getEmpNo());

pstmt.setString(2, emp.getEmpName());

pstmt.setString(3, emp.getJob());

pstmt.setInt(4, emp.getMgr()); // 원래 컬럼 순서 직접 확인하고

pstmt.setInt(5, emp.getSal()); // 순서대로 넣어야 함.

pstmt.setInt(6, emp.getComm());

pstmt.setInt(7, emp.getDeptNo());

 

// 4. Statement, PreparedStatement를 통한 쿼리문 전달 후 반환 값 받기

// executeQuery, executeUpdate()

// + 객체에 옮겨담을 필요 없지만, 제대로 들어갔는지 확인하기 위해 변수 사용

result = pstmt.executeUpdate(); // DML이 적용된 행의 개수가 반환되니까 반환 값이 int 타입일 수밖에 없다.

// 새롭게 업데이트 되는 것들 


3_JDBC_workspace

 

〈EmployeeDAO〉

 
1)

DriverManager

드라이버를 등록해주는 것
≫ Class.forName()을 이용해서 해당 DBMS에 대한 드라이버 등록을 하는 것
 (해도 되고 안 해도 되는데 에러를 줄이기 위해 하는 것이 좋음)

1. 드라이버는 어떠한 DBMS에 연결할 때 필요함
2. 오라클을 써서 오라클에 연결함.
3. 그런데 오라클에 계정이 여러 개임
4. 오라클 연결 - 어떤 계정에 대해 연결할 지 정보를 등록하는 곳이 결국 driver manager 임.

 
 

2)

Connection

쿼리 전달 // Driver manager를 통해 계정 연결이 되면 커넥션을 반환함
DB까지 접근할 수 있는 길 
 
- 드라이버 매니저 안에 있는 getConnection 메소드를 통해
 커넥션이라는 객체를 얻을 수 있고 디비에 연결할 수 있음.
- 연결이 되면 객체 반환, 연결이 안 되면 null
- SQL 문장을 실행하기 전에 Connection 객체가 있어야 함.
- Connection을 통해 DBMS한테 쿼리를 보낼 수 있음
 
 
3)

쿼리문 작성

≫ String 타입으로!

 
4)

Statement, PreparedStatement를 통해 쿼리문 전달 후 반환값 받기 (우체부)

≫ executeQuery()를 통해 실질적으로 쿼리를 ResultSet에 전달해줌

 


5)

활용할 수 있는 객체에 옮겨담기

≫ 클래스에 들어가는 필드는 테이블에 들어가는 컬럼과 똑같이 구성할 필요 없다.
(내가 필요한, 자주 사용하는 컬럼들을 가지고 조인해서 구성)


ResultSet에서 만들었던 컬럼대로 구현하는 것이 맞음. ▼
 


 
6)

자원 반납

close() 하는 순서

 
7)

메소드 반환 타입 void에서 ArrayList<Employee>로 바꾸기

 



🔨 자동 커밋 오류

≫ conn.setAutoCommit(false)로 자동 커밋을 꺼주면 된다.