ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 학원 day29. 데이터 변경, 삭제, JDBC
    기록 2022. 10. 18. 08:00

    ★ 데이터 조회 시 실행 순서

    select 컬럼명, 컬럼명, ...    --- 3

    from 테이블명                    --- 1

    [where 조건식]                   --- 2 (컬럼의 별칭을 사용할 수 없음)

    [order by 정렬기준]            --- 4 (컬럼의 별칭을 사용할 수 있음)

     

    SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, SALARY*12 AS ANNUAL_SALARY

    FROM EMPLOYEES

    WHERE ANNUAL_SALARY >= 150000;   // 오류 발생

     

    SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, SALARY*12 AS ANNUAL_SALARY

    FROM EMPLOYEES

    WHERE DEPARTMENT_ID = 80

    ORDER BY ANNUAL_SALARY ASC;  // 오류 아님

     

    데이터 변경

    - 테이블에 저장된 데이터를 변경한다.

    - UPDATE 명령어 사용

    -- WHERE 조건식이 없으면 모든 행에서 해당 컬럼의 값을 변경한다.

    -- WHERE 조건식이 있으면 조건식을 만족하는 행에서만 해당 컬럼의 값을 변경한다.

     

    UPDATE 테이블명

    SET

          컬럼명 = ,

          컬럼명 =

          컬럼명 = ,

           ...

    [WHERE 조건식]

     

     

    데이터  삭제

    - 테이블에 저장된 데이터를 삭제한다.

    - DELETE FROM 명령어 사용

    - WHERE 조건식이 없으면 테이블의 모든 행이 삭제된다.
    - WHERE 조건식이 있으면 조건식을 만족하는 행만 삭제한다.

     

    DELETE FROM SAMPLE_USERS;

    - 테이블에서 모든 행의 데이터를 삭제한다.

    - 데이터가 저장되었던 영역은 남아있다.

     

    TRUNCATE TABLE SAMPLE_USERS;

    - 테이블에서 모든 행을 잘라낸다.

    - 데이터가 저장되었던 영역도 사라진다.

    - 테이블을 처음 생성했던 상태로 초기화한다.

     

    * 단, 삭제나 변경할 때 자식 레코드가 참조하고 있는 경우는 삭제, 변경 불가! (프라이머키 변경 불가)

      자식레코드가 없는 레코드는 삭제 가능

     

     

    SQL 오류

    -- SQL 오류 : ORA-00942 : table or view does not exist
    -- 테이블이나 뷰의 이름이 올바르지 않을 때 발생한다.
    SELECT *
    FROM DEPARTMENT;       -- DEPARTMENTS가 올바른 테이블 이름이다.
    
    -- ORA-00923 : FROM keyword not found where expected
    -- FROM 키워드가 없습니다.
    SELECT *
    FORM EMPLOYEES;   -- 철자 오류
    
    SELECT EMPLOYEE_ID, FIRST_NAME NAME LAST_NAME SALARY  -- SELECT 절에서 컬럼명을 적을 때 ,가 누락되었을 때
    FROM EMPLOYEES;
    
    -- SQL 오류 : ORA-00926 : missing VALUES keyword
    -- insert 문에 values 키워드가 누락되었다.
    INSERT INTO SAMPLE_USERS
    (USER_ID, USER_PASSWORD, USER_EMAIL, USER_NAME, USER_TEL)
    VALUE  -- VALUES라고 적어야 한다..
    ('sejong', 'zxcv1324', 'sejong@naver.com', '세종대왕', '010-1234-5678');
    
    -- SQL 오류 : ORA-00913 : too many values
    -- INSERT 문에서 컬럼의 갯수가 값의 갯수가 많다.
    INSERT INTO SAMPLE_USERS
    (USER_ID, USER_PASSWORD, USER_EMAIL, USER_NAME, USER_TEL)
    VALUES
    ('sejong', 'zxcv1234', 'sejong@naver.com', '세종대왕', '010-1234-5678', 100);
    
    -- SQL 오류: ORA-00947: not enough values
    -- INSERT 문에서 컬럼의 갯수보다 값의 갯수가 적다.
    INSERT INTO SAMPLE_USERS
    (USER_ID, USER_PASSWORD, USER_EMAIL, USER_NAME, USER_TEL)
    VALUES
    ('sejong', 'zxcv1234', 'sejong@naver.com', '세종대왕');
    
    -- ORA-02292: integrity constraint (HR.JHIST_DEPT_FK) violated - child record found
    -- 이 행을 참조하는 자식 레코드가 있기 때문에 이 행을 삭제할 수 없다.
    DELETE FROM DEPARTMENTS
    WHERE DEPARTMENT_ID = 60;   -- EMPLOYEES테이블에서 DEPARTMENT_ID가 60번이 행이 존재하기 때문에 60번 부서는 삭제할 수 없다.
    
    UPDATE DEPARTMENTS
    SET
        DEPARTMENT_NAME = 300
    WHERE
        DEPARTMENT_ID = 60;     -- EMPLOYEES테이블에서 DEPARTMENT_ID가 60번이 행이 존재하기 때문에 60번 부서의 아이디를 변경할 수 없다.

     


    JDBC

    - Java DataBase Connectivity

    - 자바가 데이터베이스에 접속해서 SQL을 실행할 수 있도록 하는 표준이다.

    - 자바 애플리케이션에서 데이터베이스 엑세스에 필요한 객체들의 표준을 정의하고 있다.

    - java.sql 패키지와 javax.sql 패키지에 관련 인터페이스와 클래스가 존재한다.

    - 각 데이터베이스 제조사가 java.sqljavax.sql에 정의된 인터페이스를 구현해서 자사의 데이터베이스에 엑세스할 수 있는 구현클래스를 제공하고 있다. (jdbc드라이버)

    주요 API 

    • Connection 인터페이스
      • 자바프로그램과 데이터베이스간의 연결을 담당하는 객체다. SQL의 전송을 담당하는 메소드가 있다.
      • Statement createStatement()
        • SQL전송을 담당하는 Statement객체를 반환한다.
      • PreparedStatement prepareStatement(String sql)
        • SQL전송을 담당하는 Statement객체를 반환한다.
      • void commit()
        • SQL실행결과를 DB에 반영시킨다.
      • void rollback()
        • SQL실행결과의 DB 반영을 취소시킨다.
      • void close()
        • DB와의 접속을 해제한다.
    • PreparedStatement 인터페이스
      • SQL의 전송을 담당하는 객체다.
      • int executeUpdate()
        • INSERT, UPDATE, DELETE 쿼리를 DB로 전송하고, 실행결과를 반환한다.
      • ResultSet executeQuery()
        • SELECT 쿼리를 DB로 전송하고, 조회결과를 반환한다.
      • void setXXX(int index, XXX value)
        • ?위치에 실제값(파라미터값)을 설정한다.
        • void setString(int index, String value)
        • void setInt(int index, int value)
        • void setLong(int index, long value)
        • void setDouble(int index, double value)
        • void setDate(int index, Date value)
      • void close()
        • DB 연결 자원을 해제한다.
    • ResultSet 인터페이스
      • SELECT 쿼리문의 조회결과를 담당하는 객체다.
      • boolean next()
        • 커서를 다음행으로 이동시킨다. 데이터행이 존재하면 true를 반환한다.
      • XXX getXXX(String columnName)
        • 컬럼명에 해당하는 값을 반환한다.
        • String getString(String columnName);
        • int getInt(String columnName);
        • long getLong(String columnName);
        • double getDouble(String columnName);
        • Date getDate(String columnName);
      • void close()
        • DB 연결 자원을 해제한다.
    • DriverManager 클래스
      • JDCB 표준을 구현한 JDBC드라이버를 관리하는 클래스다.
      • JDBC드라이버는 각 DBMS제작사가 자사의 DBMS에 엑세스할 수 있도록 위에 언급한 인터페이스를 구현한 클래스들의 모음이다.
      • Connection getConnection(String url, String username, String password)
        • url이 가르키는 데이터베이스에 지정된 계정정보로 연결을 시도한 후 연결을 담당하는 Connection객체를 반환한다.

     

    +) 외부 라이브러리 자바에 넣는 방법

    jdbc폴더 - 오른쪽버튼 buildpath - Configure buildpath - 라이브러리 classpath - Add External Jars 클릭 - c 밑에 app 밑에 자기이름폴더 밑에 product밑에 21c밑에 dbhomexe밑에 jdbc밑에 lib밑에 ojdbc11.jar선택하고 열기 - apply

     

    JDBC API를 사용해서 자바와 데이터베이스 연동하기

    INSERT, UPDATE, DELETE 작업
    - 테이블의 데이터를 변경(추가, 변경, 삭제)하는 작업
    - 결과값은 항상 변경된 행의 갯수다.

    0. SQL 작성하기
    String sql = "insert into sample_products" + "(product_no, product_name, product_price, product_discount_rate, product_stock) " + "values " + "(?, ?, ?, ?, ?)";

    1. Oracle JDBC 드라이버를 메모리에 로딩시킨다.
    Class.forName("oracle.jdbc.OracleDriver");

    2. DBMS와 연결을 담당하는 Connection 구현객체를 획득한다.
    String url = "jdbc:oracle:thin:@localhost:1521:xe";
    String user = "hr";
    String password = "zxcv1234";
    Connection connection = DriverManager.getConnection(url, user, password);

    3. SQL을 데이터베이스로 전송/실행시키는 PreparedStatement 구현객체를 획득한다.
    PreparedStatement pstmt = connection.prepareStatement(sql);

    4. SQL에 ?가 있으면 값을 바인딩한다.
    pstmt.setInt(1, 100);
    pstmt.setString(2, "iphone 14 pro max");
    pstmt.setInt(3, 1700000);
    pstmt.setDouble(4, 0.05);
    pstmt.setInt(5, 10);

    5. SQL을 데이터베이스로 전송하고 실행시킨다.
    int rowCount = pstmt.executeUpdate( );
    System.out.println(rowCount + "개의 행이 추가/변경/삭제 되었습니다.");

    6. 리소스를 해제한다.
    pstmt.close( );
    connection.close( );

    * 1, 2, 3, 5, 6 수행문은 언제나 같은 코드다.
    * 0, 4 수행문은 실행하는 작업마다 다른 코드다.

    package day29;
    
    import java.sql.Connection; 
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class DataBaseApp1 {
    
    	public static void main(String[] args) throws ClassNotFoundException, SQLException{
    		
    		// 값이 들어갈 자리가 ?로 표시된 sql을 정의한다.
    		String sql = "insert into sample_users " // 끝에 공백을 하나 포함시켜야 뒤에 문장이랑 붙어서 실행되지 않는다.
    					+ "(user_id, user_password, user_email, user_name, user_tel, user_point) "
    					+ "values "
    					+ "(?, ?, ?, ?, ?, ?)";
    		
    		// 1. oracle.jdbc.OracleDriver를 자바가상머신의 드라이버 레지스트리에 "jdbc:oracle:thin"이라는 이름으로 등록시키기
    		// Class.forName(클래스의 전체 경로)는 지정된 클래스를 메모리의 설계도 영역에 로딩시킨다.
    		// OracleDriver는 메모리에 로딩이 완료되면 자바가상머신의 드라이버 레지스트리에 오라클 드라이버를 등록시킨다.
    		Class.forName("oracle.jdbc.OracleDriver");
    		
    		// 2. 데이터베이스와 연결을 담당하는 Connection인터페이스의 구현객체를 획득하기
    		// url의 "jdbc:oracle:thin"은 드라이버 레지스트리에 등록된 이름이다.
    		// url의 "@localhost:1521:xe"에서 @localhost는 데이터베이스 설치된 컴퓨터의 이름이다.
    		//								1521은 데이터베이스가 사용하는 포트번호다.
    		//                              xe는 데이터베이스를 식별하는 고유한 이름이다.
    		// username과 password는 데이터베이스 계정명과 비밀번호다.
    		// DriverManager는 자바가상머신의 드라이버 레지스트리를 관리하는 클래스다.
    		// DriverManager의 getConnection(url, username, password)는 지정된 url의 데이터베이스와 연결을 유지하는
    		// java.sql.Connection인터페이스의 구현객체를 반환한다. (구현객체는 ojdbc11.jar에서 제공한다.)
    		String url = "jdbc:oracle:thin:@localhost:1521:xe";
    		String username = "hr";
    		String password = "zxcv1234";
    		Connection connection = DriverManager.getConnection(url, username, password);
            System.out.println(connection);   // oracle.jdbc.driver.T4CConncection@226a82c4 커넥션 구현 객체가 출력됨 
            
            // 3. SQL을 데이터베이스로 전송/실행시키는 Preparedstatement인터페이스 구현객체 획득하기
            // pstmt는 oracle.jdbc.driver.OraclePreparedStatementWrapper객체의 PreparedStatement를 참조한다.
            PreparedStatement pstmt = connection.prepareStatement(sql);
            System.out.println(pstmt); 
            
            // 4. SQL의 ?자리에 실제 값을 바인딩하기
            pstmt.setString(1, "hong-gd");				// user_id (VARCHAR2) 컬럼의 값
            pstmt.setString(2, "hong_gd@naver.com");	// user_email (VARCHAR2) 컬럼의 값
            pstmt.setString(3,"zxcv1234");				// user_password (VARCHAR2) 컬럼의 값
            pstmt.setString(4, "홍길동");					// user_name (VARCHAR2) 컬럼의 값
            pstmt.setString(5, "010-1111-1111");		// user_tel (VARCHAR2) 컬럼의 값
            pstmt.setInt(6, 100);						// user_point (Number) 컬럼의 값
            
            // 5. SQL을 데이터베이스로 전송하고, 실행시킨다.
            int rowCount = pstmt.executeUpdate();
            System.out.println(rowCount + "개의 행이 추가되었습니다.");
            
            // 6. 데이터베이스 액세스 작업에 사용했던 모든 리소스 연결해제하기
            pstmt.close();
            connection.close();
            
    	}
    
    }

    * ?를 바인딩 변수라고 한다. 값이 매번 바뀔 거니까 변수처럼 쓰인다. 

    바인딩변수의 이점은 '홑따옴표'를 안적어도 된다.

    * 데이터베이스마다 url이 다르다.

    * jdbc:oracle:thin:@localhost:1521:xe

    -> thin타입의 오라클 jdbc드라이버를 사용해서 내 컴퓨터의 1521번 포트를 사용하고 있는 xe라는 데이터베이스에 연결하라는 의미임.

    * 데이터베이스의 시작은 1이다.

    커밋을 하기 전까지는 테이터베이스에 올라가지 않고 update작업이 끝날때까지 행 잠금 상태로 있기 때문에 다음 작업을 하기위해서는 커밋을 해야 한다. 

    update, delete문을 실행하면, 해당 행을 다른 프로세스가 수정할 수 없도록 행잠금이 발생한다. 

    commit, rollback명령을 실행하면 행잠금이 해제된다. 

    다른 행들은 영향을 받지 않는다.

     

    package day29;
    
    import java.sql.Connection;  
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.text.MessageFormat;
    import java.util.Date;
    
    public class DataBaseApp4 {
    
    	public static void main(String[] args) throws Exception {
    		
    		String sql = "select * "
    				   + "from sample_users "
    				   + "order by user_id asc ";
    		
    		Class.forName("oracle.jdbc.OracleDriver");
    		
    		Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "zxcv1234");
    		PreparedStatement pstmt = connection.prepareStatement(sql); // sql을 전송하는 객체
    		ResultSet rs = pstmt.executeQuery();   // 조회결과를 담고 있는 객체 Resultset은 데이터가 하나도 없어도 null은 아님. 
    	
    		while (rs.next()) {
    			String id = rs.getString("user_id");
    			String password = rs.getString("user_password");
    			String email = rs.getString("user_email");
    			String name = rs.getString("user_name");
    			String tel = rs.getString("user_tel");
    			int point = rs.getInt("user_point");
    			String disabled = rs.getString("user_disabled");
    			Date createdDate = rs.getDate("user_created_date");
    			Date updatedDate = rs.getDate("user_created_date");
    			
    			String text = MessageFormat.format("{0} {1} {2} {3} {4} {5} {6} {7} {8}",
    					id, password, email, name, tel, point, disabled, createdDate, updatedDate);
    			System.out.println(text);
    		}
    		
    		rs.close();
    		pstmt.close();
    		connection.close();
    	}
    
    }
    package day29;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.text.MessageFormat;
    
    public class DatabaseApp5 {
    
    	public static void main(String[] args) throws Exception {
    		
    		String sql = "select employee_id, first_name, job_id, salary, salary*12 as annual "
    				   + "from employees "
    				   + "where department_id = ? "
    				   + "order by employee_id asc ";
    		
    		Class.forName("oracle.jdbc.OracleDriver");
    		
    		String url = "jdbc:oracle:thin:@localhost:1521:xe";
    		String user = "hr";
    		String password = "zxcv1234";
    		Connection connection = DriverManager.getConnection(url, user, password);
    		
    		PreparedStatement pstmt = connection.prepareStatement(sql);
    		pstmt.setInt(1, 60);
    		
    		ResultSet rs = pstmt.executeQuery();  // 실행결과를 ResultSet에 담는다.
    		
    		while (rs.next()) {
    			int id = rs.getInt("employee_id");
    			String name = rs.getString("first_name");
    			String job = rs.getString("job_id");
    			double salary = rs.getDouble("salary");
    			double annualSalary = rs.getDouble("annual"); // 별칭 
    			
    			String text = MessageFormat.format("{0} {1} {2} {3} {4}", id, name, job, salary, annualSalary);
    			System.out.println(text);
    		}
    	}
    }

     

    실행결과 :

     

     

     

     

     

     

     

     

     

     

    '기록' 카테고리의 다른 글

    학원 day31. 조인  (0) 2022.10.19
    학원 day30. 오라클 내장함수, 데이터 타입  (0) 2022.10.18
    학원 DAY28. SQL  (0) 2022.10.15
    학원 DAY27. 데이터베이스, SQL  (0) 2022.10.15
    학원 DAY25~26. 예외 처리(2)  (0) 2022.10.12

    댓글

Designed by Tistory.