**프로그래밍 언어에서 데이터베이스 사용
1. 사전 준비
=> 프로그래밍 언어와 데이터베이스 사이에서 통역의 역할을 수행할 드라이버 설치
- 자바에서는 드라이버 파일을 build Path에 추가해 주어야 함
- ojdbc6.jar 파일을 프로젝트에 복사, 파일을 마우스 오른쪽을 클릭, [build path] - [add to build path] 메뉴 실행
=> 데이터베이스 접속 정보를 알아야 함
- url : 데이터베이스 서버 컴퓨터의 ip나 도메인, 포트번호, 데이터베이스명(오라클 : sid, service name)
- userid와 passward : 데이터베이스 종류에 따라 없어도 되는 경우가 있음(Access, Sqlite3)
- 192.168.0.200, 1521, xe / user08:user08
2. java에서 데이터베이스 연동작업
1) 드라이버 클래스를 로드
- Class.forName(String driverClassName);
- driverClassName은 데이터 베이스 종류마다 다름
- 이 작업은 프로그램 내에서 처음 1회만 수행(static Class)
- 오라클 : oracle.jdbc.driver.OracleDriver
2) 데이터베이스 연결
- Connect 연결변수 = DriverManager.getConnection(String url[, String userid, String passward]);
=> url은 데이터베이스 종류마다 다름
(오라클 url - "jdbc:oracle:thin:@192.168.0.200:1521:xe" or "1521/service name", "user08", "user08")
=> 연결에 실패하면 예외 발생
=> 데이터베이스 서버가 사용가능한지, url은 정확한지, id, pw가 맞는 지 확인(catch구문에서 예외내역 확인)
3) SQL 실행 객체 생성
=> PreparedStatement : SQL 실행
- PreparedStatement 실행객체변수 = 연결변수.prepareStatement(String sql);
=> CallableStatement : Procedure 실행
=> SQL 작성시 값의 자리에는 ?를 사용하여 나중에 바인딩 가능
- insert -> values
- update -> set의 값, where에서 조건의 값의 자리
- delete -> where의 조건의 값의 자리
- select -> where과 having에서 조건의 값의 자리
- 컬럼 명은 ?로 대체 불가
=> ?자리에 값을 바인딩 : set자료형(물음표 번호, 실제 데이터)
4) SQL 실행
=> select : resultSet 결과 변수 = 실행객체변수.executeQuery();
=> 그외 : int 결과변수 = 실행객체 변수.executeUpdate();
=> select 구문은 실행결과가 순서대로 결과에 접근 할 수 있는 cursor가 리턴
=> 나머지 구문은 영향받은 행의 갯수가 리턴
5) 실행 결과 사용
6) 생성된 객체들의 연결을 해제
- ResultSet.close()
- PreparedStatement.close()
- Connection close()
=> 클라이언트가 서버에 직접 접속시 정확하게 해야 하고, 클라이언트가 앱 서버를 통하여 접속하는 경우 크게 문제가 되지 않음
**DEPT 테이블에 대한 삽입과 삭제 작업
1. DEPT 테이블 구조
=> DEPTNO : 숫자 2자리
=> DNAME : 문자 14자리 - 한글 4자
=> LOC : 문자 13자리 -한글 4자
2. Java Project 생성
3. 드라이버 설치
=> ojdbc.jar 파일을 프로젝트에 복사
=> 복사한 파일을 선택하고 마우스 오른쪽을 클릭 [build Path] - [Add To Build Path]를 실행
4. main 메소드를 소유한 클래스를 만들고 데이터를 삽입하는 코드를 작성
=> 에러발생시 constraint 단어가 보이면, 유일해야하는 데이터중 중복이 있거나, not null 설정된 열에 데이터를
생략하고 입력하거나, foreign key로 설정된 열에 참조할 테이블에 없는 데이터등을 확인
=> table or view does not exist : 테이블이 없는 경우
=> SQL 메시지가 보이면 SQL을 잘못 작성한 경우
=> 자료형이 맞지 않으면 Invalid 자료형으로 에러 메시지가 출력됨
5. 확인 : 데이터베이스 접속 프로그램에서 실행
=> 삽입한 데이터가 있는 지 확인
6. select 작업
=> PreparedStatement의 executeQuery 메소드로 수행
=> 결과는 ResultSet 타입
1) ResultSet의 next()
=> 다음 데이터가 있으면 그 데이터를 가리키는 곳으로 이동하고 true를 리턴(없으면 false 리턴)
=> if(ResultSet.next() == true){ 조회된 데이터가 있는 것 }else{ 조회된 데이터가 없는 것 }
=> 여러행의 데이터라면 아래처럼 반복문을 이용해서 각각의 행에 접근 하는 것이 가능
=> while(ResultSet.next(){ 행단위 작업 }
2) ResultSet의 get 메소드
=> 열의 값을 가져올때 사용하는 메소드
=> get자료형(열이름이나 select 구문의 열 인덱스)로 사용
=> getInt, getDouble, getString, getDate의 형태로 만들어져 있음
=> 모든 열의 값은 getString으로 가져오는 것이 가능
- getInt("deptno") : deptno열의 값을 정수로 리턴
- getInt(1) : 첫번째 열의 값을 정수로 리턴
- getString("dname") : dname 열의 값을 문자열로 리턴
3) main 메소드를 소유한 클래스를 만들고 main 메소드에 작성
=> DEPT 테이블의 전체 데이터를 읽어와서 출력
SELECT DEPTNO, DNAME, LOC
FROM DEPT;
4) main 메소드를 만들고 작성
=> deptno(primary key - not null, unique)를 입력받아서 deptno에 해당하는 데이터를 조회(상세보기)
[가져오는 방법들]
select deptno, round(avg(sal)) 평균급여
from emp
group by deptno;
rs.getInt("deptno")
rs.getInt("round(avg(sal))") => rs.getInt("평균급여") => rs.getInt(2)
7. Transaction
=> 한번에 처리되어야하는 작업의 단위
1) 구현방식
- auto-commit : sql문장이 성공적으로 수행되면 자동으로 commit - 자바의 기본
- manual-commit : commit이나 rollback을 명시적으로 호출해야만 commit, rollback 되는 방식
2) java에서의 활용
=> 기본은 AutoCommit인데, ManualCommit으로 변경하려면 Connection.setAutoCommit(false); 호출
=> Commit이나 Rollback을 하고자 하는 경우 Connection.commit() or rollback()을 호출
=> rollback은 작업을 취소하는 명령, 대부분의 경우 하나의 거래를 수행하는 도중 예외가 발생하면 rollback
=> 작업이 정상적으로 완료시, commit을 호출하여 원본에 작업 내용 반영
**Procedure 연동
1. PROCEDURE
=> 자주 사용하는 SQL문장을 하나의 이름으로 만들어 두고 프로그래밍 언어의 메소드처럼 사용하는 것
=> 사용자에게 실제 테이블의 구조를 보여주지 않아도 되서 보안이 향상 됨
=> SQL문장은 보조 기억장치에서 주기억장치로 불러와서 실행되지만 프로시저는 한번 컴파일되면 주기억장치에
상주한 상태로 실행되기에 실행속도도 향상됨
=> 프로시저를 만드는 문법은 데이터베이스 종류에 따라 서로 다름
- Oracle에서 프로시저 만드는 문법 : PL/SQL
=> DEPT 테이블에 데이터를 삽입하는 프로시저
CREATE OR REPLACE PROCEDURE INSERT_DEPT_PROC
(VDEPTNO IN DEPT.DEPTNO%TYPE,
VDNAME IN DEPT.DNAME%TYPE,
VLOC IN DEPT.LOC%TYPE)
IS
BEGIN
INSERT INTO DEPT(DEPTNO, DNAME, LOC)
VALUES(VDEPTNO, VDNAME, VLOC);
END;
/
=> 앞에서 만든 프로시저 테스트
BEGIN
INSERT_DEPT_PROC(01, '기획', '서울');
END;
=> 프로시저는 SI업체와 같은 대기업, 공공기관 프로젝트를 받아서 하는 기업은 되도록 사용
=> Start-up이나 중소기업처럼 역할이 분리되지 않은 곳에서는 잘 사용하지 않음
2. Java에서 프로시저 사용
=> PreparedStatement 대신 CallableStatement 생성
- CallableStatement 실행객체 변수 = Connection.prepareCall("{call 프로시저명(?...)}");
- 실행객체 변수.set자료형(물음표 번호, 실제 데이터)...
=> 실행은 executeUpdate() 또는 executeQuery()
3. 앞에서 만든 insert_dept_proc
**데이터베이스 연동 패턴
1. DTO(Data Transfer Object - Variable Object, Domain) 패턴
=> 여러개의 속성을 묶어서 하나로 표현하기 위한 클래스를 DTO 또는 VO라고 함
=> 테이블과 매핑되는 클래스를 만들어서 사용하는 패턴
(이패턴의 확장 : ORM(SQL없이 인스턴스만으로 데이터 베이스 작업을 수행하도록 해주는 프레임 워크))
2. DAO(Data Access Object)
=> 데이터베이스 작업만 수행하는 별도의 클래스를 만들어서 사용하는 패턴
=> 이 패턴을 서버에 적용할 때는 특별한 경우가 아니면 Singleton Pattern으로 디자인
3. Singleton
=> 객체를 하나만 만들수 있도록 클래스를 디자인하는 패턴
4. Service : 사용자의 요구(Business Logic)를 처리하는 클래스
5. Controller : 사용자의 요청을 받아서 필요한 Service를 호출하는 클래스
6. View : 클라이언트가 보고있는 화면
**DTO & DAO 패턴을 이용한 CRUD(Create Read Update Delete)작업
1. 작업에 필요한 샘플 데이터 생성
1) 샘플 테이블 생성
- 상품 테이블
상품 코드 : 영문과 숫자로 이루어진 문자열 10자리 - 자주 변함 PRIMARY KEY
상품 명 : 한글 포함한 20자리 문자열 - 변하지 않음, 필수
상품 원산지 : 한글 포함한 50자리 문자열 - 변하지 않음, 필수
상품 가격 : 정수 10자리 이내 - 기본값 0
상품 입고일 : 날짜 - 기본값 오늘 날짜
ISBN : 영문과 숫자로 이루어진 문자열 20자리 - 변하지 않음 PRIMARY KEY
책 제목 : 한글 포함한 20자리 문자열 - 변하지 않음, 필수
출판사 : 한글 포함한 50자리 문자열 - 변하지 않음, 필수
책 가격 : 정수 10자리 이내 - 기본값 0
출간일 : 날짜 - 기본값 오늘 날짜
CREATE TABLE BOOK(
ISBN VARCHAR2(20) PRIMARY KEY,
BOOKNAME VARCHAR2(60) NOT NULL,
AUTHOR VARCHAR2(30) NOT NULL,
COMPANY VARCHAR2(150) NOT NULL,
PRICE NUMBER(10) DEFAULT 0,
FIRSTDATE DATE DEFAULT SYSDATE);
--샘플데이터 입력
INSERT INTO BOOK(ISBN, BOOKNAME, AUTHOR, COMPANY, PRICE, FIRSTDATE)
VALUES(001, '난중일기', '이순신', '지학사', 15000, SYSDATE-10);
INSERT INTO BOOK(ISBN, BOOKNAME, AUTHOR, COMPANY, PRICE, FIRSTDATE)
VALUES(002, '난장이가 쏘아올린 작은 공', '작자 미상', '아름다운나무', 7000, SYSDATE-30);
INSERT INTO BOOK(ISBN, BOOKNAME, AUTHOR, COMPANY, PRICE, FIRSTDATE)
VALUES(003, '셰익스피어 4대 비극', '셰익스피어', '청어람', 10000, SYSDATE-20);
INSERT INTO BOOK(ISBN, BOOKNAME, AUTHOR, COMPANY, PRICE, FIRSTDATE)
VALUES(004, '죄와벌', '도프토예프스키', '푸른숲', 15000, SYSDATE-1);
COMMIT;
2. 테이블의 데이터를 표현 할 클래스를 자바 프로젝트에 생성
public class Books {
private String ISBN;
private String bookName;
private String author;
private String company;
private int price;
private Date pubDate;
//생성자 - 인스턴스를 생성하기 위해서 호출하는 메소드
//생성자는 new로 호출
public Books() {
super();
// TODO Auto-generated constructor stub
}
public Books(String iSBN, String bookName, String author, String company, int price, Date pubDate) {
super();
ISBN = iSBN;
this.bookName = bookName;
this.author = author;
this.company = company;
this.price = price;
this.pubDate = pubDate;
}
//접근자 메소드 - getters & setters
public String getISBN() {
return ISBN;
}
public void setISBN(String iSBN) {
ISBN = iSBN;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Date getPubDate() {
return pubDate;
}
public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
}
//디버그를 빠르게 하기 위한 메소드
@Override
public String toString() {
return "Books [ISBN=" + ISBN + ", bookName=" + bookName + ", author=" + author + ", company=" + company
+ ", price=" + price + ", pubDate=" + pubDate + "]";
}
3. DAO 클래스를 생성 - 데이터베이스 작업만을 담당하는 클래스
=> GoodDAO 클래스
=> 서버에서 사용할 것이라면 Singleton 패턴으로 작성
'수업 정리' 카테고리의 다른 글
27일차 수업 정리(MySQL) (0) | 2020.05.15 |
---|---|
26일차 수업 정리 (0) | 2020.05.14 |
24일차 수업 정리(Index, Synonym, Procedure, Trigger) (0) | 2020.05.12 |
23일차 수업 정리(트랜잭션, 제약조건, 뷰, 시퀀스) (0) | 2020.05.11 |
22일차 수업 정리(DB - Join, DDL, DML, Subquery) (0) | 2020.05.08 |