■ 네트워크란 무엇인가?

※ 출처 : 따라하면서 배우는 IT

https://www.youtube.com/watch?v=Av9UFzl_wis&list=PL0d8NnikouEWcF1jJueLdjRIC4HsUlULi 

 

■ 요약

1. 네트워크란,

- 노드들이 데이터를 공유할 수 있게하는 디지털 전기통신망의 하나이다.

- 분산되어 있는 컴퓨터를 통신망으로 연결한 것

 

2. 인터넷이란,

- 전세계를 연결하는 가장 큰 네트워크

- WWW는 인터넷을 통해 웹과 관련된 데이터를 공유하는 것으로 인터넷과 다른 개념이다.

 

3. 네트워크는 크기/연결형태에 따라 여러 개의 분류로 나누어진다.

1) 크기 : LAN / WAN / MAN / 기타

▶ LAN(Local Area Network) : 근거리 통신망. 가까운 지역을 연결

- ex. PC방에서 친구와 스타크래프트를 LAN UDP로 연결

 WAN(Wide Area Network) : 멀리 떨어진 곳을 연결. 가까운 지역끼리 묶인 LAN과 LAN을 다시 하나로 묶은 것

- ex. 우리집에서 네이버와 연결

2) 연결 형태 : Star형, Mesh형

▶ Start형 : 주로 LAN대역(가까운 곳)에 있는 장치들끼리 연결할 때 사용한다.

* 공유기가 고장나면 나머지 장치들도 연결이 안 된다

▶ Mesh형 : 여러 장비들끼리 서로 그물처럼 연결

* 장치 하나가 고장이 나더라도 다른 장치들 전체에 영향을 미치지 않는다.

▶ 혼합형 : 여러 형태를 혼합한 형태로, 실제 인터넷은 혼합형으로 되어 있다.

 

4. 네트워크의 통신방식

유니캐스트 특정 대상과만 1 : 1로 통신
멀티캐스트 특정 다수와 1 : N으로 통신
브로드캐스트 네트워크에 있는 모든 대상과 통신

 

5. 네트워크 프로토콜

- 프로토콜이란, 일종의 약속 양식을 말한다.

- 네트워크에서 노드와 노드가 통신할 때

    어떤 노드가 어느 노드에게

    어떤 데이터를 어떻게 보내는지

   작성하기 위한 양식

 

5-1. 네트워크 프로토콜 종류

가까운 곳과 연락할 때 이더넷 프로토콜 (MAC 주소) 
멀리 있는 곳과 연락할 때 ICMP, IPv4, ARP (IP 주소)
여러가지 프로그램으로 연락할 때 TCP, UDP (포트 번호)

▶ 실제로 채팅창과 같은 프로그램을 쓸 때는 패킷 곧, 여러 개의 프로토콜을 캡슐화해서 사용한다.

 

란?

- FIFO (First in First Out) 방식으로 데이터를 입출력

- 현실 세계의 큐 예 )

    티켓 판매기에서 대기하고 있는 사람들,

    일방통행 도로의 차동자들, 인쇄기의 인쇄 순서, CPU의 테스크 스케줄링

- 큐의 한계 :

  1) front부터 삭제되며, 삭제된 공간을 다시는 사용하지 못한다. 

  2) (배열을 사용할 경우) 큐의 크기가 정해지기 때문에 rear가 더 움직이지 못한다.

     (-> 이 부분은 자바에서는 동적관리 객체인 LinkedList로 해결했다)

- 큐의 한계를 보완 : 원형 큐, 우선순위 큐

 

큐의 내부 구조

- 유투브의 영상에 나와있는 튜토리얼에 따라 큐를 구현해보았다. 

https://www.youtube.com/watch?v=W3jNbNGyjMs&list=PLjSkJdbr_gFZL2BNnGLvTgMYXptKGIyum&index=2 

☞ 확인 사항

- 큐는 데이터를 넣을 때 마지막에 넣고, 꺼낼 때는 앞에서부터 꺼낸다

  (1) offer을 할 때는 : REAR가 가리키는 것이 있을 때 ) REAR의 NEXT에 연결

                            FRONT가 가리키는 것이 없을 때(= 저장된 데이터의 사이즈가 0) )

                                FRONT와 REAR가 모두 null임을 명시한다.

  (2) poll을 할 때는 : FRONT가 가리키는 것이 없을 때 ) 꺼낼 수 없으므로 예외 (NoSuchElementException)를 발생

                           FRONT를 꺼낸 뒤 FRONT->NEXT를 FRONT로 변경

                           만약에 새로운 FRONT가 가리키는게 없을때(= 저장된 데이터의 사이즈가 0)

                               FRONT와 REAR가 모두 null임을 명시한다.

※ 자바의 경우 큐는 인터페이스며, LinkedList가 이를 구현하고 있다.

   아래의 실제 자바 Queue메소드는 LinkedList에서 사용 가능하다.
실제 자바 Queue 메소드 구현객체의 메소드 내용
offer(data) add(data) 데이터 추가
poll() remove() 가장 앞 데이터 꺼내기
peek() peek() 가장 앞 데이터 읽기
isEmpty() isEmpty() 비어있는지 확인

☞ 구현 하기

import java.util.NoSuchElementException;

class Queue<T>{
	
	class Node<T>{
		private T data;
		private Node<T> next;
		
		public Node(T data) {
			this.data = data;
		}
	}
	
	private Node<T> first;
	private Node<T> last;
	
	public void add(T item) {
		Node<T> t = new Node<T>(item);
		
		if (last != null) {
			last.next = t;
		}
		last = t;
		
		if (first == null) {
			first = last;
		}
	} 
	
	public T remove() {
		if (first == null) {
			throw new NoSuchElementException();
		}
		
		T data = first.data;
		first = first.next;
		
		if (first == null) {
			last = null;
		}
		return data;
	}
	
	public T peek() {
		if (first == null) {
			throw new NoSuchElementException();
		}
		return first.data;
	}
	
	public boolean isEmpty() {
		return first == null;
	}

}//end class Queue

 

■ 큐 알고리즘 예제

https://www.acmicpc.net/problem/2164

☞ 계획 수립

  [1] LinkedList를 사용하여 데이터를 하나씩 넣어준다.
  [2] 반복문을 통해 [1] poll [2] poll & offer을 반복한다.

☞ 계획 수행

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;

public class Ex01_2164_카드2 {

	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		int N = Integer.parseInt(reader.readLine());
		
		LinkedList<Integer> list = new LinkedList<Integer>();
		
	    //순서대로 1~N값 입력
		for (int i = 1; i <= N; i++) {
			list.offer(i);
		}
		
		//버리고, 밑으로 내리는 것 반복
		while (list.size() != 1) {			
			list.poll(); //첫번째로 꺼낸 것은 버린다.
			list.offer(list.poll()); //두번째로 꺼낸 것은 가장 마지막에 넣는다.
		}
		System.out.println(list.peek());
		
	}

}

- 여기까지는 문제가 어렵지 않았다.. 그런데 아래의 문제들을 만난 뒤 당황..

 

■ 원형 큐 (Circular Queue)의 원리를 사용한 알고리즘 문제

- 원형 큐의 개념 : 큐를 원형의 구조처럼 한 바퀴를 돌리며 사용하는 방식

☞ 계획 수립

  [1] LinkedList를 사용한다.
  [2] 이중 루프를 돌려,
      - 바깥에서는 큐가 빌 때까지 반복,
      - 안쪽에서는 K번째 전까지는 poll & offer을 반복하고, K번째에는 poll을 한다.
  [3] 출력은 StringBuffer를 사용한다.

 

☞ 계획 수행

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Ex02_11866_요세푸스문제1_원형큐사용 {

	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringBuffer buffer = new StringBuffer();
		StringTokenizer token = new StringTokenizer(reader.readLine());
		
		int N = Integer.parseInt(token.nextToken());
		int K = Integer.parseInt(token.nextToken());
		
		//1~N까지의 데이터를 담을 연결리스트
		Queue<Integer> queue = new LinkedList<Integer>();
		
		//1~N까지 데이터 채우기
		for (int i = 1; i <= N; i++) {
			queue.offer(i);
		}
		
		buffer.append("<");
		
		int count = 0;
		
		//큐가 더 이상 아무것도 없을 때까지 반복
		while (!queue.isEmpty()) {
			//K보다 작을 때까지 poll&offer을 반복
			for (int i = 1; i < K; i++) {
				queue.offer(queue.poll());
			}
			
			//K번째에 poll해서 buffer에 저장
			if (count == 0) {
				buffer.append(queue.poll());
				count++;
				continue;
			}
			
			buffer.append(", ").append(queue.poll()); 
			
		}//end while
		
		buffer.append(">");

		System.out.println(buffer);
		
	}
	
}

 

>> 결과

7 3
<3, 6, 2, 7, 5, 1, 4>

▼ 처음에 일반큐 + 배열 + 커서변수를 사용해서 예제를 풀었었다. 

    그렇게 하니 코드도 길고 내가 적고도 다른 사람에게 설명할 수 없는 코드가 만들어졌다.

    스터디 때 다른 팀원분이 원형큐에 대해 설명해주셔서 알아보고 다시 작성을 해보았는데

    원형큐를 사용하니 메모리 사용량은 더 많았어도 시간은 더 준 걸 볼 수 있었다.

 

 

[참조]

https://st-lab.tistory.com/184

https://velog.io/@delicate1290/%EB%B0%B1%EC%A4%80-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C-1158%EB%B2%88

'Computer Science > Algorithm' 카테고리의 다른 글

[정렬] 병합정렬(Merge Sort)  (0) 2022.05.11
[정렬] 퀵 정렬(Quick Sort)  (1) 2022.05.10
[자료구조] 스택  (0) 2022.04.18
[검색] 선형탐색과 이진탐색  (0) 2022.04.12
[자바의 정석] 스택과 큐  (0) 2022.03.30

■ 프로시저란?

- 어떤 업무를 수행하기 위한 절차로 자주 쓰는 명령을 절차적으로 지정해둔 형태

 

■ 함수와 프로시져의 차이점

https://mjn5027.tistory.com/47

 

[ Oracle ] 프로시저와 함수의 차이

오라클을 사용하다보면 자주 접하게 되는 프로시저와 함수. ​ 이 둘의 정의와 차이점에 대해 알아보자. 프로시저(Procedure)란? 넓은 의미로는 어떤 업무를 수행하기 위한 절차를 뜻한다. ​ 예를

mjn5027.tistory.com

 

■ 프로시져 코딩 예시

-- 수정
create or replace procedure book_update(v_name IN varchar2, v_price IN number, v_idx IN number)
is
begin
   UPDATE book SET name = v_name, price = v_price WHERE idx = v_idx;
   commit;
end;
/


--삭제
create or replace procedure book_delete(v_idx IN number)
is
begin
   DELETE from book WHERE idx = v_idx;
   commit;
end;
/

-- 추가
create or replace procedure book_insert(v_name IN varchar2, v_price IN number)
is
begin
   INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),v_name,v_price);
   commit;
end;
/

 

■ 명령 프롬프트에서 프로시저 생성 및 실행하는 법

 

 

■ CallableStatement를 사용하여 프로시져 구문 쓰기

- CallableStatement는 PreparedStatement를 상속한다.

package mymain;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
//import oracle.jdbc.driver.OracleDriver;

public class MyMain_DBTest2_프로시져 {
	
	//DB Driver Loading
	//메인 메소드가 시작되기 전에 먼저 0순위로 선작업.
	static {
		// 0. 객체가 생성 되기 이전에 클래스를 메모리에 적재 
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception{
		// 1. Connection을 얻어오기
		//(1) 연결경로, 사용자정보 가져오기
		//            jdbc:oracle:드라이버종류:@IP주소:포트:db아이디   <<- JavaEE에서 Data Source Explorer > Properties의 URL복사
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; 
		String user = "test1";
		String pwd  = "test1";
		
		//(2) Connection 인스턴스를 싱글톤 방식으로 가져온다.
		Connection conn = DriverManager.getConnection(url, user, pwd);
		System.out.println("---------Success Connection-------");
		
		//2. Procedure사용할 객체
		String sql = "call book_insert(?, ?)";
		CallableStatement cstmt = conn.prepareCall(sql);
		
		//3. Parameter
		cstmt.setString(1, "And");
		cstmt.setInt(2, 22000);
		
		//4. 실행
		cstmt.executeUpdate();
		
		//5. 닫기 (열린 역순)
		cstmt.close();
		conn.close();
		
	}

}

 

 

[출처]

함수와 프로시저의 차이 https://mjn5027.tistory.com/47

■ 컴파일러 버전 바꾸기

- [프로젝트] - 오른쪽마우스 - [Properties] - [Java Compiler] 

- 체크를 풀어주고, 버전을 변경한다.

 

■ Facet도 같이 바꿔야한다.

■ 스터디 방향성

- 5월-6월간 매주 일요일 오전 11시에 각 조원들이 아래 강의를 보고 네트워크/운영체제를 공부

 

1. 네트워크

- 개념 정리 포커스 : https://dev-coco.tistory.com/161?category=1056309 

 

신입 개발자 기술면접 질문 정리 - 네트워크

💡 HTTP 프로토콜에 대해 설명해주세요. HTTP(Hyper Text Transfer Protocol)이란 데이터를 주고 받기 위한 프로토콜이며, 서버/클라이언트 모델을 따릅니다. HTTP는 상태 정보를 저장하지 않는 Stateless의

dev-coco.tistory.com

- 강의 링크 : https://www.youtube.com/playlist?list=PL0d8NnikouEWcF1jJueLdjRIC4HsUlULi 

 

네트워크 기초(개정판)

OSI 7계층에서 각 계층의 다양한 프로토콜들을 통해서 배우는 네트워크 기초에 대한 강의입니다.

www.youtube.com

 

2. 운영체제

- 개념 정리 포커스 : https://dev-coco.tistory.com/162?category=1056309 

 

신입 개발자 기술면접 질문 정리 - 운영체제

💡 프로세스와 쓰레드의 차이에 대해 설명해주세요. 프로세스는 실행 중인 프로그램을 말하며, 완벽히 독립적이기 때문에 메모리 영역(Code, Data, Heap, Stack)을 다른 프로세스와 공유하지 않습니

dev-coco.tistory.com

- 강의 링크 : https://www.youtube.com/playlist?list=PLBrGAFAIyf5rby7QylRc6JxU5lzQ9c4tN 

 

[Course] Operating System (CPA310) - 운영체제 강의

o Operating System (운영체제), CPA310, KOREATECH o Instructor: Duksu Kim (김덕수) o Course homepage: https://sites.google.com/view/hpclab/courses/operating-system 운...

www.youtube.com

 

 

■ 자료 공유

- 각자 블로그 및 파일 등에 정리한 내용을 공유

- 궁금한 점이 있다면 채팅을 통해 나누는 방식

■ MVC 모델이란?

https://m.blog.naver.com/jhc9639/220967034588

구분 내용
모델 애플리케이션의 데이터를 담고 CRUD하는 객체 (DAO 객체)
데이타를 기반으로 사용자들이 볼 수 있는 화면
컨트롤러 데이터와 사용자인터페이스 요소들을 잇는 다리역할
 

[개발자 면접준비]#1. MVC패턴이란

오늘은 개발자면접에 많이 나오기도 하는 MVC패턴에 대해서 알아보고자 합니다. 과연 MVC패턴이 무엇...

blog.naver.com

 

■ DB 모듈화 전체 구성

* 화살표 방향은 무시하고 전체적인 흐름만 보세요.

 

■ Connection(서버연결) 관리 객체

  드라이버를 로딩하고, DB 서버와 연결하는 객체 

 

- DAO가 Connection 관리 객체에게 DB 연결

  곧, Connection을 요청하면, Connection 인스턴스를 DAO에게 전달한다.

 

[코드 예시]

package service;

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

public class DBservice {
	
	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버를 찾을 수 없습니다.");
		}
	}
	
	private static DBservice single = null;
	
	public static DBservice getInstance() {
		
		if (single == null) {
			single = new DBservice();
		}
		
		return single;
		
	}
	
	private DBservice(){
		
	}
	
	public Connection getConnection() throws SQLException{
		
		Connection conn = null;
		
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user = "test1";
		String pwd = "test1";
		
		conn = DriverManager.getConnection(url, user, pwd);
		
		return conn;
	}
	
}

 

■ VO (Value Object) : 칼럼의 맴버와 타입을 저장관리하는 객체

  DB의 테이블 칼럼을 필드맴버로 저장한 객체 

 

- 객체지향적으로 데이터의 속성 정보를 저장하는 객체이다.

- 일종의 구조체와 같아 보인다. 

   [Person이라는 객체 안에 name, age, addr]이 등록되는 것과 같이 객체의 속성을 저장한다.

 

Rf. 과거에 DTO (Data Tranfer Object) 라고도 불렀다.

    - VO는 읽기, DTO는 읽기/쓰기 모두 가능한 경우

 

[코드 예시]

package vo;

public class MemberVo {

	int ein;
	String name;
	String addr;
	String ssn; //주민번호
	int hireday;
	String id;
	String pwd;
	
	//Getter, Setter
	public int getEin() {
		return ein;
	}
	public void setEin(int ein) {
		this.ein = ein;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getSsn() {
		return ssn;
	}
	public void setSsn(String ssn) {
		this.ssn = ssn;
	}
	public int getHireday() {
		return hireday;
	}
	public void setHireday(int hireday) {
		this.hireday = hireday;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	
	
	
}

 

■ DAO (Data Access Object) - DB정보를 CRUD하는 객체

  데이터를 DB에서 불러와, LIST형태로 저장하는 객체   *데이터 CRUD 담당    

 

- 기능 : Create / Read/ Update / Delete

- 메서드 : insert / select / update / delete

 

   selectList()       -->   테이블의 리스트 정보를 선택하여 반환
   insert(VO)       -->   신규 레코드 삽입
   update(VO)     -->    기존 레코드 수정
   delete(칼럼명)  -->   칼럼 삭제

 

[코드 예시]

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import service.DBservice;
import vo.MemberVo;

public class MemberDao {
	
	private static MemberDao single = null;
	
	private MemberDao() {};
	
	public static MemberDao getInstance() {
		
		if (single == null) {
			single = new MemberDao();
		}
		
		return single;
	}
	
	public List<MemberVo> selectList(){
		
		List<MemberVo> list = new ArrayList<MemberVo>();
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = "SELECT * FROM member";
		
		try {
			conn = DBservice.getInstance().getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			
			while (rs.next()) {
				
				MemberVo vo = new MemberVo();
				
				vo.setEin(rs.getInt("ein"));
				vo.setName(rs.getString("name"));
				vo.setAddr(rs.getString("addr"));
				vo.setSsn(rs.getString("ssn"));
				vo.setHireday(Integer.parseInt(rs.getString("hireday"))+1900);
				vo.setId(rs.getString("id"));
				vo.setPwd(rs.getString("pwd"));
				
				list.add(vo);
				
			}
			
		} catch (Exception e) {
			
		} finally {
			try {
				if (rs != null) rs.close();
				if (pstmt != null) pstmt.close();
				if (conn != null) conn.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
		return list;
	}
	
}

 

■ SQL Injection

공격자가 악의적인 의도를 갖는 SQL 구문을 삽입하여, 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격 기법

 

▶ 해커의 해킹 방식

//아래의 SQL문에 항상 참인 값을 넣으면 모든 정보가 노출이된다.
String sql = "SELECT * FROM test_member WHERE id = 'test' AND pwd = '1234'" + "or 1 = 1";

- 위와 같은 방식으로 SQL구문을 삽입하여 DB를 조작하는 공격을 SQL 인젝션이라 한다.

- 해결 방법 : PreparedStatement를 사용한다.

 

■ Statement와 PreparedStatment의 차이점

  Statement PreparedStatement
차이점 캐시 미사용 캐시 사용
절차 쿼리 문장 분석
컴파일
실행
--> 계속해서 위 세단계를 반복
쿼리 문장 분석
컴파일
실행
-> 처음 한번만, 캐시에 담아 재사용
결론 보안 낮음, 성능 낮음 보안 높음, 성능 높음

 

■ PreparedStatement로 JDBC프로그래밍 하는 순서

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class _00_preparedStatement {

	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버 정보를 찾을 수 없습니다.");
		}
	}
	
	public static void main(String[] args) throws Exception{
		//1. 연결
		String url = "  /* url 정보 */";
		String user = "계정명";
		String pwd = "비밀번호";
		
		Connection conn = DriverManager.getConnection(url, user, pwd);
		
		//2. preparedStatement
		//1) SQL문에 '?'를 넣어 값을 넣을 parameter를 형성
		// parameter index   1        2
		//                   id = ?   pwd = ?  
		String sql = "SELECT * FROM test_member WHERE id = ? AND pwd = ?";
		
		//2) PreparedStatement안에 SQL문을 넣기
		PreparedStatement pstmt = conn.prepareStatement(sql);
		
		//3) SQL문의 parameter를 세팅한다.
		pstmt.setString(1, "사용자 아이디");
		pstmt.setString(2, "사용자 비밀번호");
		
		//3. 처리
		ResultSet rs = pstmt.executeQuery();
		
		while (rs.next()) {
			String name = rs.getString("name");
			String id = rs.getString("id");
			String password = rs.getString("pwd");
			
			System.out.printf("[%s]님의 아이디는 %s, 비밀번호는 %s\n",name,id,password);
		}
		
		//4. 닫기
		rs.close();
		pstmt.close();
		conn.close();
		
	}//end main

}

 

 

 

- 출처:

  - SQL인젝션 개념 https://dev-coco.tistory.com/158 [슬기로운 개발생활😃]

  - 캐시에 대한 자세한 내용 https://p829911.tistory.com/11

  - 그 외 ) 국비지원 수업 과정

- 참고 : 여기어때의 해킹 사건 https://show-me-the-money.tistory.com/entry/%EC%97%AC%EA%B8%B0-%EC%96%B4%EB%95%8C-%ED%95%B4%ED%82%B9-%EC%82%AC%EA%B1%B4%EC%9D%84-%ED%8C%8C%ED%97%A4%EC%B9%98%EB%8B%A4

■ JDBC란?
- 자바 APP과 DB를 연결하여 프로그래밍을 하기 위한 API (또는 이클립스에선 라이브러리라고도 부른다)
- 물리적으로는 jdbcXX.jar 파일을 의미한다.
- 우리는 jdbc.jar안의 드라이버를 통해 모든 종류의 데이터베이스를 사용할 수 있다. (EX. 오라클, mySql 등)

출처 :&amp;nbsp;https://dyjung.tistory.com/50

■ 데이터베이스를 연결하기 전에 점검할 사항

1. 현재 내가 만들고자 하는 앱은 무엇인가?
- 데스크탑 앱 : 로컬에서 설치, 실행되는 앱 프로그램
- 웹 앱 : 브라우저를 통해 실행되는 앱 프로그램

2. 현재 내가 접속하고자 하는 DB 서버의 위치는 어디인가?
- 로컬 서버인가?
- 외부 클라우드 서버인가?
* DB 서버와의 연결 시, 서버 url과 사용자명, 비밀번호가 필요하기에 미리 알아두는 것이 좋다.

3. IDE를 사용하고 있고 jdbc.jar파일 경로를 입력한 적이 있다면, 라이브러리 경로가 제대로 입력되어 있는가?
- 이클립스에 jdbc.jar 파일을 import하고 경로를 옮기면 이클립스는 옮긴 jar파일 경로를 인식하지 못한다.
- 이런 경우, 프로젝트의 [properties] - [Libraries] 에서 jar파일 위치를 재설정하는 게 필요하다.
- 자주 발생하는 미스사항이므로 미리 고려해두자.

+ 이클립스에서 처음 프로젝트를 생성할 때, JRE 버전 확인하기
- JRE 버전을 높히고 다시 낮추었을 때, jdbc.jar의 위치를 인식하지 못하는 오류가 있었다.
(이유는 구글링을 해도 나오지 않아 명확하진 않지만...)
- 처음 프로젝트를 생성할 때부터 JRE 버전을 유의해서 생성하는 게 필요하다.


■ JDBC 프로그래밍을 위한 환경설정

- 프로젝트 생성 시, jdbc.jar파일 경로를 입력하기

프로젝트 > [Build Path] > [Configure Build Path]


■ JDBC 프로그래밍 절차

[ Statement를 사용한 경우 ]
- Statement는 보안성 낮다
- Secure Coding을 위해 PreparedStatement를 사용하는게 좋다. (다음 포스팅 참조)

1. DB 드라이버 로딩

2. Connection 객체를 통해 서버와 연결

3. Statement 객체를 통해 SQL명령 처리
가. SQL 명령어 세팅 : String sql = "select * from table_test";
나. SQL 명령 -> DB전송
: conn.executeQuery(sql)
- 조회 제외 : executeUpdate() 메소드 사용
- 조회 명령 : executeQuery() 메소드 사용
다. 명령에 따라 구분 분석(Parsing)
라. 실행
- 조회 제외 : create, alter, update... 등 실행
- 조회 경우 : ResultSet 객체를 통해 조회 결과를 담아 처리

4. close() 메소드를 통해 연결 해제
*연결 해제는 연결한 순서의 역순으로 해제한다.


[1] DB 드라이버 로딩

class Unknown{

    static {
	     Class.forName("  /*  DB 드라이버 이름   */  ");
    }

    /*  메인 메소드 * /

}
  - 오라클 : oracle.jdbc.driver.OracleDriver
  - MySQL : com.mysql.jdbc.Driver

 

▼ 위와 같이 드라이버 로딩을 하는 이유는? - 더보기 선택

더보기

- jdbc.jar 파일을 가져오면 라이브러리를 쓸 수 있는 상태가 된다.

- 자바 라이브러리처럼, jdbc 라이브러리에서 제공하는 클래스들이 있는데,

  그 중에 하나가 OracleDriver이다.

- 라이브러리만 가져온다고 클래스 내의 기능을 쓸 수 있는 것은 아니기 때문에, OracleDriver 클래스를 사용하기 위하여 드라이버 로딩을 해주는 것이다.

 


[2] Connection 인스턴스를 통해 서버와 연결

import java.sql.Connection;
import java.sql.DriverManager;

class Unknown{

    static {
	     Class.forName("  /*  DB 드라이버 이름   */  ");
    }

    public static void main(String args[]){
         //서버 url, user, pwd 정보 가져오기
         String url = " /* 서버 연결 정보 */ ";
         String user = "계정명";
         String pwd = "비밀번호";  //좌측처럼 민감번호는 코드에 노출하면X (시큐어 코딩)
         
         //DriverManager 객체를 통해 Connection 인스턴스 형성(싱글톤 방식)
         Connection conn = DriverManager.getConnection(url, user, pwd);
    }

}

* 이클립스 내에서 아래 서버 연결 정보는 [Database Connections] - [Properties] - [Driver Properties]에서 얻을 수 있다.

양식 jdbc:[DBMS]:[데이터베이스식별자]
Oracle jdbc:oracle:드라이버종류:@호스트명:포트명:SID
MySQL jdbc:sqlserver://호스트명:포트명;databaseName=DB


[3] Statement (또는 PreparedStatement *이 부분은 다음 포스트에서) 인스턴스를 사용하여
- Statement는 보안성 낮다. 중요하니 다시 안내

아래의 코드는 조회를 한 경우 이나, Statement의 execureUpdate() 메소드를 사용하면 그 외의 명령도 수행할 수 있다.
import java.sql.Connection;
import java.sql.DriverManager;

class Unknown{

    static {
	     Class.forName("  /*  DB 드라이버 이름   */  ");
    }

    public static void main(String args[]){
         //1. [연결]
         //서버 url, user, pwd 정보 가져오기
         String url = " /* 서버 연결 정보 */ ";
         String user = "계정명";
         String pwd = "비밀번호";  //좌측처럼 민감번호는 코드에 노출하면X (시큐어 코딩)
         
         //DriverManager를 통해 Connection 인스턴스 형성(싱글톤 방식)
         Connection conn = DriverManager.getConnection(url, user, pwd);
         
         //2. [Statement]
        
         //가. SQL문 세팅
         String sql = " /* SQL문 */ ";
         
         //나. SQL명령 -> DB전송
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql); //DB상에서 구분분석 후, 받은 결과
         
         //다. 실행
         //ResultSet는 커서 역할을 하며, 파일의 BOF에서 EOF까지 가리킨다.
         //.next()는 커서가 가리키는 곳에 레코드가 있음을 true or false로 반환한다.
         while(rs.next()){
             String name = rs.getString("name"); // 칼럼의 헤딩
             int score = rs.getInt("score"); 
             
             system.out.println(name + ":" + score);
         }
         
    }

}


[4] 사용한 것을 역순으로 닫는다.

import java.sql.Connection;
import java.sql.DriverManager;

class Unknown{

    static {
	     Class.forName("  /*  DB 드라이버 이름   */  ");
    }

    public static void main(String args[]){
         //1. [연결]
         //서버 url, user, pwd 정보 가져오기
         String url = " /* 서버 연결 정보 */ ";
         String user = "계정명";
         String pwd = "비밀번호";  //좌측처럼 민감번호는 코드에 노출하면X (시큐어 코딩)
         
         //DriverManager를 통해 Connection 인스턴스 형성(싱글톤 방식)
         Connection conn = DriverManager.getConnection(url, user, pwd);
         
         //2. [Statement]
        
         //가. SQL문 세팅
         String sql = " /* SQL문 */ ";
         
         //나. SQL명령 -> DB전송
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql); //DB상에서 구분분석 후, 받은 결과
         
         //다. 실행
         //ResultSet는 커서 역할을 하며, 파일의 BOF에서 EOF까지 가리킨다.
         //.next()는 커서가 가리키는 곳에 레코드가 있음을 true or false로 반환한다.
         while(rs.next()){
             String name = rs.getString("name"); // 칼럼의 헤딩
             int score = rs.getInt("score"); 
             
             system.out.println(name + ":" + score);
         }
         
         //3. [역순으로 닫는다]
         rs.close();
         stmt.close();
         conn.close();
         
    }

}



[출처]
- JDBC https://dyjung.tistory.com/50
- 데스크탑 앱 또는 웹 앱 https://appmaster.io/ko/blog/deseukeutab-aeb-ddoneun-web-aeb-jangdanjeom

■ 데이터의 무결성

- 데이터가 실제 현실 세계의 자료와 차이가 없는 수준의 정확성을 보이는 것

- 여러 사용자가 동일 내용의 테이블을 중복하여 사용할 경우, 데이터에 이상현상 발생 가능성 높음

-> 제약조건으로 데이터 자체의 무결성 유지

-> 정규화를 사용하여 테이블을 분해

-> 동기화

 

■ 조인

- 정규화한 테이블을 역정규화하는 키워드

- 원리 : 각 테이블의 Key를 사용하여 연결한다. 

- 장점 : 중복된 레코드 수를 줄인다. 이상현상을 방지하고 성능이 높아진다.

  1) 오라클 조인      - WHERE를 사용한 방법
  2) 공통 SQL 조인   - ANSI 방식

 

■ 조인의 종류

종류  
INNER  JOIN 조인 조건(두 테이블의 키)에 일치하는 데이터만 가져온다.
OUTER JOIN 조인 조건에 일치하는 데이터 및 일치하지 않는 데이터 모두 가져온다.
*일치하지 않는 데이터는 : NULL로 가져온다.
CROSS JOIN 별도의 조인 조건 없이 두 테이블을 조언 시 가능한 모든 경우의 데이터를 가져온다.
SELF    JOIN 자기 자신을 하나의 테이블로 취급하여 조인하는 방법
*칼럼명이 중복되므로 반드시 ALIAS를 사용하여 조인 필요

 

■ ANSI 조인

 

  INNER JOIN  

SELECT 
  a.APPLY_NO AS 순번,
  c.COM_NAME AS 기업명,
  c.COM_CAT AS 기업분야,
  c.COM_FOCUS AS 주력요소,
  TO_CHAR(a.APPLY_DATE, 'YYYY-MM-DD') AS 지원일자,
  a.APPLY_STATE AS 지원상태
FROM MY_APPLY a INNER JOIN COMPANY c
     ON a.APPLY_NO = c.APPLY_NO;

>> 결과

 

  OUTER JOIN  

 

  LEFT OUTER JOIN    

- 좌측테이블을 기준으로 조건에 일치하는 데이터 추출, 조건에 맞지 않으면 NULL

SELECT
  c.COM_NO AS 순번,
  c.COM_NAME AS 기업명,
  w.SALARY AS 연봉,
  w.OVERTIME_PAY AS 야근수당,
  W.FACILITY AS 시설
FROM COMPANY c LEFT OUTER JOIN WORK_ENV w
     ON c.COM_NO = w.COM_NO;

>> 결과

  RIGHT OUTER JOIN    

- 우측테이블을 기준으로 조건에 일치하는 데이터 추출, 조건에 맞지 않으면 NULL

SELECT
  c.COM_NO AS 순번,
  c.COM_NAME AS 기업명,
  w.SALARY AS 연봉,
  w.OVERTIME_PAY AS 야근수당,
  W.FACILITY AS 시설
FROM WORK_ENV w RIGHT OUTER JOIN COMPANY c
     ON w.COM_NO = c.COM_NO;

>> 결과

 

  CROSS JOIN  

SELECT
  c.COM_NO AS 순번,
  c.COM_NAME AS 기업명,
  w.SALARY AS 연봉,
  w.OVERTIME_PAY AS 야근수당,
  W.FACILITY AS 시설
FROM WORK_ENV w CROSS JOIN COMPANY c

>> 결과

- 심플컴패니2에 해당되는 연봉, 야근수당, 시설을 입력한 적이 없는데, 심플컴패니에 해당되는 부분이 추출됐다.

 

  SELF JOIN  

- 반드시 ALIAS를 써서 자기 자신의 테이블을 구분할 수 있게 해야한다.

SELECT
  c.COM_NO AS 순번,
  c2.COM_NAME AS 회사명,
  c2.COM_CAT AS 카테고리
FROM COMPANY c JOIN COMPANY c2
     ON c.COM_NO = c2.COM_NO;

>> 결과

 

■ 오라클 조인  ---- WHERE를 사용한다.

 

  INNER JOIN  

SELECT
  a.APPLY_NO AS 순번,
  c.COM_NAME AS 기업명,
  c.COM_CAT AS 기업분야,
  c.COM_FOCUS AS 주력요소,
  TO_CHAR(a.APPLY_DATE, 'YYYY-MM-DD') AS 지원일자,
  a.APPLY_STATE AS 지원상태
FROM MY_APPLY a, COMPANY c
WHERE a.APPLY_NO = c.APPLY_NO;

 

  OUTER JOIN  

 

  LEFT OUTER JOIN    

SELECT
  c.COM_NO AS 순번,
  c.COM_NAME AS 기업명,
  w.SALARY AS 연봉,
  w.OVERTIME_PAY AS 야근수당,
  W.FACILITY AS 시설
FROM COMPANY c, WORK_ENV w
WHERE c.COM_NO = w.COM_NO;

  RIGHT OUTER JOIN    

SELECT
  c.COM_NO AS 순번,
  c.COM_NAME AS 기업명,
  w.SALARY AS 연봉,
  w.OVERTIME_PAY AS 야근수당,
  W.FACILITY AS 시설
FROM WORK_ENV w, COMPANY c
WHERE w.COM_NO = c.COM_NO;

 

 

[출처]

- 뉴렉처 강의

- https://tragramming.tistory.com/74

+ Recent posts