DBMS

[Oracle] 개요 & SQL문법

amoomar 2022. 1. 19. 20:56
반응형

 

 

이번 포스팅에서는 DBMS의 개념, 유의사항과 같은 배경 이론과 JDBC를 활용한 테이블형 DB의 기본 작동과, 데이터 관리 실습에 대한 내용을 다루었다.

 

 

 

 


 

 

 

 

1. DBMS의 개념

 

1) What? : "DBMS란?"

: 데이터베이스를 관리해주는 프로그램 혹은 시스템이다. 본인의 블로그에서는 오라클을 사용하여 포스팅 될 예정이다.

 

2) Why? : "왜 존재하고, 왜 관리하는데?"

: 여러 사람들이 공유하여 사용하는 것을 목표로 하기 때문

 

 

3) How? : "어떤식으로 관리할건지?"

  1. 데이터의 구성 : 모델링. ex) 학번, 이름, 학과, 성적, 나이, 성별, 전화번호, 주소, ...
  2. 데이터의 사용 : SQL의 조작
  3. 데이터의 가공 : JDBC의 사용

 

4) DB를 다룰때 유의사항

  1. 중복제거 : 씽크가 맞지 않는 현상과 데이터 낭비를 방지해야한다. (ex. 학교 & 동아리에서의 학생정보관리 통일)
  2. 가용성을 상승시켜 관리 : 항상 접근 가능해야 한다. 사용자의 요청에 상시로 반응해야한다. (ex. 쇼핑몰재고부족)
  3. 기밀성 유지 : 이용자가 권한을 가지고 있는지 확인이 필요하다. (ex. 웹툰 유료분 볼 수 있는지 체크하는 과정)
  4. 무결성 유지 : 데이터의 변조를 막는 것

 

 

즉, DB를 다룰때 일관성, 무결성, 보안성유지를 유의해야하며, 이는 정보보호 3요소의 내용과도 연관이 깊다.

 

 

*정보보호 3요소(CIA)*

  1. Confidentiality 기밀성 : 허가된 사용자만 접근
  2. Integrity 무결성 : 허가된 사용자만,해당 대상에 대해서만 수정,삭제
  3. Availability 가용성 : 사용 필요시 항상 가능해야 함

 

 

 

 


 

 

 

2. 테이블형 DB_기초

 

1) 작업 전 처리

 

  1. 프로젝트에서 SQL파일 생성
    사진첨부
  2. connection의 Name을 변경하면 Type이 함께 전환되는 것을 확인할 수 있다.
    사진첨부
  3. [프로젝트 파일] -> 우클릭 -> [Properities]
    사진첨부
  4. [Java Build Path]탭 -> [Libraries] -> [Add External JARs...]클릭 -> 별도 설치한 "orcle6"연동! -> [Apply and Close]
    사진첨부

 

 

1, 2번의 작업은 매 SQL파일 생성시마다 진행 / 3, 4번의 작업은 Project파일에서 처음 SQL파일 생성시마다 진행해주어야 한다.

 

 

 


 

 

 

2) SQL파일 활용 기초_TableDB생성

  1. TableDB의 생성
    --주석처리의 방법이 상이한 것을 확인 가능--
    select * from all_tables;
    
    --TableDB 생성--
    create table student(
    	snum int primary key,
    	sname varchar (10)
    );
    
    --데이터 추가--
    insert into student values(1, '홍길동');
    insert into student values(2, '티모');
    
    --TableDB 조회--
    select * from student;
    varchar(문자열의 byte) : 문자열 1개에 약 2, 3byte정도로 계산이 된다. 입력받을 최대글자수를 염려하여 초기설정 할 것.
  2. 데이터 저장_조회를 위한 Results창 세팅
    우클릭 -> [Execute All]을 통하여 구성해놓은 Table에 지정한 데이터를 저장할 수 있다. 
    오른쪽 하단의 SQL Results창을 통해서 데이터의 상황을 확인하기 위해서는 해당 순서의 진행을 통해 view를 작동시켜야한다. "이클립스 상단의 [Window] -> [Show View] -> [Other] -> 'SQL Results'검색 -> 실행"
  3. 데이터 현황 조회_SQL파일에서의 명령어 수행
    단축키 [Alt + X]
    실행할 명령어를 드래그 한 후 Alt + X 입력을 통해 SQL파일에서 명령어 수행을 진행할 수 있다. 이때 출력명령어인 select * from 클래스명; 을 진행하면, 오른쪽 하단에 실행 성공 / 실패 유무와 Results창에서 현재 데이터 상황을 곧장 조회할 수 있다.

 

 

 


 

 

 

3) TableDB사용_기초

: 새로운 java파일을 생성하여 해당 파일에서 SQL파일 접근 및 접근한 데이터베이스를 사용하는 방법.

 

*DB 접근과 사용은 아래와 같이 4개의 단계로 진행된다.*

  1. DBMS에 맞는 드라이버 데이터 로드
  2. DB에 연결
  3. 데이터를 read, write
  4. ★DB와의 연결을 해제★ : 자원 낭비와 속도저하 방지 & 다음 연결에 문제 발생을 야기하므로 중요하다.

 

package class01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Test001 {

   public static void main(String[] args) {

      // 1. DBMS에 맞는 드라이버 데이터를 로드
      // 2. DB에 연결
      // 3. 데이터를 read,write
      // 4. DB와의 연결을 해제☆

      final String driverName="oracle.jdbc.driver.OracleDriver";
      //*하단 사진참고*
      final String url="jdbc:oracle:thin:@localhost:1521:xe"; 
      final String user="ham"; 
      final String passwd="1234";
       
      //이용범위를 고려한 배치
      Connection conn=null;
      Statement stmt=null;
      
      Scanner sc = new Scanner(System.in);
      System.out.println("학번입력 : ");
      int snum = sc.nextInt();
      System.out.println("이름입력 : ");
      String sname = sc.next();
      
      try {
         Class.forName(driverName); // -> 1
               
         conn=DriverManager.getConnection(url,user,passwd); // -> 2
      
         // -> 3
         stmt=conn.createStatement(); //데이터불러오기
         stmt.executeQuery("insert into student values(" + snum + ",'" + sname + "')");//작성하기
                  
         System.out.println("로그: 데이터 작성완료");
      } catch (ClassNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (SQLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } finally {
         try {
            stmt.close();
            conn.close(); // -> 4
         } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
      }
      
   }

}

 

 

finally는 오류의 유무와 상관없이 진행되는 부분이기에 그점을 활용하여 하단에 데이터를 닫는 작업을 진행한다. 즉, 오류와 상관없이 데이터는 사용후 바로 닫혀야한다.

 

 

[출력화면 : -> 입력]

학번입력 : 
3
이름입력 : 
왕밤빵
로그: 데이터 작성완료

 

[SQL Results]

정상작동 확인

 

 

 

* 사진참고 주석 : 데이터 불러오기를 위한 URL, User, Password 확인 *

  1. 오른쪽 하단의 New Oracle 우클릭 -> [Properties] 클릭
    2. Driver Properties탭에서 내용 확인

 

 

 

 


 

 

4) ResultSet_데이터 복사

: 성질이 Iterator와 유사하다. 데이터의 본체를 한칸씩 찍어서 복사해내는 개념이다. 복사하면서 출력해내는것도 가능하나, 보통의 경우 배열리스트를 사용하여 VO에 하나씩 옮겨 저장할 목적으로 사용된다.

package class01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Test02 {

	public static void main(String[] args) {
		final String driverName="oracle.jdbc.driver.OracleDriver";
		final String url="jdbc:oracle:thin:@localhost:1521:xe";
		final String user="ham";
		final String passwd="1234";
		// 컬럼:속성을 지정하게 되면 선택보기가 가능하다
		final String sql = "select * from student"; 

		Connection conn=null;
		Statement stmt=null;
		try {
			Class.forName(driverName); // -> 1

			conn=DriverManager.getConnection(url,user,passwd); // -> 2

			stmt=conn.createStatement(); // -> 3
			
			//ResultSet : 데이터 그 자체
			ResultSet rs = stmt.executeQuery(sql);
			while(rs.next()) { //rs에 값 있냐?
            			//있으면 rs에서 getInt("snum")가져와봐, 그리고 가져온거 출력해
				System.out.println("학번데이터 : "+rs.getInt("snum"));
				System.out.println("이름데이터 : "+rs.getString("sname"));
			}
			rs.close(); //알아서 닫히지만 그래도...!
			
			System.out.println("로그: 데이터 작성완료");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close(); // -> 4
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

 

 

이전 내용 대비 추가된 내용은 final String SQL변수 , ResultSet의 선언,  rs를 사용한 while문과 rs.close( );이다. 이때 rs.getInt : rs.getString메서드는 인자를 index로 두는 경우와 String으로 작성하는 것, 총 두가지로 오버로딩 되어있다. final String으로 지정해놓은 SQL변수의 포함영역에 따라 각각 사용할 수 있다.

 

  1. 인자가 index인 경우
    final String sql = "select snum, sname from student";
    
    ResultSet rs = stmt.executeQuery(sql);
    			while(rs.next()) {
    				System.out.println("학번데이터 : "+rs.getInt(1));//타입따라
    				System.out.println("이름데이터 : "+rs.getString(2));//타입따라
    			}
    			rs.close();​
    : 조회하는 sql이 *(All)이 아닐때 사용가능하며 기재된 순서대로 index가 1부터 부여된다. 아래 첨부된 사진과 같은 인자를 가진 메서드로 사용하면 되고, getint와 getString중 타입에 맞춰 사용하면 된다.
    메서드의 오버로딩을 확인할 수 있다.
  2.  인자가 String인 경우
    final String sql = "select * from student";
    
    ResultSet rs = stmt.executeQuery(sql);
    			while(rs.next()) {
    				System.out.println("학번데이터 : "+rs.getInt("snum"));//타입따라
    				System.out.println("이름데이터 : "+rs.getString("sname"));//타입따라
    			}
    			rs.close();​
    : 조회하는 sql이 *(all)일때 사용가능하다. 위의 서식과 같이 작성하면 된다.

getString (String columnLable) 으로 사용할 것

 

 

 

 


 

 

5) Iterator_데이터저장

: 위의 ResutlSet작업과 함께 진행되는 것이 일반적이다. 배열리스트를 통해 VO로 복사된 내용을 iterator를 통해 저장하고, 그것을 출력할 수 있다. 예제와 함께 설명이 진행된다.

 

Q. 상품을 2개 입력받고, 가격이 가장 비싼 제품명을 출력할 것

 

  1. Table DB
    select * from all_tables;
    
    create table product(
    	snum int primary key,
    	--제품명 길이를 고려한 byte설정--
    	sname varchar (20),
    	sprice int
    );
    
    insert into product values (1001, '엄청 긴팔티', 5000);
    insert into product values (1002, '후드 없는 티', 16000);
    
    select * from product;​
  2. main
    package class01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.Scanner;
    
    //VO의 역할
    class Product{
    	private int snum;
    	private String sname;
    	private int sprice;
    
    	public int getSnum() {
    		return snum;
    	}
    	public void setSnum(int snum) {
    		this.snum = snum;
    	}
    	public String getSname() {
    		return sname;
    	}
    	public void setSname(String sname) {
    		this.sname = sname;
    	}
    	public int getSprice() {
    		return sprice;
    	}
    	public void setSprice(int sprice) {
    		this.sprice = sprice;
    	}
    	//출력을 배열 출력을 대비한 오버라이딩
    	@Override
    	public String toString() {
    		return "Product [snum=" + snum + ", sname=" + sname + ", sprice=" + sprice + "]";
    	}
    
    }
    
    public class Test03 {
    
    	public static void main(String[] args) {
    
    		Scanner sc = new Scanner(System.in);
    		final String driverName = "oracle.jdbc.driver.OracleDriver";
    		final String url="jdbc:oracle:thin:@localhost:1521:xe";
    		final String user="ham";
    		final String passwd="1234";
    		//sql속성:칼럼 지정을 통해 -> 삽입과 출력을 각각 저장
    		final String sql_insert = "insert into product values (";
    		final String sql_select = "select sname,sprice from product";
    		//VO에 옮겨 담는데에 사용할 배열리스트
    		ArrayList<Product> datas=new ArrayList<Product>();
    
    		Connection conn = null;
    		Statement stmt = null;
    		try {
    			//1번째 데이터 불러오기 전 드라이버 불러오기
    			Class.forName(driverName);
    			//2번째 작업(변수는 상단에 선언)
    			conn = DriverManager.getConnection(url, user, passwd);
    			stmt = conn.createStatement();
    
    			for(int i=0; i<2; i++) { //상품 두번 추가받을거임
    				//입력받을 내용
    				System.out.println("상품번호 : ");
    				int snum = sc.nextInt();
    				System.out.println("상품명 : ");
    				String sname = sc.next();
    				System.out.println("가격 : ");
    				int sprice = sc.nextInt();
    				stmt.executeQuery(sql_insert+snum+", '"+sname+"', "+sprice+")");
    			}
    
    			//데이터를 하나씩 읊고, 그걸 하나씩 배열리스트에 담는 로직
    			ResultSet rs = stmt.executeQuery(sql_select);
    			while(rs.next()) {
               		 // 상품명 : 00원
    				System.out.println(rs.getString(1)+" : "+rs.getInt(2)+"원"); 
                    
    				//snum은 필요 없으니, name과 price만 배열에 담음
    				Product data = new Product();
    				data.setSname(rs.getString(1));
    				data.setSprice(rs.getInt(2));
    				datas.add(data);
    			}
    			rs.close();
    
    		} catch (Exception e) { //최상위 익셉션으로 수정
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			try {
    				stmt.close();
    				conn.close();
    			} catch (SQLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    
    		//최대값 찾는 로직 : 리스트 사용
    		int maxP=datas.get(0).getSprice();
    		int maxI=0;
    		for(int i=1;i<datas.size();i++) {
    			if(maxP<datas.get(i).getSprice()) {
    				maxP=datas.get(i).getSprice();
    				maxI=i;
    			}
    		}
    		//그리고 제일 비싼 제품명 출력
    		System.out.println(datas.get(maxI).getSname());
    
    	}
    }

 

 

(출력 및 데이터 결과 조회 생략)

 

 

 


 

 

3. 테이블DB_SQL속성 : 컬럼

 

1) 구성 기본 설정

: TableDB를 생성할때 구성에 필요한 지정값에 대한 내용이다.

 

create table student(
	snum int primary key,
	sname varchar (10) not null
	score int default 0,
    	--기본값 : 현재날짜--
	reg date default sysdate
);
  • primary key : 제약조건이다. 즉, null일 수 없으며, 유일해야한다. 
  • not null : 제약조건이다. 즉, null일 순 없으나 유일할 필요는 없다.
  • default : 자동으로 지정한 기본값을 넣어준다.

 

SQL파일에서는 대소문자를 구분하지 않아 카멜표기법을 사용하지 않는다. 

 


 

2) 구조변경

: alter을 활용하여 구성을 추가할 수 있으며, 지정한 varchar의 byte를 변경할 수 있다.

 

alter table student add(phone varchar(15));
alter table student modify(sname varchar(20));
  • alter add : 괄호에 담긴 내용을 구성에 추가할 수 있다.
  • alter modify : 지정한 구성의 byte 값을 변경할 수 있다. 

 

 

+값을 넣을 구성을 지정하고, 그 구성에 각각 값을 넣는 방법+

: 비울것은 비우며 선택적 입력이 가능하다.

 

insert into student (snum, sname, phone) values(4, 왕밤빵, 01012341234);
	    	    --값 넣을 구성 지정--         --각각 저장할 값 입력--

 

 

add를 통해 전화번호입력칸 생성이 되었으나,  데이터 조회시 전화번호 구성추가 이전에 생성된 애들은 다 phone조회 결과가 null이다. 때문에 가능한 구조조정이 없도록 설계해야한다.

 

 


 

3) 지정조회

: 원하는 구성만 선택하는것이 가능하다.

 

-- * : All --
select * from student;

--select 선택할 구성 form 클래스명--
select snum from student;
select sname from student;
select snum, sname from student;

--<데이터의 정렬 : varchar도 가능>--
select * from student order by snum desc;--오름차순--
select * from student order by snum asc;--내림차순--

--구성(멤버변수)의 총 개수--
select count(*) from student;

 

 

 

 

 


 

4) 조건절 

: 주로 검색할때 많이 사용된다.

 

--'아'로 시작하는 데이터--
select * from sudent where sname like '아%';
--'아'가 들어가는 데이터--
select * from sudent where sname like '&아%';
--'아'로 끝나는 데이터--
select * from sudent where sname like '%아';

--응용 : 3이상인 snum을 오름차순 정렬--
select * from student where snum >= 3 order by snum desc;

 

 

 

조건절을 활용하여 다양한 응용이 가능함을 확인할 수 있다.

 

 

 


5) 수정과 삭제

: 조건절이 활용되어 데이터의 수정이 가능해지며, 추가로 삭제 명령어도 확인해보자

 

-- 1snum의 sname을 a로 바꿔줘 --
update student set sname='a' where snum=1;

-- snum이 2이하인 데이터 전부 삭제 --
delete from student where snum<=2;

-- tableDB 자체 삭제:생성된 적 없듯이 --
drop table 클래스명;
  • update : 수정
  • delete : 데이터 삭제
  • drop : 테이블 삭제

6) pk++하여 삽입

: 위의 속성들을 응용하면 sum의 존재하는 데이터중 가장 큰 값+1을 하여 데이터를 추가할 수도 있다.

 

insert into student values((select nvl(max(snum),0)+1,from student),'티모');
			    --nvl(snum의 max가 null이라면, 0을 사용할게)--

DB에서는 자료형이 int라 해도, 입력되지 않은 값은 0이 아닌 null로 표시된다.

때문에 nvl(왼쪽의 값이 null이라면, 이쪽을 사용할게)의 사용이 필수이다.

 

 


sql컬럼을 메인에 변수로 선언하여 메인에서도 간편하고, 자유롭게 접근할 수 있다.

 

 

 

 


 

반응형