레이블이 JAVA ORACLE인 게시물을 표시합니다. 모든 게시물 표시
레이블이 JAVA ORACLE인 게시물을 표시합니다. 모든 게시물 표시

2013년 8월 9일 금요일

[OracleJavaCommunity,오라클자바커뮤니티]이번 강좌에서는 자바에서의 main 메소드에 대해 자세히 알아 보도록 하겠습니다

이번 강좌에서는 자바에서의 main 메소드에 대해 자세히 알아 보도록 하겠습니다. main 앞에 왜 static이 붙으며 왜 public이 붙는지등에 관한 것을 공부해 보도록 하겠습니다. 잘 알아두시기 바랍니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



main 메소드의 특징 

메인 메소드는 JVM에 의해 자바 프로그램을 실행 할 때 처음 호출되는 메소드 입니다.
메인 메소드는 객체 생성을 위한 첫 실행 메소드 이다. 그러므로 어느 클래스에서 접근이 가능해야 하므로 public 이라는 접근 제어자를 사용 합니다.
해당 클래스로 부터 생성된 모든 객체에서 접근이 가능해야 한다. (static) --> static이라는 말이 붙으면 객체와 관련이 있는 것이 아니라 클래스와 관련이 있으며 초기화가 한번만 일어나며, 클래스가 실행되기 위해 메모리로 로딩되는 시점에 한번만 초기화가 일어 납니다. 즉 전역변수등에 사용되며...등등 [자바기초다지기#7]변수-인스턴스변수, 클래스변수 강좌에서 이미 공부 했던 부분 입니다.
Return 값을 가지지 않습니다.(void)
또한 실행 될 때 인자 값을 받아 들일 수 있습니다.

자바 인터프리터는 Java Application에 주어지는 각 명령형 인자들을 main(String[] args) 메소드에 매개변수로 넘겨 줍니다.
각 명령행 인자는 공백문자(whitespace)로 구분 하며, C/C++에서 메인 함수의 매개변수 개수를 나타내는 argc와 명령형 매개 변수 들을 문자열 배열로 받아 들이는 argv는 결국 Java의 args.length, args로 대체 될 수 있습니다.

[예제]

class ArgTest
{
public static void main (String[] args)
{
for(int i = 0; i < args.length; ++i) //이 프로그램을 실행할때 넘어 오는 아규멘트의 갯수 만큼 루프를 돕니다. >
System.out.println( "args[" + i + "] = " + args[i] );
}
}



[결과1]

java ArgTest test 100 이라고 실행시

args[0] = test
args[1] = 100


[결과2]

java ArgTest "test 100" 이라고 실행시

args[0] = test 100

2013년 8월 8일 목요일

[ORACLEJAVA커뮤니티]struts-config.xml이나 메시지 리소스 파일을 수정 후 웹서버를 Restart하지 않고 변경사항을 반영하는 방법

struts-config.xml이나 메시지 리소스 파일을 수정 후 웹서버를 Restart하지 않고 변경사항을 반영하는 방법 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


1.        새로운 ActionServlet을 하나 만듭니다.

package yfarm;

import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import org.apache.struts.action.ActionServlet;
import java.io.IOException;

//struts-config.xml과 메시지 Resource 파일을 수정 했을 때 자동으로 인식할 수 있게...
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.RequestUtils;

public class NewActionServlet extends ActionServlet {
       
    protected void Process (HttpServletRequest request, HttpServletResponse response)
                                  throws IOException, ServletException {
        String uri = request.getRequestURI();
       
        if(uri.indexOf("reload.do") != -1) {
            init();
           
            RequestUtils.selectModule(request, getServletContext());
           
            ModuleConfig config = getModuleConfig(request);
           
            getRequestProcessor(config).init(this, config);
           
            RequestDispatcher dispatcher = request.getRequestDispatcher("/reload.jsp");
           
            dispatcher.forward(request, response);           
        }
        else {
            super.process(request, response);
        }
    }
}
                       
위의 NewActionServlet은 URL에 reload.do가 포함되어 있는 경우 초기화를 수행 하도록 합니다. 초기화는 두 단계로 진행하는데 첫째 ActionServlet의 init() 호출하여 struts-config.xml을 초기화 하며 둘째 RequestProcessor 클래스를 초기화 합니다. RequestProcessor 클래스가 초기화 되지 않으면 struts-config.xml이 수정되기 전에 사용된 Action 클래스들이 재사용 되므로 수정된 내용이 반영되지 않을 수도 있습니다.

2.        web.xml을 수정 합니다.
(사용자의 요청을 NewActionServlet이 수행하도록 수정 합니다.)

<servlet>
                <servlet-name>action</servlet-name>
                <servlet-class>yfarm.NewActionServlet</servlet-class>
                <init-param>
                        <param-name>config</param-name>
                        <param-value>/WEB-INF/struts-config.xml</param-value>
                </init-param>
                <load-on-startup>1</load-on-startup>               
        </servlet>

3.        ReloadStrutsConfigAction 클래스를 만듭니다. ( 이 클래스가 reload action인 reload.do에 대해 대응을 하는데 아무 일도 하지 않습니다.)

/*
 * Created on 2005. 5. 6.
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package oraclejava;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 이종철
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

public class ReloadAction extends Action {
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest  request,
        HttpServletResponse response) throws Exception {
        return null;     
    }
}

4.        struts-config.xml에 아래를 추가 합니다. (action-mappings에 추가)

<action
            path="/reload"
            type="oraclejava.ReloadAction"   
    />


5.        XML파일이나 메시지 리소스 등을 수정 후 URL에서 /reload.do를 불러주면 웹 서버를 재시작 하지 않더라도 수정 사항이 반영 됩니다.

2013년 8월 6일 화요일

[오라클자바닷넷교육강좌]웹애플리케이션에서의 로깅 , Web Application Logging

웹애플리케이션에서의 로깅 

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



로그를 남겨 프로그램을 디버깅 하는 일은 대단히 중요한 일입니다. 웹 애플리케이션에서의 로깅은 크게 시스템 로깅과 애플리케이션 로깅으로 나누어 볼 수 있는데 시스템 로깅은 사용자의 데이터 보다 애플리케이션의 내부적인 동작에 대한 기록 입니다. 예를 들면 컨테이너가 시작했을 때의 시스템적인 오류 정보 등을 기록하는 것들이 해당 되며 애플리케이션의 로그는 사용자가 로그인을 하는 경우 인증을 한 정보 등을 기록하는 것이 해당 됩니다.

시스템의 오류는 error로 표현되는 반면에 애플리케이션의 에러는 info로 정의가 가능합니다.

--------------------------------------
서블릿 컨테이너를 이용한 로깅
--------------------------------------

서블릿의 스펙에서 개발자들이 컨테이너의 로그 파일에 이벤트 정보를 로깅 할 수 있도록 지원 합니다. 로그파일의 이름이나 위치는 어떤 컨테이너를 사용 하느냐에 따라 다르지만 기록이 된다는 것은 사실 입니다.

java.servlet.ServletContext는 로그를 남기기 위한 두개의 메소드를 제공 합니다.

ppublic void log(Stirng msg);
public void log(String msg, Throwable throwable);

아래는 이 메소드를 Struts의 Action에서 사용 한 예입니다.

[이전의 DB를 이용한 인증 예제의 LoginAction 입니다.]

//로그를 남기자.
                StringBuffer buf = new StringBuffer("LoginAction : User --> ");
                buf.append(id + " logged in session");
                servlet.log(buf.toString());

위의 소스 코딩에 위해 Tomcat의 Console창에 다음과 같은 기록이 남습니다…

정보: action: LoginAction : User --> jcleelogged in session



------------------------
필터사용
-----------------------

필터는 서블릿2.3에 새로 추가된 기능 입니다. 서블릿의 필터를 이용하면 HTTP요청과 응답객체의 Contents를 검사 할 수 있으며 정적인 Contents뿐 아니라 동적인 Contents에 대해서도 필터기능을 이용하는 것이 가능 합니다.

필터링 기능을 이용하여 아래와 같은 일들이 가능 합니다.

- 클라이언트의 요청이 도달하기 전에 웹 리소스에 대해 접근 가능 합니다.
- 클라이언트의 요청이 리소스에 도달하기 전 요청을 처리 할 수 있습니다.
- 요청헤더나 데이터에 대한 수정이 가능
- 응답헤더나 데이터에 대한 수정 가능
- 어떤 리소스를 수행 한 후 리소스에 대한 메소드 호출을 가로챌 수 있습니다.

이 필터 기능을 로깅만을 위해 쓰기에는 아까운 면도 있지만 시스템에서 사용자의 행위를 추적하기에는 적합한 기술 입니다. 필터를 이용해 암호화, URL 및 기타정보에 대한 캐시, 인증,XML Contents를 변환하기 위한 XSLT 변환 등 다양한 일들을 할 수 있습니다.

필터를 생성 하기 위해서는 세 단계를 거쳐야 합니다.

1.        javax.servlt.Filter 인터페이스를 구현하는 자바 클래스를 만듭니다.
2.        web.xml에 filter 요소를 선언 합니다.
3.        웹애플리케이션의 리소스와 함께 filter class를 packaging 합니다.

Javax.servlet.Filter 인터페이스를 구현하는 클래스에서 반드시 구현해야 하는 세가지 메소드는 다음과 같습니다.

public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
public void destroy( );

[필터 예]


import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletContext;
import javax.servlet.ServletResponse;
import javax.servlet.ServletException;

public class LoggingFilter implements Filter{
        public final static String LOG_FILE_PARAM = "Login.log";
        private FilterConfig filterConfig = null;
        private ServletContext servletContext = null;

        public void init( FilterConfig config ) throws        ServletException {
                // Initialize any neccessary resources here
                this.filterConfig = config;
                this.servletContext = config.getServletContext( );

                // You can get access to initialization parameters from        web.xml
                // although this example doesn't really use it
                String logFileName = config.getInitParameter( LOG_FILE_PARAM );

                // You can log messages to the servlet log like this
                log( "Logging to file " + logFileName );

                // Maybe initialize a third-party logging framework        like log4j
        }

        public void doFilter( ServletRequest request,ServletResponse response,FilterChain filterChain )       
                              throws IOException, ServletException {
                // Log a message here using the request data
                log( "doFilter called on LoggingFilter" );

                // All request and response headers are available to the filter
                log( "Request received from " +        request.getRemoteHost( ) );

                // Call the next filter in the chain
                filterChain.doFilter( request, response );
        }

        public void destroy( ){
                // Remove any resources to the logging framework here
                log( "LoggingFilter destroyed" );
        }

        protected void log( String message ) {
                getServletContext( ).log("LoggingFilter: " + message );
        }

        protected ServletContext getServletContext( ){
                return this.servletContext;
        }
}


[web.xml]

<filter>
                <filter-name>MyLoggingFilter</filter-name>
                <filter-class>LoggingFilter</filter-class>
                <init-param>
                        <param-name>log_file_name</param-name>
                        <param-value>log.out</param-value>
                </init-param>
        </filter>

        <filter-mapping>
                <filter-name>MyLoggingFilter</filter-name>
                <servlet-name>MyExampleServlet</servlet-name>
        </filter-mapping>

        <filter-mapping>
                <filter-name>MyLoggingFilter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>



다음은 필터 기능을 이용하여 스트럿츠에서 한글 문제를 해결 한 경우 입니다.

[SetCharacterEncodingFilter.java]

package filters;


import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;



public class SetCharacterEncodingFilter implements Filter {

    protected String encoding = null;

    protected FilterConfig filterConfig = null;


    /**
    * Should a character encoding specified by the client be ignored?
    */
    protected boolean ignore = true;


    public void destroy() {

        this.encoding = null;
        this.filterConfig = null;

    }


    public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain)
        throws IOException, ServletException {

        // Conditionally select and set the character encoding to be used
        if (ignore || (request.getCharacterEncoding() == null)) {
            String encoding = selectEncoding(request);
            if (encoding != null)
                request.setCharacterEncoding(encoding);
        }

        // Pass control on to the next filter
        chain.doFilter(request, response);

    }

    public void init(FilterConfig filterConfig) throws ServletException {

        this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
        String value = filterConfig.getInitParameter("ignore");
        if (value == null)
            this.ignore = true;
        else if (value.equalsIgnoreCase("true"))
            this.ignore = true;
        else if (value.equalsIgnoreCase("yes"))
            this.ignore = true;
        else
            this.ignore = false;

    }


    protected String selectEncoding(ServletRequest request) {

        return (this.encoding);

    }
}


[web.xml]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app>

<!-- Example filter to set character encoding on each request -->
<filter>
 <filter-name>Set Character Encoding</filter-name>
 <filter-class>filters.SetCharacterEncodingFilter</filter-class>
 <init-param>
  <param-name>encoding</param-name>
  <param-value>EUC-KR</param-value>
 </init-param>
</filter>

<!-- Define filter mappings for the defined filters -->
<filter-mapping>
 <filter-name>Set Character Encoding</filter-name>
 <servlet-name>action</servlet-name>
</filter-mapping>

    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
       
        <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>3</param-value>
        </init-param>
        <init-param>
            <param-name>detail</param-name>
            <param-value>3</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
 
</web-app> 

(오라클자바커뮤니티, 자바교육, 오라클교육)Struts Exception Handler

ㅍException Handler

Action은 검사를 마친 예외들의 전부 혹은 일부를 ActionServlet으로 돌려 보내며 예외들을 처리하게 됩니다.

만약 ActionServlet이 예외를 처리 한다면 서블릿은 예외의 타입이나 상위 타입을 위한 Handler가 등록되었는지 검사 합니다.

ActionMapping 클래스의 지역 Exception Handler를 먼저 확인하고 그 다음 전역(global) 예외들을 검색 합니다.

ExceptionHandler는 exception 요소를 사용하여 다음과 같이 등록 합니다.

<exception
        type = “org.apache.struts.webapps.example.ExpiredPasswordException”
        key = “expired.password”
        path = “/changePWD.jsp” />

만약 ExpiredPasswordException이 발생 한다면 디폴트 핸들러는 특정 키와 특정 경로의 ActionForward를 사용하여 ActionError를 생성 합니다. 그러면 모듈안의 / changePWD.jsp로 포워드 됩니다.

이 순간 JSP는 메시지 리소스 번들로부터 expired.password라는 키에 해당 하는 메시지를 출력 할 것입니다. 만약 path 속성을 생략하게 되면 디폴트 핸들러는 ActionMapping의 input 속성을 이용 합니다.

ExceptionHandler 클래스는 반드시 org.apache.struts.action.ExceptionHandler의 하위 클래스이어야 합니다. 처음 실행되는 메소드는 execute() 메소드 입니다.

Action의 execute() 메소드처럼 작업이 끝나면 ActionForward를 반환하면 됩니다.

org.apache.struts.config.ExceptionConfig 빈은 struts-config.xml에서 exception 요소를 나타내며 특별한 프로퍼티 집합이 필요하면 ExceptionConfig의 서브 클래스를 만든 다음 <set-property> 요소를 사용하여 설정 파일로부터 속성을 초기화 하면 됩니다. 

[ORACLEJAVA, 오라클자바교육강좌]struts DataBase 접근하기(DBCP)

DataBase 접근하기 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)   

스트럿츠를 이용한 대부분의 개발은 데이터베이스에 대한 접근을 하게 됩니다. 가장 좋은 구성은 Action이 프리젠테이션 영역과 비즈니스 로직 영역을 연결하는 thin adapter 역할을 하도록 구성 하는 겁니다.

DAO approach인 경우 데이터에 대한 접근은 Business Interface의 뒤쪽에 숨어 있게 됩니다. 비즈니스 클래스에 대한 구현은 Connection Pool을 지원하는 DataSource를 통해 이루어 지므로 대부분의 데이터베이스에 대한 접근은 Connection Pool을 이용한다고 보면 됩니다.

Connection Pool이라는 것은 간단히 말해 DB에 연결을 맺은 Connection 객체를 미리 만들어 주어 사용자가 접속하면 할당을 하는 형태로 DB접속을 관리하는 것을 말합니다. 실제 테스트를 해보면 아시겠지만 데이터베이스에 대한 Connection을 수립하는데도 많은 비용이 드는 것은 사실이니까요… 생성과 삭제, 관리등을 Connection Pool에서 알아서 관리 해줍니다.

대부분의 컨테이너와 데이터베이스 시스템은 DataSource에 대한 구현을 번들로 제공 합니다. DataSource는 JNDI를 통해 접근이 가능하며 JNDI approach인 경우 별다른 고민 없이 DataSouce에 대한 비즈니스 클래스의 접근을 용이하게 해 줍니다.



-------------------------------
Struts DataSource Manager
-------------------------------

비즈니스 로직 계층에서는 데이터액세스에 대한 상세한 부분과 데이터베이스의 Conenction을 얻는  부분을 캡슐화 합니다. Struts에서는 DataSource Manager 라는 것이 있어 Action 클래스가 데이터 액세스 요구에 위해 리소스(DB Connection등)를 생산해 내는 것을 쉽게 만들어 줍니다.

가능하다면 데이터를 액세스 하는 경우 DAO(Data Access Object) 패턴을 사용하기를 권고 하며 그래서 Action 클래스는 내부의 메커니즘을 알 필요가 없게 되는 것입니다. 

DataSource Manager는 1.X 버전과의 호환을 위해 존재하며 향후 2.x 버전에서는 사라질 예정 입니다.

DataSource Manager는 struts-config.xml 파일에서 설정하며 javax.sql.DataSource 인터페이스를 구현한 어떠한 Conenction Pool에서도 deploy해서 사용 할 수 있습니다.

만약 현재 사용하고 있는 DB or 컨테이너가 javax.sql.DataSouce 인터페이스를 구현한 클래스를 제공 하다면 있는 것을 사용하셔도 무방 합니다.  대부분의 엔터프라이즈 애플리케이션 개발에서 보다 나은 성능을 위해 다른 connection pool을 사용하고 있죠^^

이 강좌에서는 Jakarta Commons dbcp's BasicDataSource(org.apache.commons.dbcp.BasicDataSource)를 이용하여 DataSource를 사용해 보도록 하겠습니다.

DBCP는 다음  URL에서 다운 받으시기 바랍니다.

http://jakarta.apache.org/commons/dbcp/downloads.html

1.        DBCP BasicDataSource를 사용하기 위한 설정은 아래와 같습니다…(struts-config.xml에 설정)

<!-- =============== for DataSource ======================= -->
<data-sources>
<!-- configuration for commons BasicDataSource -->
<data-source key="mysql" type="org.apache.commons.dbcp.BasicDataSource">
            <set-property property="driverClassName" value="com.mysql.jdbc.Driver" />
            <set-property property="url" value="jdbc:mysql://localhost/test" />
            <set-property property="username" value="root" />
            <set-property property="password" value="pw" />
            <set-property property="maxActive" value="10" />
            <set-property property="maxWait" value="5000" />
            <set-property property="defaultAutoCommit" value="true" />
            <set-property property="defaultReadOnly" value="false" />
            <set-property property="maxIdle" value="10000" />
        </data-source>
        <data-source key="oracle" type="org.apache.commons.dbcp.BasicDataSource">
            <set-property property="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
            <set-property property="username" value="scott" />
            <set-property property="password" value="tiger" />
            <set-property property="url" value="jdbc:oracle:thin:@localhost:1521:WINK" />
            <set-property property="maxActive" value="50" />
            <set-property property="maxIdle" value="10000" />
            <set-property property="maxWait" value="100" />
            <set-property property="defaultAutoCommit" value="true" />
</data-source>
</data-sources>

2. 소스 코드에서는 아래와 같이 사용 합니다.

public ActionForward
      execute(ActionMapping mapping,
              ActionForm form,
              HttpServletRequest request,
              HttpServletResponse response) throws Exception
{
 javax.sql.DataSource dataSource;
 java.sql.Connection myConnection;
 try {
  //for oracle
  javax.sql.DataSource dataSource = getDataSource(request,"oracle");
  myConnection = dataSource.getConnection();
 } catch (SQLException sqle) {
    getServlet().log("Connection.process", sqle);
 } finally {
    //enclose this in a finally block to make
    //sure the connection is closed
    try {
      myConnection.close();
    } catch (SQLException e) {
      getServlet().log("Connection.close", e);
    }
  }
}

3.        다중 데이터 소스를 사용하는 경우에는 struts-config.xml에서 다음과 같이 선언 합니다.

<data-sources>
  <data-source key="A" type="org.apache.commons.dbcp.BasicDataSource">
      ... properties as before ...
  </data-source>
  <data-source key="B" type="org.apache.commons.dbcp.BasicDataSource">
      ... properties as before ...
  </data-source>
  ...
</data-sources>


4.        다중 데이터 소스인 경우 프로그램에서는 다음과 같이 사용 합니다.

...
  try {
      dataSourceA = getDataSource(request, "A");
      dataSourceB = getDataSource(request, "B");
  ...

2013년 8월 3일 토요일

[SQL초보실전전문가]조인 방법 변경(USE_MERGE) , 오라클교육,오라클힌트 교육, 자바교육

[Hint]조인 방법 변경(USE_MERGE)
 
구로디지털 오엔제이프로그래밍실무교육센터
 
 
머지 조인(Merge Join)이 일어나도록 유도하는 힌트 구문으로 이 경우 거의 SORT를 동반하므로 SORT MERGE JOIN이라고 부릅니다머지 조인이란 양쪽 테이블에서 대상 로우를 추출 후 조인 컬럼을 기준으로 SORT를 한 후 최종 결과를 만들어 내는 조인 방식 입니다.
 
USE_NL처럼 FROM 절 다음에 위치하는 테이블의 순서는 중요하지 않은데 그 이유는 어차피 독립적으로 정렬된 후 병합이 일어나므로 중요하지 않다고 할 수 있으며 SORT MERGE JOIN에서는 드라이빙 테이블의 의미가 없습니다.
 
[형식]
 
 
[]
아래 예제는 Oracle 10g에서 돌렸습니다.
 
 
select 
       e.empno,
          e.ename,
          d.dname,
          d.loc
from   dept d, emp e
where  e.deptno = d.deptno
 
---------------------------------------------------------------
Operation            Object Name      Rows     Bytes    Cost     
-------------------------------------------------------------
SELECT STATEMENT Optimizer Mode=ALL_ROWS               14                      5
  MERGE JOIN                  14         406       5                                                       
    TABLE ACCESS BY INDEX ROWID         SCOTT.DEPT      4           72         2            
      INDEX FULL SCAN   SCOTT.PK_DEPT             4                        1            
    SORT JOIN                 14         154       3                                                       
      TABLE ACCESS BY INDEX ROWID      SCOTT.EMP        14         154       2            
        INDEX FULL SCAN             SCOTT.IDX_EMP_DEPTNO            13                      1                                                           
 
select 
       e.empno,
          e.ename,
          d.dname,
          d.loc
from   dept d, emp e
where  e.deptno = d.deptno
 
---------------------------------------------------------------------
Operation            Object Name      Rows     Bytes    Cost     
------------------------------------------------------------------
SELECT STATEMENT Optimizer Mode=ALL_ROWS               14                      5
  MERGE JOIN                  14         406       5                                                       
    TABLE ACCESS BY INDEX ROWID         SCOTT.DEPT      4           72         2            
      INDEX FULL SCAN   SCOTT.PK_DEPT             4                        1                SORT JOIN                14         154               3                                                       
      TABLE ACCESS BY INDEX ROWID      SCOTT.EMP        14         154       2            
        INDEX FULL SCAN             SCOTT.IDX_EMP_DEPTNO            13                      1                                                           
 
[실습]
 
-      실습을 위한 예제 테이블 및 데이터는 아래 링크에서 확인 바랍니다.
 
myemp1 : 1000만건
myemp1_old : 100만건
mydept : 5
 
테스트환경 : oracle 11g
 
 
MYEMP1이 비드라이빙 테이블이지만 머지조인 에서는 별 의미 없다.
 
SQL> select
  2         e.ename,
  3         d.dname
  4  from   mydept1 d, myemp1 e
  5  where  e.deptno = d.deptno   ;
 
20000000 개의 행이 선택되었습니다.
 
   : 00:02:22.62
 
 
---------------------------------------------------------------------------------------
| Id  | Operation           | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |         |    20M|   476M|       | 68516   (2)| 00:13:43 |
|   1 |  MERGE JOIN         |         |    20M|   476M|       | 68516   (2)| 00:13:43 |
|   2 |   SORT JOIN         |         |    10 |   100 |       |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| MYDEPT1 |    10 |   100 |       |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |         |    10M|   143M|   459M| 68463   (1)| 00:13:42 |
|   5 |    TABLE ACCESS FULL| MYEMP1  |    10M|   143M|       | 16941   (1)| 00:03:24 |
 
 
SQL> select
  2         e.ename,
  3         d.dname
  4  from   myemp1 e, mydept1 d
  5  where  e.deptno = d.deptno ;
 
20000000 개의 행이 선택되었습니다.
 
   : 00:02:09.58
 
---------------------------------------------------------------------------------------
| Id  | Operation           | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |         |    20M|   476M|       | 68516   (2)| 00:13:43 |
|   1 |  MERGE JOIN         |         |    20M|   476M|       | 68516   (2)| 00:13:43 |
|   2 |   SORT JOIN         |         |    10M|   143M|   459M| 68463   (1)| 00:13:42 |
|   3 |    TABLE ACCESS FULL| MYEMP1  |    10M|   143M|       | 16941   (1)| 00:03:24 |
|*  4 |   SORT JOIN         |         |    10 |   100 |       |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| MYDEPT1 |    10 |   100 |       |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

2013년 8월 2일 금요일

JAVA DataInputStream/DataOutputStream – 예제

import java.io.*;

class InputStreamTest {
  public static void main(String[] args) throws IOException {
    FileInputStream fis=new FileInputStream(args[0]);
    DataInputStream dis=new DataInputStream(fis);
    //BufferedReader dis = new BufferedReader(new InputStreamReader(fis));

    String s;
    while( (s=dis.readLine()) !=null) {  //readLine은 Deprecated 된 Method
                                //ReadLine을 사용하기 위해선 위의 주석된것을 사용
                                //하는것이 바람직하다.
System.out.println(s);
}
    fis.close();
  }
}




===================



import java.io.*;

class OutputStreamTest {
  public static void main(String[] args) throws IOException  {
FileOutputStream fos = new FileOutputStream("test.txt");
DataOutputStream dos=new DataOutputStream(fos);

dos.writeChars("하하하");
//dos.write("홍길동".getBytes()); //Default문자인코디을 따라 byte[]로 만듬
dos.writeUTF("256-1234");
os.writeInt(30);

dos.close();

  }

2013년 8월 1일 목요일

자바의 특성(객체지향적) , ORACLE JAVA OOP 실무강좌

******** 자바의 특성(객체지향적) ************

추상화(Abstraction) : 실제 사물을 명사화/동사화 시켜서 프로그램에 적용할수 있는 형태로 만드는 것
상속성(Inheritance) : 미리 만들어진 소스를 가지고 공유하며 재사용하고, 또한 특별한 부분에 대 해서는 다시 재정의해서 사용하는 것 자바에서 상속은 한 클래스를 확장하여 새로운 클래스를 만드는 것을 말한다. 이렇게 새로 만들어지는 클래스를 하위클래스(subclass)라고 부른다. 그리고 원래의 클래스는 상위클래스(superclass)라고 부른다.
다형성(Polymorphism) : 상속을 받은 것을 그대로 사용하지 않고 입맛에 맞게 바꾸어 줄 수 있도록 하는것이며 이 때문에 다형성 함수는 전달하는 변수의 타입을 고려하지 않게된다.
캡슐화(Encapsulation) : 캡슐화는 사용자로부터 객체 내부의 데이터를 감추는 것이다. 데이터를 변수로 나타내며, 클래스의 함수와 프로시저는 메소드(Method)라고 한다. 클래스가 다른 클래스의 데이터를 다루려면 메소드를 통해야 한다. 이러한 캡슐화는 객체 내부의 처리과정을 알 필요없이 그것을 다루는 메소드에 대해서만 알면 된다는 점에서 편리하다. 변수들(외부에서 임의로 조작되었을때 원하지 않는 결과가 나오는것들 또는 잘못된 결과가 나오는것들) 에대해서 외부로 부터 접근제한을 시키는 것이 바로 encapsulation, 즉 객체내부의 데이터와 메소드 항목을 정의할때 private로 지정하여 클래스 외부에서의 접근을 제한하는것.


다중 쓰레드를 지원한다.
- 프로세스는 실행중인 프로그램을 뜻하는 말입니다. 보통 프로세스가 운영 체제의
여 러 자원을 사용하는 기본 단의 입니다.
- 쓰레드(Thread)란 프로세스 내부에서 실행되는 일련의 명령 흐름을 뜻합니다.
프로세스내의 제어의 단일 순차 흐름을 의미하며, 때때로 수행 문맥
(execution context)또는 가벼운 프로세스(lightweight peocess)라함
- 프로세스가 실행되면서 하나의 흐름만을 갖는 것이 아니라 여러 개의 흐름으로
분기할 수 있으며 하나의 프로세스가 같은 시간에 여러 가지 일을 수행하기
위해서 여러 개의 스레드를 만들게 됩니다.
- 다중 쓰레드란 하나의 프로그램내에서 동시에 수행되며 서로 다른 작업들을
수행하는 복수개의 쓰레드들을 의미한다.


[예제]
class Employee {
String name;
String id;

//생성자
public Employee(String name1, String id1) {
name = name1;
id = id1;
}
public void gotoOffice() {
System.out.println(name+"님 출근하였습니다...");
}
public void gotoHome() {
System.out.println(name+"님 퇴근하였습니다...");
}
}


class Manager extends Employee {
String chargeDept;
public Manager(String newName,String newID,String newDept) {
//super는 상위클래스의 생성자를 의미
super(newName, newID);
this.chargeDept = newDept;
}

public void startJob() {
System.out.println(this.chargeDept +” “+ super.name + "님이 직원관리를 시작합니다...");
}
}


class Example {
public static void main(String args[]) {
Manager m = new Manager("이종철","12345","솔루션개발부");
m.gotoOffice();
m.startJob();
m.gotoHome();
Manager m1 = new Manager("홍길동","12346","고객관리부");
m1.gotoOffice();
m1.startJob();
m1.gotoHome();
}
}