1. VIEW 뷰
: SELECT(쿼리문)을 저장해둘 수 있는 객체
(자주 쓰는 건 SELECT 문을 저장해두면 긴 SELECT문을 매번 다시 기술할 필요가 없음)
임시테이블(실제 데이터가 들어가는 것은 아니다.)
- 한국에서 근무하는 사원들의 사번, 이름, 부서명, 급여, 근무국가명, 직급명 조회
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, SALARY, NATIONAL_NAME, JOB_NAME
FROM NATIONAL
JOIN LOCATION USING(NATIONAL_CODE)
JOIN DEPARTMENT ON(LOCATION_ID = LOCAL_CODE)
JOIN EMPLOYEE ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE)
WHERE NATIONAL_NAME = '한국';
1) VIEW 생성방법
[표현법]
① CREATE VIEW 뷰명
AS 서브쿼리;
② CREATE OR REPLACE VIEW 뷰명
AS 서브쿼리
-> OR REPLACE는 생략이 가능함
: 뷰 생성 시 기존에 중복된 이름의 뷰가 없다면 새로 만들고
기존에 중복된 이름의 뷰가 있다면 해당 뷰를 변경(갱신)하는 옵션
-뷰 이름 : VW_EMPLOYEE
CREATE VIEW VW_EMPLOYEE
AS SELECT EMP_ID, EMP_NAME, DEPT_TITLE, SALARY, NATIONAL_NAME, JOB_NAME
FROM NATIONAL
JOIN LOCATION USING(NATIONAL_CODE)
JOIN DEPARTMENT ON(LOCATION_ID = LOCAL_CODE)
JOIN EMPLOYEE ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE);
--KH계정에 뷰 생성 권한이 없기 때문에 오류 발생
- 관리자계정 : 권한 부여
GRANT CREATE VIEW TO KH;
- 다시 뷰를 생성절을 실행하면, 'View VW_EMPLOYEE이(가) 생성되었습니다.'라고 뜸.
SELECT * FROM VW_EMPLOYEE
WHERE NATIONAL_NAME = '한국';
SELECT * FROM VW_EMPLOYEE
WHERE DEPT_TITLE LIKE '해외%';
- > 따로 반복해서 적지 않아도 뷰명만 입력하면 조건 부여 가능
- 뷰 생성 시 서브쿼리를 이용하면 그 때 그 때 알아보기 힘든 쿼리문을 길게 작성하는 것보다 한 번 만든 뷰를 통해서 편하게 조회가 가능하다.
-만약 조회 싶은 컬럼을 추가하고 싶을 땐?
-> BONUS컬럼을 추가해보자.
CREATE OR REPLACE VIEW VW_EMPLOYEE
AS SELECT EMP_ID, EMP_NAME, DEPT_TITLE, SALARY, NATIONAL_NAME, JOB_NAME, BONUS
FROM NATIONAL
JOIN LOCATION USING(NATIONAL_CODE)
JOIN DEPARTMENT ON(LOCATION_ID = LOCAL_CODE)
JOIN EMPLOYEE ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE);
OR REPLACE 옵션을 함께 쓰면 원래있던 VIEW가 갱신됨.
- 뷰는 논리적인 가상 테이블 즉, 하드디스크에 실질적으로 저장이 되지 않음.(=존재하지 않음)
쿼리문이 테이블에 TEXT로 저장되어있음.
- 해당 계정이 가지고 있는 VIEW들에 대한 내용을 조회하고자 한다면 데이터 딕셔너리 중 USER_VIEW를 조회하면 된다.
-사원의 사번, 이름, 직급명, 성별, 근무년수
CREATE OR REPLACE VIEW VW_EMP_JOB
AS SELECT EMP_ID, EMP_NAME, JOB_NAME,
DECODE(SUBSTR(EMP_NO, 8, 1), 1, '남', 2, '여') ,
EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM HIRE_DATE)
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);
--별칭을 지정하지 않아서 문제 발생 -> 함수식과 연산식에는 반드시 앨리어스 붙여주기
--00998: must name this expression with a column alias
CREATE OR REPLACE VIEW VW_EMP_JOB
AS SELECT EMP_ID, EMP_NAME, JOB_NAME,
DECODE(SUBSTR(EMP_NO, 8, 1), 1, '남', 2, '여') "성별",
EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM HIRE_DATE) "근무년수"
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);
-근무년수에 따라 사원들 조회
SELECT * FROM VW_EMP_JOB
WHERE 근무년수 >= 10;
- 뷰를 삭제해보면,
DROP VIEW VW_EMP_JOB;
--실제 데이터가 삭제되는 것이 아닌 TEXT만 사라짐
2-1) 뷰를 이용해서 DML(INSERT, UPDATE, DELETE) 사용하기
뷰에 적용 => 실제 데이터가 담긴 베이스테이블에 적용이 된다.
- JOB테이블 복사한 VIEW 생성
CREATE OR REPLACE VIEW VW_JOB
AS SELECT * FROM JOB;
- 뷰에 INSERT
INSERT INTO VW_JOB
VALUES ('J8', '인턴');
SELECT * FROM JOB;
-논리적 테이블(VW_VIEW)에 INSERT했는데 물리적테이블(JOB)에도 INSERT됨
-JOB_CODE가 J8인 JOB_NAME을 알바로 UPDATE
UPDATE VW_JOB
SET JOB_NAME = '알바'
WHERE JOB_CODE = 'J8';
* 수행결과에 따른 차이점
- SELECT : Result Set
- DML(INSERT, UPDATE, DELETE) : N행이(가) 삽입/변경/삭제되었습니다.
DELETE FROM VW_JOB
WHERE JOB_CODE = 'J8';
-만약 없는 조건을 삭제할 경우 '0행 이(가) 삭제되었습니다.'라고 출력
COMMIT;
-DML을 실행한 뒤에는 반드시 트랜잭션 처리를 해주어야 함(COMMIT혹은 ROLLBACK)
2-2) 뷰를 이용해 DML처리가 불가능한 경우
①뷰에 정의되지 않은 컬럼을 조작하는 경우 ② NOT NULL제약조건이 지정된 경우 ③ 산술연산식 또는 함수를 통해서 정의되어있는 경우 ④ 그룹함수 GROUP BY절이 포함된 경우 ⑤ DINTINCT 구문이 포함된 경우 ⑥ JOIN을 이용해서 여러 테이블을 매칭시켜놓을 경우 |
①뷰에 정의되지 않은 컬럼을 조작하는 경우
--VIEW 생성
CREATE OR REPLACE VIEW VW_JOB
AS SELECT JOB_CODE FROM JOB;
SELECT * FROM VW_JOB; --컬럼 1개
--INSERT
INSERT INTO VW_JOB(JOB_CODE, JOB_NAME) VALUES ('J8', '인턴');
--JOB_NAME을 찾을 수 없음
--UPDATE
UPDATE VW_JOB
SET JOB_NAME = '인턴'
WHERE JOB_CODE = 'J7';
--JOB_NAME을 찾을 수 없음
--DELETE
DELETE FROM VW_JOB
WHERE JOB_NAME = '인턴';
--JOB_CODE로는 가능
-현재 VW_JOB 뷰에 존재하지 않는 JOB_NAME컬럼에 값을 추가, 변경, 삭제하고자 하면 오류 발생
-SQL오류: ORA-00904: "JOB_NAME": invalid identifier
② NOT NULL제약조건이 지정된 경우
CREATE OR REPLACE VIEW VW_JOB
AS SELECT JOB_NAME FROM JOB;
SELECT * FROM VW_JOB;
--INSERT
INSERT INTO VW_JOB VALUES('인턴'); --JOB테이블에 (NULL, '인턴')이 삽입되려고 했다. 하지만 JOB_CODE는 NOT NULL제약조건
--UPDATE
UPDATE VW_JOB
SET JOB_NAME = '알바'
WHERE JOB_NAME = '사원';
SELECT * FROM JOB;
--가능(VIEW에 존재하는 컬럼)
UPDATE VW_JOB
SET JOB_CODE = NULL
WHERE JOB_NAME = '알바';
--불가능(VIEW에 존재하지 않는 컬럼)
ROLLBACK;
--DELETE
DELETE FROM VW_JOB
WHERE JOB_NAME = '사원';
-사용하고 있는 자식데이터가 존재한다면 삭제가 안됨
③ 산술연산식 또는 함수를 통해서 정의되어있는 경우
-사원의 사번, 사원명, 급여, 연봉에 대해서 조회하는 뷰
--VIEW생성
CREATE OR REPLACE VIEW VW_EMP_SAL
AS SELECT EMP_ID, EMP_NAME, SALARY, SALARY*12 "연봉"
FROM EMPLOYEE;
--INSERT
INSERT INTO VW_EMP_SAL VALUES(400, '이승철', 20000000, 240000000);
--산술연산을 통해 나온 결과값에는 입력 불가능
--UPDATE
UPDATE VW_EMP_SAL
SET 연봉 = 40000000
WHERE EMP_ID = 200;
--가상의 컬럼(산술연산)엔 불가능
UPDATE VW_EMP_SAL
SET SALARY = 7800000
WHERE EMP_ID = 200;
--실제 존재하는 컬럼엔 가능
DELETE FROM VW_EMP_SAL
WHERE 연봉 = 72000000;
--조작하는 것이 아니기에 가능
ROLLBACK;
④ 그룹함수 GROUP BY절이 포함된 경우
-부서별 급여 합, 평균급여를 조회하는 경우
--VIEW생성
CREATE OR REPLACE VIEW VW_GROUPDEPT
AS SELECT DEPT_CODE, SUM(SALARY) "급여합", ROUND(AVG(SALARY)) "평균급여"
FROM EMPLOYEE
GROUP BY DEPT_CODE;
SELECT * FROM VW_GROUPDEPT;
--INSERT
INSERT INTO VW_GROUPDEPT VALUES('D0', 80000000, 400000);
--UPDATE
UPDATE VW_GROUPDEPT
SET 급여합 = 8000000
WHERE DEPT_CODE = 'D1';
--DELETE
DELETE FROM VW_GROUPDEPT
WHERE DEPT_CODE = 'D1';
--GROUPBY절로 묶여있거나 그룹함수로 묶여있는 경우 DML불가능
⑤ DINTINCT 구문이 포함된 경우
--VIEW생성
CREATE OR REPLACE VIEW VW_DT_JOB
AS SELECT DISTINCT JOB_CODE FROM EMPLOYEE;
SELECT * FROM VW_DT_JOB;
--INSERT
INSERT INTO VW_DT_JOB VALUES('J8');
--중복값을 제거하기 때문에 어느 컬럼에 삽입/수정/삭제를 해야할 지 모호함
--따라서, UPDATE, DELETE도 안됨
⑥ JOIN을 이용해서 여러 테이블을 매칭시켜놓을 경우
--VIEW생성
CREATE OR REPLACE VIEW VW_JOINEMP
AS SELECT EMP_ID, EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
SELECT * FROM VW_JOINEMP;
--INSERT
INSERT INTO VW_JOINEMP VALUES(999, '가나다', 'A부');
--둘 이상의 테이블이 JOIN되었기 때문에 불가능
--UPDATE
UPDATE VW_JOINEMP
SET EMP_NAME = '서동일'
WHERE EMP_ID = 200;
--EMPLOYEE테이블에만 업데이트하기 때문에 가능
--DELETE 또한 불가능
ROLLBACK;
3) VIEW옵션
[상세 표현법]
CREATE OR REPLACE FORCE/NOFRCE VIEW 뷰명
AS 서브쿼리
WITH CHECK OPTION
WITH READ ONLY;
①OR REPLACE : 해당 뷰가 존재하지 않으면 새로 생성 / 존재하면 갱신시켜주는 옵션
②FORCE / NOFORCE
- FORCE : 서브쿼리에 기술된 테이블이 존재하지 않아도 뷰가 생성
- NOFORCE(기본값) : 서브쿼리에 기술된 테이블이 반드시 존재해야만 뷰가 생성
③ WITH CHECK OPTION : 서브쿼리에 조건절에 기술된 내용에 만족하는 값으로만 DML가능
조건에 부합하지 않는 값으로 수정하는 경우 오류가 발생
④WITE READ ONLY : 뷰에 대해서 조회만 가능(DML 수행불가)
①OR REPLACE : 앞 서 구문들 참고
②FORCE / NOFORCE
: 기억할 때 TIP, FORCE = '힘이 쎈'으로 기억하기.
--DEFAULT값 : NO FORCE
CREATE OR REPLACE /*NO FORCE*/ VIEW VW_TEST
AS SELECT FORCE, NOFORCE
FROM NIKE; --없는 테이블은 생성 X
--FORCE : 힘이세서 강제로 생성 가능
CREATE OR REPLACE FORCE VIEW VW_TEST
AS SELECT FORCE, NOFORCE
FROM NIKE;
-- 경고: 컴파일 오류와 함께 뷰가 생성되었습니다.
하지만, 실행해보면
SELECT * FROM VW_TEST;
--오류 발생
FORCE로 옵션을 지정하는 이유는 추후 바로 테이블을 생성할 때 지정함.
CREATE TABLE NIKE(
FORCE NUMBER,
NOFORCE NUMBER
);
SELECT * FROM VW_TEST;
--테이블 생성 후 다시 조회하면 오류 발생 X
③ WITH CHECK OPTION
CREATE OR REPLACE VIEW VW_EMP
AS SELECT * FROM EMPLOYEE
WHERE SALARY >= 3000000
WITH CHECK OPTION;
SELECT * FROM VW_EMP;
SALARY가 3,000,000원 이상인 사원만 VW_EMP에 저장한다는 CHECK OPTION을 지정함.
UPDATE VW_EMP
SET SALARY = 2999999
WHERE EMP_NAME = '선동일';
--서브쿼리에 기술한 조건에 부합하지 않기 때문에 변경 불가
ROLLBACK;
④WITE READ ONLY
: 읽기 전용
CREATE OR REPLACE VIEW VW_EMPBONUS
AS SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE
WHERE BONUS IS NOT NULL
WITH READ ONLY;
SELECT * FROM VW_EMPBONUS;
DELETE FROM VW_EMPBONUS
WHERE EMP_ID = 213;
-> 읽기 전용이기에 삭제(DML) 불가
2. SEQUENCE 시퀀스
자동으로 번호를 발생시켜주는 역할을 하는 객체, 정수값을 자동으로 순차적으로 생성해줌.
예) 회원번호, 사번, 게시글 번호 등등 채번할 때 사용
INSERT INTO MEMBER VALUES(1, 'user01', 'pass01', ...);
INSERT INTO MEMBER VALUES(2, 'user01', 'pass01', ...);
INSERT INTO MEMBER VALUES(3, 'user01', 'pass01', ...);
INSERT INTO MEMBER VALUES(4, 'user01', 'pass01', ...);
...
INSERT INTO MEMBER VALUES(1453, 'user01', 'pass01', ...);
-> 실수할 확률이 높아짐
1) 시퀀스 객체 생성구문
- CREATE SEQUENCE 시퀀스명
- START WITE 시작 숫자 => 생략가능, 처음 발생시킬 시작값 지정
- INCREMENT BY 증가값 => 생략가능, 몇 씩 증가시킬 건지 지정
- MAXVALUE => 생략가능, 최대값 지정
- MINVALUE => 생략가능, 최소값 지정
- CYCLE / NOCYCLE => 생략가능, 값 순환여부
- CACHE 바이트크기 / NOCACHE => 생략가능, 캐시메모리사용여부 기본값은 20Byte
* SEQUENCE CACHE MEMORY : 미리 발생할 값들을 생성해서 저장해두는 공간
매번 호출 할 때 새로 번호를 생성하는 것은 비효율적이니
캐시메모리공간에 미리 생성된 값들을 가져다 쓰게해서 속도를 높임.
* 접두사, 접미사
- 테이블명 : TB_
- 뷰명 : VW_
- 시퀀스 : SEQ_
* 회사마다 기준이 다르기에 회사 기준 따르기
CREATE SEQUENCE SEQ_EMPNO
START WITH 300--시작값
INCREMENT BY 5 --증가값
MAXVALUE 310 --최대값
NOCYCLE --순환X
NOCACHE; --캐시 미사용
2) 시퀀스 사용구문
시퀀스명.CURRVAL : 현재 시퀀스 값(마지막으로 성공적으로 발생된 NEXTVAL값)
시퀀스명.NEXTVAL : 시퀀스 값을 증가시키고 증가된 시퀀스값
기존의 시퀀스 값에서 INCREMENT BY 값만큼 증가된 값
(시퀀스명.CURRVAL + INCREMENT BY 값)
SELECT SEQ_EMPNO.CURRVAL FROM DUAL;
-> NEXTVAL을 한 번이라도 수행하지 않는 이상 CURRVAL을 수행할 수 없음
SELECT * FROM USER_SEQUENCES;
-- LAST_NUMBER : 현재 상황에서 NEXTVAL을 실행할경우 예정 값
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL;
SELECT SEQ_EMPNO.CURRVAL FROM DUAL; -- 300
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; -- 305
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; -- 310
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; -- MAXVALUE에 걸침
SELECT SEQ_EMPNO.CURRVAL FROM DUAL;
3) 시퀀스 변경
[ 표현법 ]
ALTER SEQUENCE 시퀀스명
INCREMENT BY 증가값 => 생략가능, 몇 씩 증가시킬건지 지정
MAXVALUE => 생략가능, 최대값 지정
MINVALUE => 생략가능, 최소값 지정
CYCLE / NOCYCLE => 생략가능, 값 순환여부
CACHE 바이트크기/NOCACHE => 생략가능, 캐시메모리사용여부, 기본값은 20Byte
* START WITH는 변경불가
ALTER SEQUENCE SEQ_EMPNO
INCREMENT BY 10
MAXVALUE 400;
SELECT SEQ_EMPNO.CURRVAL FROM DUAL; --310
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; --340
시퀀스를 이용해 EMP_ID를 생성해보면,
CREATE SEQUENCE SEQ_EID
START WITH 300;
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, JOB_CODE, SAL_LEVEL)
VALUES(SEQ_EID.NEXTVAL, '시퀀스맨', '1231231232', 'J3', 'S3');
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, JOB_CODE, SAL_LEVEL)
VALUES(SEQ_EID.NEXTVAL, '시퀀스맨맨', '123123', 'J2', 'S4');
SELECT * FROM EMPLOYEE;
-> 자동으로 300부터 순번 매겨짐
3. JDBC
1) 도입-드라이버란?
사용자와 하드웨어를 연결시켜주는 것은 OS
하드웨어 사에서 드라이버 제공해주어 작동하게끔 해줌
JDBC에도 적용해보면,
애플리케이션과 연결해주는 것이 JDBC Driver
앞으로 반드시 기본적으로 해주어야 하는 설정 **
①
②
전 세계 공통인 UTF-8로 변경
< Oracle SQL Developer >
- 관리자계정에서 JDBC계정생성, 최소한의 권한 부여
CREATE USER JDBC IDENTIFIED BY JDBC;
GRANT CONNECT, RESOURCE TO JDBC;
- JDBC TEST용 테이블 생성
CREATE TABLE TEST(
TNO NUMBER,
TNAME VARCHAR2(20),
TDATE DATE
);
< ECLIPSE >
①ojdbc6.jar 추가하기
- 프로젝트 선택 후 마우스 오른쪽 클릭 > Properties -> Java BuildPath -> Libraires -> Add External JARs
* -> c:\dev\objdbc6.jar 선택 -> Apply -> Apply and Close
References Libraries에 ojdbc6 추가 된 것을 확인
* 만약 하지 않을 시 ClassNotFoundException 발생
② DML실행해보기
- 사용자에게 값을 입력받아서 DBMS로 전달
ㄱ. 값 입력받기
Scanner sc = new Scanner(System.in);
System.out.println("번호를 입력해주세요.>");
int num = sc.nextInt();
sc.nextLine();
System.out.println("이름을 입력해주세요.>");
String name = sc.nextLine();
ㄴ. JDBC필요한 변수 셋팅
int result = 0;
Connection conn = null;
Statement stmt = null;
//1단계 끝
ㄷ. 실행 SQL("완성형태"로 만들기)
String sql = "INSERT INTO TEST VALUES(1, '박혜*', SYSDATE)";
String sql = "INSERT INTO TEST VALUES(" + num + ", '" +name + "', SYSDATE)";
//2단계 끝
ㄹ. JDBC driver등록
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("driver 등록 성공");
ㅁ. Connection 객체 생성
//DB에 연결(url, 계정명, 비밀번호)
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
System.out.println("Connection 객체생성");
ㅂ. Statement 객체 생성
stmt = conn.createStatement();
System.out.println("Statement 객체생성");
ㅅ. SQL쿼리를 날려서 실행 후 결과받기(처리된 행 수)
result = stmt.executeUpdate(sql);
//내가 실행할 SQL문이 DML문(INSERT UPDATE DELETE)일 경우
//-> stmt.executeUpdate("DML문") : int
ㅇ. 트랜잭션 처리
//성공했으면 COMMIT, 아니면 ROLLBACK
if(result > 0) { //성공했을 경우
conn.commit();
} else { //실패했을 경우
conn.rollback();
}
ㅈ. 자원반납
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
ㅊ. 결과 반환
if(result > 0 ) {
System.out.println("insert 성공");
} else {
System.out.println("insert 실패");
}
③ SELECT - 내 로컬 PC DBMS상에 JDBC계정에 TEST테이블에 모든 데이터 조회해보기
-> ResultSet (조회된 데이터들 행의 집합) 받기
-> ResultSet으로부터 데이터 뽑기
ㄱ. 변수 셋팅
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
//1단계 끝
ㄴ. 실행 SQL
String sql = "SELECT * FROM TEST";
ㄷ. JDBC Driver 등록
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
ㄹ. Connection 객체 생성
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
ㅁ. Statement 객체 생성
stmt = conn.createStatement();
ㅂ. SQL문 전달해서 실행 후 결과 받기
rset = stmt.executeQuery(sql);
//내가 실행할 SQL문이 SELECT문일 경우
//stmt.executeQuery("SELECT문") : ResultSet
ㅅ. rset.next() : 커서를 움직여주는 역할, 해당 행이 존재한다면 true / 없으면 false
- 조회값 출력
while(rset.next()) {
int tNo = rset.getInt("TNO"); //오타났다면, "부적합한 열이름" 오류
String tName = rset.getString("TNAME");
Date tDate = rset.getDate("TDATE");
System.out.println(tNo + ", " + tName + ", " + tDate);
}
ㅇ. 예외처리와 자원반납
} catch (ClassNotFoundException e) {
System.out.println("드라이버 오타날 경우의 오류");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("커넥션 오류");
e.printStackTrace();
} finally {
try {
rset.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
4. MVC 패턴
1) Model : 데이터와 관련된 역할(데이터를 담는다거나 , DB에 접근해서 데이터 입출력) - vo, dao
2) View : 사용자가 보게될 시각적인 요소 / 화면(입력, 출력)
3) Controller: 사용자의 요청을 받아서 처리 후 응답화면을 지정하는 역할
< 기본 원칙 >
* View단에서만 출력문 (System.out.println)을 사용한다.
* Model의 DAO(Data Access Object)에서만 DB에 직접적으로 접근 한 후 해당 SQL문을 실행한 결과를 받는다.
5. JDBC
1) JDBC의 역할
① Java코드를 통해 DB서버에 접속
② SQL문을 구성하고 DB서버에서 실행
③ DB서버에서 처리한 결과를 가져오기
2) JDBC 사용객체
①DriverManager
* JDBC드라이버를 통해서 커넥션을 만드는 역할
* Class.forName()메소드를 통해 생성되며, 반드시 예외처리를 해줘야 함
* getConnection()을 호출해서 Connection객체를 반환
②Connection
* 특정 데이터 원본과 연결된 객체
* Statement 객체를 생성할 때도 connection객체를 이용해야 함
③Statement
* Connection객체에 의해 프로그램에 구현되는 일종의 메소드 집합
* Connection클래스의 createStatement()를 호출하여 객체 생성
* Statement객체로 SQL문을 String객체로 담아 인지값으로 전달하여 질의를 수행
④ResultSet
* SELECT문을 사용한 질의 성공 시 반환되는 객체
* SQL 질의에 해당하는 결과를 담고 있으며 '커서(cursor)'를 이용하여 특정행에 대한 참조를 조작
'클라우드 융합 Full-stack 웹 개발자 양성과정 > SQL, JDBC' 카테고리의 다른 글
SQL응용 - JDBC(PreparedStatemen) (1) | 2022.10.11 |
---|---|
SQL응용 - JDBC(MEMBER) (1) | 2022.10.06 |
SQL활용 - DDL(복합키, FOREIGN KEY 제약조건, 테이블 복사, ALTER, DROP), DML(INSERT, UPDATE, DELETE), DCL(GRANT, REVOKE, SAMPLE계정), TCL(COMMIT, ROLLBACK, SAVEPOINT) (1) | 2022.10.04 |
데이터 베이스 구현 - SELECT(SUBQUERY), SQL활용 - DDL(CREATE) (0) | 2022.09.29 |
데이터 베이스 구현 - SELECT(GROUP BY, JOIN) (0) | 2022.09.28 |