** Java에서의 프로시저 연동
1. Procedure
- 프로그램에서는 한번에 수행되어야 하는 코드 블럭을 의미하는데, 함수나 메소드와 유사한 개념입니다.
- 데이터베이스에서는 자주 사용하는 SQL 구문을 하나의 이름으로 묶어서 사용할 수 있도록 해주는 개체로, 하번 호출되면 메모리에 상주합니다.
- 데이터베이스에서는 보안과 속도 때문에 사용합니다.
2. Oracle에서의 프로시저 생성과 실행
1) 생성
create or replace procedure 프로시저이름
(매개변수이름 자료형)
is
지역변수 선언
begin
수행할 SQL 구문;
end;
/
2) 실행
execute 프로시저이름(매개변수)
- 실습1
3. Java에서의 데이터베이스 연동
1) 프로젝트 build path에 데이터베이스 드라이버 파일을 추가
2) 사용할 데이터베이스 드라이버 클래스 로드
Class.forName("드라이버 클래스 이름");
3) Connection 객체를 생성
DriverManager.getConnection("데이터베이스 URL", "계정", "비밀번호");
4) Statement 객체를 생성
Connection객체.prepareStatement 또는 prepareCall;
5) sql에 물음표가 있으면 데이터 바인딩
Statement객체.set자료형(물음표번호, 실제데이터);
6) sql 실행
- select가 아닌 구문 : 정수로 받음
int 변수명 = Statement객체.executeUpdate();
- select 구문
ResultSet 변수명 = Statement객체.executeQuery();
7) 결과 사용
- select가 아닌 경우는 영향받은 행의 개수를 리턴하고
- select의 경우는 결과 셋입니다.
- next()와 get자료형(select절에서의 번호 또는 "컬럼이름")을 이용해서 결과를 사용합니다.
8) 사용한 객체 닫기
4. Java에서의 Oracle 프로시저 실행
1) PreparedStatement 대신에 CallableStatement 클래스 이용
- CallableStatement객체.prepareCall("{call 프로시저이름(매개변수만큼 ?)}"};
- 물음표에서 값 바인딩
- executeUpdate 나 executeQuery 호출
** 실습1 : dept 테이블
--dept 테이블에 데이터를 삽입하는 프로시저 create or replace procedure insertDeptProc (vdeptno dept.deptno%type, vdname dept.dname%type, vloc dept.loc%type) is begin insert into dept(deptno, dname, loc) values(vdeptno, vdname, vloc); end; / --만든 프로시저를 실행시키는 구문 execute insertDeptProc(13, '비서', '전주'); --dept 테이블 전체 조회 select * from dept; --dept 테이블에 데이터를 삭제하는 프로시저: deptno를 매개변수로 create or replace procedure deletDeptProc (vdeptno dept.deptno%type) is begin delete from dept where deptno = vdeptno; end; / execute deletDeptProc(13); select * from dept; commit;
|
** 람다(lambda)식
- java에서 함수적 프로그래밍을 적용하기 위해 1.8버전에서 추가한 문법
- 람다는 이름없는 함수를 만들기 위한 문법입니다.
- java에서는 '하나의 추상 메소드 만을 가진 인터페이스'의 '익명객체'를 만들 때 사용할 수 있습니다.
- 람다 메소드 구현
(매개변수)->{
수행할 내용
return
}
-Thread 인터페이스 : Runnable 인터페이스
- 이 인터페이스는 public void run() 이라는 추상 메소드만을 소유하고 있습니다.
- 스레드를 만들기 위해서는 1. 인터페이스를 implements 하는 클래스를 만들고 인스턴스를 만들어서 사용하거나 2. anonymous class를 만들어서 사용하는 방법이 있습니다. 3. 추상 메소드가 1개라면 람다를 이용할 수 있습니다.
** 실습2 : 스레드 만들기 (별도의 클래스를 만들어서 사용하는 방법)
- 메인
package lambdaEx; public class Main { public static void main(String[] args) { //별도의 클래스를 만들어서 이용 (재사용 할 경우 많이 사용) RunnableImpl r = new RunnableImpl(); Thread th = new Thread(r); th.start(); //2개 째 RunnableImpl r1 = new RunnableImpl(); Thread th1 = new Thread(r); th1.start(); } } |
- RunnableImpl implement Runnable
package lambdaEx; public class RunnableImpl implements Runnable { @Override public void run() { //1초마다 쉬면 토마토 게임 하기 10회 int i=0; while(i<10) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(i%2 == 0) { System.out.println("토"); }else{ System.out.println("마"); } i=i+1; } } } |
** 실습3 : 스레드만들기(클래스를 만들지 않고 Thread 객체를 만들어서 사용)
- anonymous class 만들기 : 인스턴스는 있는데 클래스가 없다.
- 메인
package lambdaEx; public class Main { public static void main(String[] args) { //익명 클래스 이용하기 : 클래스를 안 만드는 만큼 메모리 사용을 줄일 수는 있지만 재사용하기에는 불편. Runnable r = new Runnable() { @Override public void run() { // 1초마다 쉬면 토마토 게임 하기 10회 int i = 0; while (i < 10) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (i % 2 == 0) { System.out.println("토"); } else { System.out.println("마"); } i = i + 1; } } }; Thread th = new Thread(r); th.start(); } }
|
** 실습4 : 스레드만들기(람다를 이용한 스레드-매개변수x)
- Runnable 인터페이스에는 메소드가 1개만 존재합니다.
- 1개의 메소드만 소유한 인터페이스를 상속받고자 하는 경우에는 람다를 이용할 수 있습니다.
()->{
내용
}
- 메소드 이름을 기재하지 않기 때문에 인터페이스에 메소드가 1개만 존재해야 합니다.
-메인
package lambdaEx; public class Main { public static void main(String[] args) { // 익명 클래스 이용하기 : 클래스를 안 만드는 만큼 메모리 사용을 줄일 수는 있지만 재사용하기에는 불편. Runnable r = () ->{
// 1초마다 쉬면 토마토 게임 하기 10회 int i = 0; while (i < 10) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (i % 2 == 0) { System.out.println("토"); } else { System.out.println("마"); } i = i + 1; } }; Thread th = new Thread(r); th.start();
} }
|
** 실습5 : 스레드만들기(람다이용-매개변수 있는 메소드 구현)
- 매개변수의 자료형은 기재할 필요가 없습니다.
- 매개변수가 하나일 때는 ()를 생략해도 됩니다.
- 아래와 같은 인터페이스가 있을 경우
interface T{
public void method(int n)
}
- 메인
package lambdaEx; interface T{ public void method(int n); } public class LamdaMain { public static void main(String[] args) { // 위와 같은 인터페이스 T를 구현해서 사용해야 하는 경우
T t = n ->{ System.out.println("n:"+n); }; t.method(10); } }
|
** 실습6 : 스레드만들기(람다이용-return 타입이 있는 메소드)
- 메소드 내에서 타입에 해당하는 데이터만 리턴하면 됩니다.
- 아래와 같은 인터페이스가 있을 경우
interface V{
public int add(int n1, int n2);
}
- 메인
package lambdaEx; interface V{ public int add(int n1, int n2); } public class LamdaMain { public static void main(String[] args) { //인터페이스 V를 구현해서 사용해야 하는 경우 V v = (n1, n2) ->{ return n1+n2; }; System.out.println(v.add(100, 300)); } }
|
** 직접 인터페이스를 만들어서 람다를 사용할 일은 거의 없습니다.
- 스트림 API를 사용할 때 스트림 API의 많은 메소드들이 이미 만들어져 있는 인터페이스의 객체를 매개변수로 대입해야 동작하는 경우가 많습니다.
- 이 때 익명 클래스를 사용하는 것보다는 람다 형식을 사용하는 것을 권장합니다.
- 안드로이드 스튜디오에서는 메소드가 1개 뿐인 인터페이스의 익명 클래스를 코드 최적화를 위해서 람다 코드로 변경을 합니다.
** 표준 API 람다 인터페이스
Consumer 인터페이스 |
매개변수는 있고 리턴 값은 없는 메소드 소유 |
Supplier 인터페이스 |
매개변수는 없고 리턴 값만 있는 메소드 소유 |
Function 인터페이스 |
매개변수도 있고 리턴 값도 있는 메소드 소유 - 가공해서 리턴 |
Operator 인터페이스 |
매개변수가 있고 리턴 값도 있는 메소드 소유 - 연산해서 리턴 |
Predicate 인터페이스 |
매개변수가 있고 리턴 값이 boolean인 메소드 소유 - 필터링 할 때 사용 |
** Stream API
- 컬렉션(배열, List, Set, 다른 언어에서는 문자열과 Map도 컬렉션으로 취급)의 데이터를 접근하는 로직과 작업을 수행하는 로직을 하나의 구문으로 처리할 수 있도록 해주는 API로 1.8버전에서 추가된 API
- 작업을 처리하는 로직은 람다를 이용해서 대입하는 것을 권장
- 컬렉션의 데이터를 반복문을 이용해서 접근하는 것보다 간결하게 작성할 수 있고 병렬처리(동시에 작업을 수행하는 것)가 쉽습니다.
1. 스트림의 특징
- 컬렉션의 모든 데이터를 접근하는 방법이 동일합니다.
- 반복문을 메소드의 내부에 숨기기 때문에 반복문을 잘못 작성하는 경우가 없습니다.
- 원본 데이터를 변경하지 않습니다.
- 1회용이라서 한 번 사용하고 나면 다시 사용할 때는 재생성해야 합니다.
2. 스트림 생성
- List 나 Set은 stream() 이나 parellelStream() 이라는 인스턴스 메소드로 생성 가능
- 배열은 Arrays.stream 이라는 메소드의 매개변수로 배열을 대입해서 생성
- 실습7 : 배열과 List를 가지고 스트림 생성하기
package streamAPIEx; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class StreamMain0 { public static void main(String[] args) { //문자열 배열을 생성 String [] ar = {"카드캡터채리","원피스","명탐정코난","천사소녀네티"};
//문자열 리스트를 생성 List<String> list = new ArrayList<>(); list.add("나루토"); list.add("심슨네 가족들"); list.add("천재소년 지미"); list.add("스폰지밥");
//문자열 배열을 가지고 스트림 만들기 Stream<String> stream = Arrays.stream(ar); //작업 수행 stream.forEach(cartoon ->{System.out.println(cartoon);});
//List를 가지고 스트림 만들기 stream = list.stream(); stream.forEach(cartoon -> {System.out.println(cartoon);}); } }
|
3. 중간처리 메소드
- 스트림의 데이터를 변경하거나 조건에 맞는 데이터만 골라내기 위한 작업
skip(정수) |
정수 만큼 넘어가기 |
limit(정수) |
정수 만큼만 가져오기 |
distinct() |
동일한 데이터를 제거하고 가져오는데 equals 메소드를 이용합니다. |
filter() |
매개변수가 1개이고 boolean을 리턴하는 람다 식을 대입하면 람다 식이 true를 리턴하는 데이터만 가져옵니다. |
- 중간처리 메소드는 여러개 사용할 수 있음.
- 메인
package streamAPIEx; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class StreamMain1 { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("떡볶이"); list.add("카레덮밥"); list.add("평양냉면"); list.add("버섯전골"); list.add("떡볶이"); list.add("매운갈비찜"); list.add("갈비탕"); list.add("알탕"); list.add("삼겹살"); list.add("곱창"); list.add("삼겹살"); list.add("라멘"); list.add("평양냉면"); list.add("소고기 타다키"); list.add("고로케"); list.add("갈비탕"); list.add("떡볶이"); //ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
//스트림 변환 Stream<String> stream = list.stream(); //모든데이터를 출력 //stream.forEach(food -> {System.out.println(food);}); //중복을 제거 //stream.distinct().skip(2).limit(3).forEach(food -> {System.out.println(food);}); //라로 시작하는 데이터만 찾아서 출력 //return 문장 하나 밖에 없을 때는 return 이라는 단어를 생략가능 //수행되는 코드가 한 줄 일 때는 {} 생략 가능 //stream.filter(food ->food.startsWith("라")).forEach(food ->System.out.println(food)); stream.filter(food ->food.length() == 3).distinct().forEach(food ->System.out.println(food)); } }
|
- mapTo자료형(클래스이름::getter메소드) : 인스턴스의 getter 메소드의 값으로 인스턴스가 대체
- 예시
String msg = "Hello";
mapToString(String::toUpperCase): toUpperCase 메소드의 값으로 변경
'프로그래밍 공부&정리 > DataBase' 카테고리의 다른 글
Oracle(MySQL)을 이용한 회원관리 (0) | 2018.09.08 |
---|---|
[0904]MySQL (0) | 2018.09.04 |
[0904] 데이터베이스(MySQL) (0) | 2018.09.04 |
3장. 오라클 주요 함수 (0) | 2018.09.03 |
2장. SQL의 기본 (0) | 2018.08.24 |