본문 바로가기
DBMS

[Oracle] 개요 & SQL문법

by amoomar 2022. 1. 19.
반응형

 

 

이번 포스팅에서는 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컬럼을 메인에 변수로 선언하여 메인에서도 간편하고, 자유롭게 접근할 수 있다.

 

 

 

 


 

반응형

'DBMS' 카테고리의 다른 글

[Oracle] 웹크롤링_기초  (0) 2022.01.24
[Oracle] 트랜잭션  (0) 2022.01.22
[Oracle] pstmt  (0) 2022.01.21
[Oracle] DB접근&MVC분리  (0) 2022.01.20
[Oracle] 설치와 오류  (0) 2022.01.18