중복제거 : 씽크가 맞지 않는 현상과 데이터 낭비를 방지해야한다. (ex. 학교 & 동아리에서의 학생정보관리 통일)
가용성을 상승시켜 관리 : 항상 접근 가능해야 한다. 사용자의 요청에 상시로 반응해야한다. (ex. 쇼핑몰재고부족)
기밀성 유지 : 이용자가 권한을 가지고 있는지 확인이 필요하다. (ex. 웹툰 유료분 볼 수 있는지 체크하는 과정)
무결성 유지 : 데이터의 변조를 막는 것
즉, DB를 다룰때 일관성, 무결성, 보안성유지를 유의해야하며, 이는 정보보호 3요소의 내용과도 연관이 깊다.
*정보보호 3요소(CIA)*
Confidentiality 기밀성 : 허가된 사용자만 접근
Integrity 무결성 : 허가된 사용자만,해당 대상에 대해서만 수정,삭제
Availability 가용성 : 사용 필요시 항상 가능해야 함
2. 테이블형 DB_기초
1) 작업 전 처리
프로젝트에서 SQL파일 생성사진첨부
connection의 Name을 변경하면 Type이 함께 전환되는 것을 확인할 수 있다.사진첨부
[프로젝트 파일] -> 우클릭 -> [Properities]사진첨부
[Java Build Path]탭 -> [Libraries] -> [Add External JARs...]클릭 -> 별도 설치한 "orcle6"연동! -> [Apply and Close]사진첨부
1, 2번의 작업은 매 SQL파일 생성시마다 진행 / 3, 4번의 작업은 Project파일에서 처음 SQL파일 생성시마다 진행해주어야 한다.
2) SQL파일 활용 기초_TableDB생성
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정도로 계산이 된다. 입력받을 최대글자수를 염려하여 초기설정 할 것.
데이터 저장_조회를 위한 Results창 세팅우클릭 -> [Execute All]을 통하여 구성해놓은 Table에 지정한 데이터를 저장할 수 있다. 
오른쪽 하단의 SQL Results창을 통해서 데이터의 상황을 확인하기 위해서는 해당 순서의 진행을 통해 view를 작동시켜야한다. "이클립스 상단의 [Window] -> [Show View] -> [Other] -> 'SQL Results'검색 -> 실행"
데이터 현황 조회_SQL파일에서의 명령어 수행단축키 [Alt + X]
실행할 명령어를 드래그 한 후 Alt + X 입력을 통해 SQL파일에서 명령어 수행을 진행할 수 있다. 이때 출력명령어인 select * from 클래스명; 을 진행하면, 오른쪽 하단에 실행 성공 / 실패 유무와 Results창에서 현재 데이터 상황을 곧장 조회할 수 있다.
3) TableDB사용_기초
: 새로운 java파일을 생성하여 해당 파일에서 SQL파일 접근 및 접근한 데이터베이스를 사용하는 방법.
*DB 접근과 사용은 아래와 같이 4개의 단계로 진행된다.*
DBMS에 맞는 드라이버 데이터 로드
DB에 연결
데이터를 read, write
★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 확인 *
오른쪽 하단의 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변수의 포함영역에 따라 각각 사용할 수 있다.
: 위의 ResutlSet작업과 함께 진행되는 것이 일반적이다. 배열리스트를 통해 VO로 복사된 내용을 iterator를 통해 저장하고, 그것을 출력할 수 있다. 예제와 함께 설명이 진행된다.
Q. 상품을 2개 입력받고, 가격이 가장 비싼 제품명을 출력할 것
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;
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을 하여 데이터를 추가할 수도 있다.