2016년 10월 31일 월요일

[오라클학원,SQL기초학원추천_탑크리에듀]오라클힌트 for SQL 튜닝, 단순뷰, 복합뷰의 뷰 머지(view merge), Query Transformation Hint (merge, no_merge)

탑크리에듀(www.topcredu.co.kr) 제공 SQL튜닝을 위한 힌트강좌. 쿼리문을 블럭화 하기 위해 서브쿼리, 인라인 뷰등을 자주 사용하는데 오라클 옵티마이저가 인라인뷰, 서브쿼리를 해석할 때 독자적으로 실행하지 않고 메인쿼리와 함께 실행되는 경우, 즉 쿼리블럭을 풀어서 기존 쿼리와 함께 최적화를 수행하는 것을 뷰 머징(View Merging)이라고 합니다. 인라인뷰나 서브쿼리등이 많아 지면 옵티마이저가 뷰 머징을 해서 쿼리 성능이 안좋아질 수가 있는데 서브쿼리, 인라인 뷰등에서 ROWNUM을 사용하면 뷰 머징을 방지하는 효과가 있습니다. 본 강좌는뷰 머징을 위한 merge, no_merge 힌트도 소개 합니다. 감사합니다.

[SQL기초,오라클기초강의추천](외부조인, outer join), 오라클, MySQL, 내부조인,외부조인

일반적인 조인(내부조인)은 두 테이블 모두 조인 조건을 만족시키는 레코드만 출력된다. 즉 두 테이블중 한쪽 테이블의 값이 일치하지 않는 다면 해당 레코드는 출력되지 않는데 이 경우에도 결과로 출력해야 되는 경우가 있다면 외부조인(Outer Join)을 사용하면 된다. 외부조인은 LEFT OUTER JOIN, RIGTH OUTER JOIN, FULL OUTER JOIN이 있다.

[오라클강의,오라클힌트교육추천]오라클11g_invisible 인덱스 및 use_invisible_indexes,no_use_invisible_indexes 힌트

Oracle11g R1 부터 Optimizer에게 보이지 않는 invisible index의 생성을 가능하도록 했는데 인덱스는 Index Segment에 동일하게 생성되지만 단지 보이지는 않습니다. 실무에서 인덱스 변경을 통해 SQL성능을 평가하는 경우가 많이 있으므로 실제 인덱스를 반영하기 전에 그 인덱스가 사용되었을 때의 성능을 측정하기 위해 사용하며 관련된 힌트로는 use_invisible_indexes,no_use_invisible_indexes 힌트가 있는데 본 강좌를 통해 간단히 살펴보세요~

[닷넷교육,C#기초교육]C#선택적인수, 명명된 인수(메소드, 생성자, 델리게이트, 인덱서)

C#에서 명명된 인수란? 매개 변수 목록에서의 매개 변수 위치지정 대신 매개 변수의 이름과 인수를 연결하여 특정 매개 변수에 대한 인수를 지정할 수 있으므로 매개 변수의 순서를 기억하거나 확인할 필요가 없는 방법을 제공하며 메소드에서 파라미터 값을 넘길 때 매개변수 이름을 정해서 넘기는 것을 이야기 합니다. 선택적 인수란? 메서드, 생성자, 인덱서 또는 대리자의 정의에서 해당 매개 변수가 필수인지 선택적인지 지정할 수 있는데 호출할 경우 모든 필수 매개 변수에 대한 인수는 항상 제공해야 하지만 선택적 매개 변수에 대한 인수는 생략할 수 있으며 각 선택적 매개 변수에는 기본값이 있어서 해당 매개 변수에 대해 인수를 전달하지 않으면 기본값이 사용됩니다.

[오라클교육,오라클힌트교육추천](해시조인시 드라이빙, Build Input 스와핑과 관련된 힌트,드라이빙 테이블선정)swap_join_inputs, no_swap_join_inputs

해시외부조인(hash outer-join), 해시 세미조인(hash semi-join), 해시 안티조인(hash anti-join) 시 드라이빙(driving table, build input), 비드라이빙(probe input)을 바꿀수 있도록 하는 힌트, 즉 드라이빙 테이블선정과 관련된 swap_join_inputs, no_swap_join_inputs 힌트에 대한 설명 및 실습 강좌입니다.

[오라클교육,오라클힌트교육_탑크리에듀]해시조인, Hash join, use_hash, ordered

(해시조인과 관련된 오라클힌트)해시조인은 두테이블 중 작은 테이블(Build Input, Driving Table)을 메모리에 조인키를 기반으로 해시테이블을 생성하고 해시테이블내에 행들을 위치시키기 위해 해시함수를 이용하며 나머지 테이블을 스캔하면서 메모리에 있는 해시테이블과 조인 조건을 만족하는 데이터를 찾는 조인이다. 중첩루프조인과 같이 조인시 발생하는 랜덤액세스에 대한 부하가 없는 조인방식이다. 관계형 데이터베이스에서 가장 비용이 많이 들어가는 조인방법으로 주로 작은 테이블과 큰 테이블의 조인 시 사용되며 , 드라이빙 조건과 상관없이 좋은 성능을 발휘할 수 있는 조인 방법이며 대체로 제일 빠르다.

[오라클강의,IT실무교육_탑크리에듀]오라클힌트(USE_NL, ORDERED), 중첩루프조인및 조인순서와 관련된 힌트

USE_NL 힌트는 테이블을 조인 하는 경우 중첩 루프 조인(Nested Loop Join)이 일어나도록 하는 힌트 문장이다. 중첩 루프 조인은 중첩반복 이라고도 하는데 하나의 테이블(outer/driving table)에서 추출된 ROW를 가지고 일일이 다른 테이블(inner/probed table)을 반복해서 조회하여 찾아지는 레코드를 최종 데이터로 간주하는 방법 이다. ORDERED 힌트는 FROM 뒤에 기술되는 테이블의 순서대로 조인이 일어나도록 해주는 구문으로 대부분 단독으로는 사용되지 않고 USE_NL(중첩 루프 조인을 유도), USE_MERGE(머지 소트 조인을 유도), USE_HASH(HASH 조인을 유도)등과 같이 사용된다.

2016년 10월 28일 금요일

[자바강좌,JPA강좌,스프링강좌추천★탑크리에듀][스프링JPA강좌]Querydsl오라클쿼리시퀀스(Sequence)사용예문

[스프링JPA강좌]Querydsl오라클쿼리시퀀스(Sequence)사용예문

SQLExpressions.nextval("시퀀스이름") 

아래와 같이 TYPE을 줄 수도 있다. 

SQLExpressions.nextval(Integer.class, "시퀀스이름")

[자바강좌,JPA강좌,스프링강좌추천★탑크리에듀][Querydsl오라클SQL팁]오라클ROWID,ROWNUM,LEVEL,SYSDATE같은의사칼럼사용하기

[Querydsl오라클SQL팁]오라클ROWID,ROWNUM,LEVEL,SYSDATE같은의사칼럼사용하기 

com.mysema.query.sql.oracle.OracleGrammar 클래스를 사용하면 되는데 
static 필드로 선언되어 있고 아래처럼 사용하면 된다. 

아래는 오라클의 계층형 쿼리를 Querydsl을 이용하여 구현 하였다. 

[계층형질의에서 LEVEL 예제] 

List<Tuple> rows =  query 
.select(StringExpressions.lpad( 
Expressions.stringTemplate("' '").stringValue(),     
            OracleGrammar.level.subtract(1).multiply(2), ' ')      
    .concat(emp.ename), 
    emp.sal, emp.deptno)  
.startWith(emp.ename.eq("KING"))  
.connectByPrior(emp.empno.eq(emp.mgr))    
.from(emp) 
.fetch(); 


select lpad(' ',(level - 1) * 2,' ') || EMP.ENAME, EMP.SAL, EMP.DEPTNO 
from EMP EMP 
start with EMP.ENAME = 'KING' 
connect by prior EMP.EMPNO = EMP.MGR 


-------------------------------------------------------------------- 
[ROWNUM 예제] 

List<Tuple> rows = queryFactory.select(myemp1.ename, mydept1.dname) 
.from(myemp1).innerJoin(mydept1) 
.on(myemp1.deptno.eq(mydept1.deptno)) 
.where(OracleGrammar.rownum.lt(6)).fetch(); 

select MYEMP1.ENAME, MYDEPT1.DNAME 
from MYEMP1 MYEMP1 
inner join MYDEPT1 MYDEPT1 
on MYEMP1.DEPTNO = MYDEPT1.DEPTNO 
where rownum < 6

[자바강좌,JPA강좌,스프링강좌추천★탑크리에듀][스프링JPA강좌,Querydsl,오라클DB에서 쿼리타입Q타입생성하기,SQLQueryFactory]

[스프링JPA강좌,Querydsl,오라클DB에서 쿼리타입Q타입생성하기,SQLQueryFactory] Spring Data JPA에서 오라클DB에 직접 쿼리하기 위해 오라클DB쪽 테이블을 자바쪽 프로젝트에 쿼리타입으로 생성해야 하는데, 그와 관련된 메이븐 설정 및 방법 입니다. 

첨부 파일 참조하세요~ 

감사합니다.

첨부파일URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=147

[자바강좌,JPA강좌,스프링강좌추천★탑크리에듀][스프링DATAJPA팁]Querydsl4.0.8오라클쿼리WITH구문오류!!(Querydsl,오라클쿼리강좌)

[스프링DATAJPA팁]Querydsl4.0.8오라클쿼리WITH구문오류!!(Querydsl,오라클쿼리강좌)

아래와 같은 SQL 쿼리를 만들기 위해 
(WITH문을 이용하여 MYEMP1, MYDEPT1 테이블에서 부서명, 부서별직원평균급여 구하기) 

with myemp2 as ( 
  select MYEMP1.DEPTNO, avg(MYEMP1.SAL) sal 
  from TEST.MYEMP1 MYEMP1 
  group by MYEMP1.DEPTNO) 
select MYDEPT1.DNAME, myemp2.SAL 
from MYDEPT1 
inner join myemp2 
on MYDEPT1.DEPTNO = myemp2.DEPTNO 

다음과 같이 Querydsl4.0.8 버전에서 작성했는데 

QMyemp1 myemp1 = new QMyemp1.myemp1; 
QMyemp1 myemp2 = new QMyemp1("myemp2"); 

List<Tuple> depts  = queryFactory.query() 
.with(myemp2, 
SQLExpressions 
.select(myemp1.deptno, myemp1.sal.avg().as("sal")) 
.from(myemp1) 
.groupBy(myemp1.deptno)) 
                .select(mydept1.dname, myemp2.sal) 
                .from(mydept1) 
                .innerJoin(myemp2).on(mydept1.deptno.eq(myemp2.deptno)) 
                .fetch(); 


Querydsl4.0.8 버전에서는 WITH구문이 다음과 같이 해석된다. 
(innerjoin에서 WITH구문에서 만든 myemp2와 조인을 해야되는데 
 myemp1 테이블과 조인하여 이상한 결과가 나오게 된다. ) 


with myemp2 as ( 
  select MYEMP1.DEPTNO, avg(MYEMP1.SAL) sal 
  from TEST.MYEMP1 MYEMP1 
  group by MYEMP1.DEPTNO) 
select MYDEPT1.DNAME, myemp2.SAL 
from MYDEPT1 
join MYEMP1 myemp2 
on MYDEPT1.DEPTNO = myemp2.DEPTNO 


Querydsl 버전을 4.0.9 이상으로 올리자. 
잘 동작된다.

[자바강좌,JPA강좌,스프링강좌추천★탑크리에듀][Spring Data JPA,Querydsl강좌]오라클SQL조인,ROWNUM,OracleGrammar.rownum

[Spring Data JPA,Querydsl강좌]오라클SQL조인,ROWNUM,OracleGrammar.rownum 

아래 두가지 방법 모드 가능하다. 

// List<Tuple> rows = queryFactory.select(myemp1.ename, mydept1.dname) 
// .from(myemp1).innerJoin(mydept1) 
// .on(myemp1.deptno.eq(mydept1.deptno)).limit(5).fetch(); 

List<Tuple> rows = queryFactory.select(myemp1.ename, mydept1.dname) 
.from(myemp1).innerJoin(mydept1) 
.on(myemp1.deptno.eq(mydept1.deptno)) 
.where(OracleGrammar.rownum.lt(6)).fetch(); 

------------------------------------------------- 

select MYEMP1.ENAME, MYDEPT1.DNAME 
from MYEMP1 MYEMP1 
inner join MYDEPT1 MYDEPT1 
on MYEMP1.DEPTNO = MYDEPT1.DEPTNO 
where rownum < 6

2016년 10월 27일 목요일

[자바학원,스프링학원추천]JPA 상속관계 매핑(@MappedSuperclass, @Inheritance,@DiscriminatorValue,@DiscriminatorColumn

JPA에서 상속관계 매핑 방법에 대해 설명한 자료입니다. RDB는 객체지향처럼 상속이 존재하지 않으며 대신 Super Type, Sub Type 이라는 개념이 존재한다. 슈퍼/서브 타입 논리모델을 물리적인 테이블로 변환할 때는 하나의 통합된 테이블로 표시(단일 테이블 전략)하거나, 각각 테이블로 별도로 두어 조회할 때 조인을 이용하거나 서브타입만 테이블로 변환을 하는 방법이 있다.

[오라클학원,SQL기초학원추천_탑크리에듀]스칼라서브쿼리(Scalar Subquery)

오라클 SQL초보자를 위한 스칼라 서브쿼리에 대한 간단한 설명자료 입니다. 데이터 건수가 많지 않다면 조인보다 가끔 스칼라 서브쿼리가 더 효율적일 때가 있죠. 참조하세요.

[자바교육,스프링교육,IT실무교육추천]스프링컨트롤러예외처리,@ExceptionHandler, @ControllerAdvice

스프링 WEB MVC에서 컨트롤러에서 예외처리하는 방법에 관해 설명한 PPT 입니다. @ExceptionHandler는 스프링 컨트롤러에서 정의한 메소드에서 기술한 예외가 발생되면 자동으로 받아낼 수 있는데 이를 이용하여 컨트롤러에서 발생하는 예외를 View단 JSP등으로 보내서 처리할 수 있으며@ControllerAdvice는 스프링3.2 이상에서 사용가능하며 @Controller 나 스프링 4.0이상에서 지원하는 @RestController 에서 발생하는 예외 등을 catch하는 기능을 가지고 있으며 클래스 위에 @ControllerAdvice를 붙이고 어떤 예외를 잡아낼 것인지 메소드 상단에 @ExceptionHandler(예외클래스명.class)를 기술합니다. 스프링4.0이상에서는 특정한 컨트롤러만 지정해서 캐치할 수 있죠

2016년 10월 26일 수요일

[자바교육,JPA교육,스프링교육_탑크리에듀][스프링부트JPA강좌]Querydsl,오라클시퀀스(Sequence)예제

[스프링부트JPA강좌]Querydsl,오라클시퀀스(Sequence)예제 

감사합니다.

@Override 
public Long insertMyemp1(String ename, Long sal, String deptno) { 
//////////////////////////////////////////////////////////////// 
// myemp1테이블에 insert, 오라클 시퀀스이용 
// 시퀀스생성:create sequence seq_myemp1_empno start with 10000003 
//          select seq_myemp1_empno.nextval from dual; 
// 시퀀스이름을 줄때 앞에스키마명까지 줘야한다. 아니면 ORA-02289 발생 
//------------------------------------------------------------- 
// insert into myemp1 (empno, ename, sal, deptno) 
// values (test.seq_myemp1_empno, ?, ?, ?) 
//////////////////////////////////////////////////////////////// 
Long cnt = queryFactory.insert(myemp1) 
.columns(myemp1.empno, myemp1.ename, myemp1.sal, myemp1.deptno) 
.values(SQLExpressions.nextval("test.seq_myemp1_empno"),ename,sal,deptno) 
.execute(); 

return cnt; 


------------------------------------------------------------------------ 
[로그] 
10. insert into MYEMP1 (EMPNO, ENAME, SAL, DEPTNO) 
values (test.seq_myemp1_empno.nextval, '오제이씨', 9999, '1') 
  
20160304 21:14:54.194 [http-nio-8080-exec-7] INFO j.sqltiming - insert into MYEMP1 (EMPNO, ENAME, SAL, DEPTNO) 
values (test.seq_myemp1_empno.nextval, '오제이씨', 9999, '1') 
 {executed in 255 msec}

[자바교육,JPA교육,스프링교육_탑크리에듀][스프링JPA,Querydsl강좌]오라클SQL쿼리,NVL,SelfJoin,LeftJoin

[스프링JPA,Querydsl강좌]오라클SQL쿼리,NVL,SelfJoin,LeftJoin

첨부 파일 참조하세요. 
감사합니다.

첨부파일 URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=143

[자바교육,JPA교육,스프링교육_탑크리에듀]#4.Spring부트,JPA,오라클연동게시판,리스트보기(리스트보기,레포지토리,서비스,컨트롤러,스프링부트메인, JSP, 페이징처리적용)

#4.Spring부트,JPA,오라클연동게시판,리스트보기(리스트보기,레포지토리,서비스,컨트롤러,스프링부트메인, JSP, 페이징처리적용),기존 MyBatis, Spring JDBC와 비교해보세요~

첨부 파일 참조하세요.


1. 게시판 리스트보기 설명 PDF
2. 게시판 리스트보기까지 전체 프로젝트 소스

다음 강좌 #5에서는 RestController, 부트스트랩을 통한 UI개선, AngulerJS를 적용하여클라이언트를 MVC형태로 개선해 보자!
 
boardlist.png


 

열공하세요~ 감사합니다.

[자바교육,JPA교육,스프링교육_탑크리에듀]#3.스프링부트,Spring Data JPA게시판(모델클래스작성및테이블생성)

#3.스프링부트,Spring Data JPA게시판(모델클래스작성및테이블생성)

도메인 모델 객체 생성하기<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

n  Jpa.board.model 패키지를 생성 후 엔티티 클래스를 만들자.

[Board.java]

package jpa.board.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import lombok.Getter;
import lombok.Setter;


@Entity
@Getter
@Setter
// 시퀀스의 시작값은 1
// 시퀀스의 기본 allocationSize50, 번호가 50부터 생기므로 1
@SequenceGenerator(name="BOARD_SEQ_GENERATOR",
                   sequenceName="BOARD_SEQ",
                   initialValue=1,
                   allocationSize=1) 
public class Board {
          
//  MySQL이라면 아래와같이 기술한다.
//        @Id
//        @GeneratedValue
//        @Column(length=10)
//        protected Integer id;     
          
           @Id     
           @GeneratedValue(strategy=GenerationType.SEQUENCE,
                           generator="BOARD_SEQ_GENERATOR")       
           @Column(length=10)
           protected Integer id;                
                     
           @Column(length=20, nullable=false)
           protected String name;
          
           @Column(length=20, nullable=false)
           protected String passwd;
          
           @Column(length=500, nullable=false)
           protected String title;
          
           @Column(length=4000, nullable=false)
           protected String content;
          
           //날짜기본형식 time, day, month, year 형태저장
           @Column(nullable=false, columnDefinition = "date default sysdate")
           @Temporal(TemporalType.TIMESTAMP)
           protected Date regdate = new Date();      
          
           @Column(nullable=false, columnDefinition = "number(5) default 0")
           protected Integer readcount = 0;
          
           // 답변인경우 어느글의 답변인지 상위글번호
           // 최상위글인 경우 자신의 글번호 동일하다.
           // 리스트보기에서 정렬시 우선적으로 reply로 정렬
           @Column(nullable=false, columnDefinition = "number(5)")
           protected Integer reply = 0 ;
          
           // 글아래 모든 답변들에 대해 reply_level과 관계없이 1씩 증가   
           @Column(nullable=false, columnDefinition = "number(5) default 0")
           protected Integer replystep = 0;
          
           // 1,2차 답글인지 여부
           // 하나의 글에 답변이 두개면 그 두답변은 reply_level이 같다.
           // 리스트보기에서 reply_level에 따라 들여쓰기를 한다.
           @Column(nullable=false,columnDefinition = "number(5) default 0", length=10)
           protected Integer replylevel = 0;
}
n  프로젝트에서 마우스 우측버튼 -> Run As -> Spring Boot App로 실행 후 오라클쪽에 테이블이 생성되는 것을 확인하자.