CROSS JOIN은 두 테이블의 ROW간 가능한 모든 조합을 결과로 반환하며,

이러한 CROSS JOIN의 특징을 '카티션의 곱'이라고도 합니다.

 

 


 

간단한 CROSS JOIN의 예시 코드입니다.

 

employees 테이블과 departments 테이블을 CROSS JOIN합니다.

 

SELECT
    COUNT(*)
FROM
    employees;

SELECT
    COUNT(*)
FROM
    departments;

 

먼저 각 테이블의 Row를 COUNT( * )로 조회합니다.

 

SQL

 

 

CROSS JOIN에 대한 간단한 쿼리입니다.

 

-- Oracle JOIN --

SELECT
    *
FROM
    employees,
    departments;
    

-- Ansi JOIN --

SELECT
    *
FROM
    employees CROSS JOIN departments;

 

 

 

결과는 두 테이블 Row들의 카티션의 곱즉, 107 * 27 = 2889개입니다.

 

SQL

 

만약 결과가 뜨지 않는다면 VScode의 Oracle Developer Setting에서 Max Row를 높여주시면 됩니다.

일반적으로 500개로 제한되어 있습니다.

 

 

 

 

 

 

 

 

 

'Database > SQL' 카테고리의 다른 글

그룹화  (0) 2023.08.17
인라인 뷰  (0) 2023.08.17
외래 키  (1) 2023.08.16
데이터 사전  (0) 2023.08.16
동등 조인  (0) 2023.07.26

 

 

 

JAVA 8부터 함수적 프로그래밍을 위해 람다식(Lambda Expression)을 지원합니다.

익명구현객체 코딩기법에 비해 코드가 매우 간결해지고,

컬렉션 요소(대용량 데이터)를 필터링하거나 매핑을 해서 쉽게 집계할 수 있습니다.

 

 


 

 

람다식에서는 두 가지 용어가 있습니다.

 

  1. 타겟 타입(Target Type)
    타겟 타입은 람다식으로 구현할 함수적 인터페이스(Functional Interface)를 의미합니다.

  2. 함수적 인터페이스(Functional Interface)
    자바 8이상부터 @FuntionalInterface 어노테이션을 통해 함수적 인터페이스를 정의할 수 있습니다.
    추상메서드가 1개라면, 함수적 인터페이스이지만 어노테이션을 붙이는 이유는
    컴파일러가 컴파일 시에 검사할 수 있도록 하기 위함입니다.

 

 

람다식은 이러한 함수적 인터페이스를 implements 합니다.

implements하는 함수적 인터페이스를 람다식의 타겟 타입(Target Type)이라고 합니다.

 

람다식이 구현하는 익명함수는 익명구현객체와 비슷하지만 약간의 차이가 있습니다.

익명함수는 1개의 추상 메서드만 재정의하지만,

익명구현객체는 추상 메서드의 갯수에 대한 제한이 없습니다.

 

 

여기서 "익명"이란 이름이 없는 것이 아니라 이름을 모르는 것을 의미합니다.

그렇다면, 익명구현객체를 찍어낸 인터페이스는 추상메서드의 개수에 제한이 없습니다.

 

다음은 간단한 람다식 구현 코드입니다.

 

@FunctionalInterface
interface ICalculator {
    public abstract int add(int number1, int number2) throws Exception; // 덧셈
	
} // end Interface

 

@Log4j2
public class App {

	
    // ICalculator 인터페이스를 구현(Implements)
    public static void main(String[] args) throws Exception {
		
        ICalculator calc = (int number1, int number2) -> {
            return number1 + number2;
        };

    } // main

} // end class

 

 

위의 실행 클래스는 생략 전 add() 메서드입니다.

람다식은 여기서 파라미터의 타입을 제거할 수 있습니다.

 

 

@Log4j2
public class App {

	
    // ICalculator 인터페이스를 구현(Implements)
    public static void main(String[] args) throws Exception {
		
        // 생략 전
        //ICalculator calc = (int number1, int number2) -> {
        //    return number1 + number2;
        //};
        
        
        ICalculator calc = (number1, number2) -> {
            return number1 + number2;
        };

    } // main

} // end class

 

 

만약 파라미터가 1개라면 소괄호를 생략할 수 있습니다.

기존에 생성했던 함수적 인터페이스에서 추상 메서드의 파라미터 또한 수정해야 합니다.

 

 

@Log4j2
public class App {

	
    // ICalculator 인터페이스를 구현(Implements)
    public static void main(String[] args) throws Exception {
		
        // 생략 전
        // ICalculator calc = (int number1, int number2) -> {
        //     return number1 + number2;
        // };
        
        // 파라미터 타입 생략
        // ICalculator calc = (number1, number2) -> {
        //    return number1 + number2;
        // };
        
        // 파라미터가 1개일 때, 소괄호 생략 가능
        ICalculator calc = number1 -> {
            return number1 + 100;
        };

    } // main

} // end class

 

 

여기서 중괄호 블록안에 return문만 있을 경우, 중괄호 블록과 return 키워드까지 생략해야 합니다.

 

 

@Log4j2
public class App {

	
    // ICalculator 인터페이스를 구현(Implements)
    public static void main(String[] args) throws Exception {
		
        // 생략 전
        // ICalculator calc = (int number1, int number2) -> {
        //     return number1 + number2;
        // };
        
        // 파라미터 타입 생략
        // ICalculator calc = (number1, number2) -> {
        //     return number1 + number2;
        // };
        
        // 파라미터가 1개일 때, 소괄호 생략
        // ICalculator calc = number1 -> {
        //     return number1 + 100;
        // };
        
        // return키워드, 중괄호 블록 생략
        ICalculator calc = number1 -> number1 + 100;
        
        

    } // main

} // end class

 

 

최종적으로 생략된 코드에서

  • number1 : 파라미터 선언부
  • number + 1 : 메서드 구현부

 

입니다.

 

 

 

 

 

 

 

 

 

Oracle SQL Developer는 Oracle 공식 홈페이지에서 다운로드 후 설치합니다.

 

 

Oracle SQL Developer

 

 

일반적으로 Oracle DB의 버전과 맞추는 게 좋지만, 없다면 가장 최신 버전으로 다운로드합니다.

 

 

다운로드 후, 7zip으로 압축 해제합니다.

알집이나 반디집은 제대로 풀리지 않아서 권고하지 않습니다.

 

 

다운로드 주소는 다음 글을 참조해주세요.

 

[개발자 환경설정/오라클] - 오라클 DB 및 SQL Developer 다운로드 [23.08]

 

 

 

 

 

 

 

 

PowerShell로 DB를 컨트롤 하다보면 오류가 발생하고 PowerShell은 에러코드를 반환합니다.

 

이런 에러코드를 받았을 때, 다음의 명령어로 원인과 해결방법을 확인할 수 있습니다.

에러코드를 입력할 때는 CDB접속 상태가 아닌 비접속 상태에서 해야 합니다.

 

oerr ora 00000

 

 

'00000'에 PowerShell에서 반환하는 오류코드를 입력해서 확인하면 됩니다.

 

oerr

 

 

 

 

TreeSet과 TreeMap은 계층 구조를 활용해서 검색 기능을 강화시킨 컬렉션입니다.

이 컬렉션에 나오는 자료구조인 이진 트리의 내부 구조를 알고 있어야 API를 사용할 수 있습니다.

간단히 개념만 설명하면, 루트 노드를 정하고, 대소 비교를 통해 크면 오른쪽, 작으면 왼쪽으로 비교하며 위치하게 됩니다.

 

SQL에서 SELECT문을 통한 JOIN이나 복잡한 쿼리로 데이터를 조회할 때, 인덱스를 이용합니다.

이 때, 이진 트리의 구조와 개념을 제대로 알고 사용하면 많은 도움이 될 수 있습니다.

 

 


 

1. 트리 셋( TreeSet )

TreeSet은 이진 트리(binary tree)를 기반으로 한 Set 컬렉션입니다.

좌, 우 자식 노드를 참조하기 위한 두 개의 변수로 구성됩니다.

 

 

다음은 주요 메서드입니다.

 

  • 특정 객체를 찾는 메서드 : fist(), last(), lower(), higher() 등
  • 정렬 메서드 : descendingiterator(), descendingSet()
  • 범위 검색 메서드 : headSet(), tailSet(), subSet()

 

숫자에 대한 TreeSet은 간단하므로, 다루지 않고 String으로 넘어가겠습니다.

다음은 간단한 예시 코드입니다.

 

@Log4j2
public class TreeSetExample {

	
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>();
		
        treeSet.add("apple");
        treeSet.add("forever");
        treeSet.add("description");
        treeSet.add("ever");
        treeSet.add("zoo");
        treeSet.add("base");
        treeSet.add("guess");
        treeSet.add("cherry");
		
        log.info("**** [c~f 사이의 단어 검색] ****");
		
        // 부분범위(Sub-range Search) 검색 수행
        NavigableSet<String> rangeSet = treeSet.subSet("cherry", true, "forever", true);
        rangeSet.forEach(log::info);
		
    } // main
	
} // end class

 

subSet에 boolean은 해당 문자열을 포함할 것인지를 결정하게 합니다.

문자열의 맨처음 문자만 넣으면 boolean의 사용의미가 없어지므로, 반드시 문자열을 넣어야 합니다.

 

 

 

1. 트리 맵( TreeMap )

TreeMap은 이진 트리(binary Tree)를 기반으로 한 Map 컬렉션입니다.

키와 값이 저장된 Map.Entry를 저장하며 좌, 우 자식 노드를 참조하기 위한 두 개의 변수로 구성됩니다.

 

다음은 주요 메서드입니다.

 

  • 특정 객체를 찾는 메서드 : fistEntry(), lastEntry(), lowerEntry(), higherEntry() 등
  • 정렬 메서드 : descendingKeySet(), descendingMap()
  • 범위 검색 메서드 : headMap(), tailMap(), subMap()

 

TreeMap은 TreeSet과 비슷한 구성을 가지고 있으므로 따로 다루지 않겠습니다.

 

 

 

 

'Java > Collection Framework' 카테고리의 다른 글

맵 컬렉션  (0) 2023.08.03
셋 컬렉션  (0) 2023.08.03
리스트 컬렉션  (0) 2023.08.02
컬렉션 프레임워크 개요  (0) 2023.08.02

 

 

사용자는 Oracle DB Server에 접속하는 두 가지 방식이 있습니다.

 

 


 

** 접속 전 리스너 상태 확인 **

더보기

 

접속을 하기 전에 리스너가 활성화 상태인지 확인하기 위해 다음의 명령어를 입력합니다.

이 파트의 명령어는 반드시 관리자 모드에서 실행해주세요.

 

lsnrctl status
lsnrctl status


활성화 되어 있지 않다면 다음의 명령어를 입력하고 다시 확인합니다.

lsnrctl start
lsnrctl status

 

lsnrctl start



lsnrctl status 명령어로 동작 확인 후 

'tnsping'명령어로 해당 Oracle Listener를 통해 원하는 DB에 접속 가능한 지 테스트를 수행합니다.

 

tnsping User-2023QMKPJX:1521/seoul 10

 

tnsping

 

 

 

 


 

 

 

1. TNSNAME

TNSNAME 방식은 개발자가 주로 사용하는 방식입니다.

세 가지 접속정보(IP주소, 포트번호, DB이름)를 하나의 이름으로 표시합니다.

 

다음은 명령어 예시입니다.

 

sqlplus sys/비밀번호@DB이름 as sysdba

 

위 명령어처럼 TNSNAME을 사용하면 대소문자를 구분하지 않습니다.

 

TNSNAME을 확인하는 방법은 tnsnames.ora 파일에서 확인하실 수 있습니다.

tnsnames.ora 파일은 일반적으로 오라클 설치 폴더안에 network/admin에 위치해 있습니다.

저의 tnsnames.ora 파일은 다음의 위치에 있습니다.

 

C:\u01\oracle\product\19.3.0\dbhome\network\admin

 

tnsnames.ora

 

tnsnames.ora 파일에 들어가면 TNSNAME을 확인할 수 있습니다.

 

TNSNAME in tnsnames.ora

 

저는 KOREA와 SEOUL이 TNSNAME으로 설정되어 있습니다.

TNSNAME은 대소문자를 구분하지 않으므로 접속할 때, 신경쓰지 않아도 괜찮습니다.

이제 위의 접속정보를 가지고 Oracle DB에 접속합니다.

 

sqlplus sys/비밀번호@KOREA as sysdba

 

TNSNAME

 

간단하게 접속할 수 있습니다.

 

 

2. EZCONNECT

EZCONNECT 방식은 잘 사용하지는 않지만 알아두면 좋습니다.

TNSNAME 방식이 세 가지 접속정보를 하나의 이름으로 표시한다면,

EZCONNECT 방식은 이 세 가지 접속정보를 직접 지정하는 방식입니다.

 

tnsnames.ora 파일에서 접속정보, 즉 IP주소, 포트번호, DB이름을 직접 지정합니다.

 

sqlplus sys/비밀번호@IP주소나 호스트이름:포트번호/korea as sysdba

 

EZCONNECT

 

유저 이름은 tnsnames.ora파일 이외에도 'hostname' 명령어로 알 수 있습니다.

 

 

 

 

 

 

 

 

Oracle Instance Client는 간단히 말해,

사용자가 데이터베이스에 CRUD(CREATE, READ, UPDATE, DELET)할 수 있도록 도와주는 역할을 합니다.

Oracle Instance Client SQL*plus사용자가 데이터베이스를 관리하고 쿼리를 보낼 때 사용하는 명령줄 인터페이스입니다.

 

 

Oracle Instance ClientOracle Instance Client SQLplus는 scoop으로 설치합니다.

 

 

PowerShell에 oracle을 검색합니다

 

 

scoop search oracle

 

오라클 클라이언트

 

위의 패키지 중 oracle-instant-client oracle-instant-client-sqlplus를 설치합니다.

반드시 검색 후, 해당 패키지가 있는지 확인하고 설치해야 합니다.

 

scoop install oracle-instant-client
scoop install oracle-instant-client-sqlplus

 

 

 


 

 

 

# OCI 직접 설치

 

 

구글에서 Oracle SQL cl download를 검색합니다.

 

 

3번째 글에 들어갑니다.

 

 

 

 

이전 버전이 필요하다면 Previous Version을 클릭하여 찾을 수 있습니다.

저는 19c를 사용하고 있으므로 SQLcl 20.2를 다운로드 하였습니다.

 

 

다운로드를 하고 SQLcl과 jdk에 대한 환경변수를 설정해야 합니다.

 

PowerShell에 sysdm.cpl을 입력합니다.

 

sysdm.cpl

 

 

이후 SQLcl과 corretto-jdk에 대한 환경변수를 설정합니다.

 

sqlcl

 

jdk

 

 

 

'개발자 환경설정 > Oracle' 카테고리의 다른 글

오라클 에러코드  (0) 2023.08.04
오라클 서버 접속  (0) 2023.08.03
오라클 DB 및 SQL Developer 다운로드 [23.08]  (0) 2023.08.03
4. SQLcl 설치  (0) 2023.08.02
3. 오라클 설치 확인  (0) 2023.08.02

 

 

 

Map 컬렉션은 키(key)와 값(value)으로 구성된 Map 엔트리 객체를 저장하는 구조입니다.

구현 클래스는 'HashMap', 'HashTable', 'Properties' 등이 있습니다.

 


 

Map 컬렉션의 특징 및 주요 메서드입니다

 

  • V put(K key, V value) : 주어진 키와 값을 추가, 저장이 되면 값을 리턴

  • boolean containKey(Object key) : 주어진 키가 있는지 여부
  • boolean contains Value(Object value) : 주어진 값이 있는지 여부
  • Set<Map.Entry><K,V>> entrySet() : 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아 리턴
  • V get(Object key) : 주어진 키의 값을 리턴
  • boolean isEmpty() : 컬렉션이 비어있는지 여부
  • Set<K> keySet() : 모든 키를 Set 객체에 담아서 리턴
  • int size() : 저장된 키의 총 수를 리턴
  • Collection<V> values() : 저장된 모든 값 Collection에 담아서 리턴
  • void clear() : 모든 Map.Entry를 삭제
  • V remove(Object key) : 주어진 키와 일치하는 Map.Entry 삭제, 삭제가 되면 값을 리턴

 


 

 

1. 해시 맵( HashMap)

일반적으로 HashMap 보다는 HashTable을 많이 사용합니다.

map은 set과 다르게 키가 같다면, 기존 요소를 교체합니다.

 

먼저 Student 클래스입니다.

 

@AllArgsConstructor
@EqualsAndHashCode
public class Student {
    public Integer sno;	// 학번
    public String name;	// 이름

} // end class

 

Lombok의 어노테이션인 @EqualsAndHashCode를 이용해 메서드를 오버라이드하지 않고, 코드를 구현하였습니다.

 

 

다음은 실행 클래스입니다. 

 

@Log4j2
public class HashMapExample {

	
    public static void main(String[] args) {
        // Map 컬렉션 생성
        @Cleanup("clear")
        Map<String, Integer> map = new HashMap<String, Integer>();
		
        map.put("신용권", 85);
        map.put("홍길동", 90);
        map.put("동장군", 80);
        map.put("홍길동", 95);
		
        log.info("총 엔트리 수 : {}", map.size());
        log.info(map);
		
        // 요소 객체 찾기
        log.info("홍길동 : {}", map.get("홍길동"));
		
        // Map 컬렉션 순회(Traverse)
        Set<String> keySet = map.keySet();
        Iterator<String> keyIterator = keySet.iterator();
		
        while(keyIterator.hasNext()) {
            String key = keyIterator.next();
            Integer value = map.get(key);
			
            log.info("\t + key : {}, value : {}", key, value);
        } // while
		
    } // main
	
} // end class

 

 

 

2. 해시 테이블( HashTable)

키 객체를 만드는 법은 HashMap과 동일합니다.

HashTable은 스레드 동기화(synchronization)가 된 상태입니다.

따라서, 멀티 스레드가 동시에 HashTable에 접근해서 객체를 추가, 삭제를 하더라도 thread-safe합니다.

 

 

 

3. 프로퍼티스( Properties, 속성 )

Properties는 키와 값을 String 타입으로 제한한 Map 컬렉션입니다.

Properties는 프로퍼티 파일(~.properties) 파일을 읽어 들일 때 주로 사용합니다.

이러한 프로퍼티 파일을 Resource Buncle(리소스 번들)이라고 합니다.

 

리소스 번들은 유지 보수를 편리하게 만들어 주고, ISQ-8859-1 문자셋으로 저장됩니다.

리소스 번들은 다국어를 고려하지 않고 만들었기 때문에, 한글은 유니코드(Unicode)로 변환되어 저장합니다.

 

 

간단한 리소스 번들입니다.

 

#database.properties
driver = oracle.jdbc.OracleDriver
url = jdbc:oracle:this:@localhost:1521:orcl
username = scott
password = tiger

# Set Your Name
yourname = \uD64D\uAE38\uB3D9

 

위의 리소스 번들을 기반으로 실행 코드를 만들었습니다.

 

@Log4j2
public class PropertiesExample {

	
    public static void main(String[] args) throws Exception {
        // Step.1   리소스 번들을 사용할 Map 객체릀 생성
        Properties properties = new Properties();
		
        // Step.2   실행 클래스 위치를 기준으로, 리소스 번들의 경로를
        //          지정해서 완전한 절대경로를 얻음
        String path = 
                PropertiesExample.
                class.
                getResource("/database.properties").
                getPath();
		
        log.info("1. path : {}", path);
		
        // ---------------------------------------------
		
        // Step.3   URL Encoding에 대한 URL Encoding 수행
        //          위에서 얻은 리소스 번들에는 다국어 문자가
        //          포함되어 있을 수도 있으므로, 이러한 경우
        //          다국어 문자가 포함된 경로를 읽어 들이는데 문제가 없도록
        //          URL Decoding을 수행해야 함
        path = URLDecoder.decode(path, "utf-8");
        log.info("2. path : {}", path);
		
        // ---------------------------------------------
		
        // Step.4 Step.3에서 얻어낸 완전한 경로를 Properties의
        // load 메서드에 지정해서 읽어들이게 함
        properties.load(new FileReader(path));
        log.info("2. properties : {}", properties);
		
        // --------------------------------------------
		
        // Step.5   리소스 번들이 이제 Map객체의 요소가 되었기 때문에
        //          각 항목의 값을 얻어내고 싶을 때, getProperty(key) 메서드 사용
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        		
		
		
    } // main

} // end class

 

위 코드에서 URL Encoding은 웹 브라우저가 인식 가능한 부호화된 문자열입니다.

이러한 URL Encoding을 사람이 읽을 수 있도록 역변환하는 것이 URL Decoding이며

코드에서는 URLDecoder.decode()로 진행합니다.

 

properties.load()는 path를 기반으로 리소스 번들을 읽어들입니다.

 

 

먼저 path1, path2, properties2 실행결과를 보면 다음과 같습니다.

 

path1, path2, properties2

 

리소스 번들 주소를 설정할 때, 소스 폴더는 패키지와 다르게 물리적인 폴더로서 인식되지 않습니다.

루트(타겟)에서 패키지 폴더를 반영해서 리소스 번들을 지정하면 URL을 반환합니다.

루트에 가려면 코드처럼 백슬래시(/)를 앞에 붙이면 됩니다.

 

 

간단한 예시입니다.

 

  • 프로젝트 폴더이름 : example
  • 리소스 번들 이름 : database.properties
  • 리소스 번들 위치 : src(소스 폴더) / A / B / C
  • 리소스 번들 주소 : "/ A / B / C / database.properties "

 

 

 

 

 

 

 

 

'Java > Collection Framework' 카테고리의 다른 글

트리 컬렉션  (0) 2023.08.04
셋 컬렉션  (0) 2023.08.03
리스트 컬렉션  (0) 2023.08.02
컬렉션 프레임워크 개요  (0) 2023.08.02

+ Recent posts