'분류 전체보기'에 해당되는 글 2491건

  1. 2009.01.23 [velocity] 총 정리
  2. 2009.01.23 Velocity란 무엇인가?
  3. 2009.01.23 Eclipse Plug-In : Velocity WebEditor 설치 방법
  4. 2009.01.23 cookie 정보 확인 스크립트
  5. 2009.01.23 JSTL과 Velocity를 활용한 UI 레이어 구현 방법
  6. 2009.01.23 velocity 문법 간단 정리 1
  7. 2009.01.23 xerces를 사용한 dom 방식의 xml parser lib
  8. 2009.01.23 SUN JAVA STREAMING XML PARSER 소개
  9. 2009.01.23 //인터넷 XML 날씨 정보를 파싱 (DomParser.java) : dom,parser,java
  10. 2009.01.23 XML Parser 함수들
  11. 2009.01.23 Parser 와 DOM 기초
  12. 2009.01.23 Apache AXIS 설치
  13. 2009.01.23 http://xerces.apache.org/xerces2-j/samples.html
  14. 2009.01.23 Apache parser
  15. 2009.01.23 xml 파서 jsp 버전
  16. 2009.01.23 xml 스트링 로드하고 분석하기
  17. 2009.01.23 parseXML (xml 파서) 1
  18. 2009.01.22 오라클의 날짜 함수 1
  19. 2009.01.22 새로운 JSTL1.1 태그 라이브러리 지정자 1
  20. 2009.01.22 jstl
  21. 2009.01.20 submit 후 button 막기
  22. 2009.01.20 jsp, ie 첨부파일 열기 실행시 에러 ( 캐쉬폴더에서 실행시 에러), jsp 2
  23. 2009.01.20 request.getParameter null 값 처리 5
  24. 2009.01.20 리눅스 보안 관련 소프트웨어
  25. 2009.01.19 "Server unexpectedly closed network connection" 해결방안
  26. 2009.01.19 리눅스를 사용하면서 내가 깜박 깜박 잊어버리는 자잘한 팁을 모았음. 검색이 어려우면 키워드로 검색할 것.
  27. 2009.01.19 미디어 플레이어 제어
  28. 2009.01.19 자바스크립트 팝업창 관련
  29. 2009.01.19 clob 사용법
  30. 2009.01.19 오라클 내부 함수
98..Etc/velocity2009. 1. 23. 15:05
반응형

Spring과 함께 사용

전형적인 디렉토리 구조

그림:VelocityDirectoryStructure.png

  • velocity와 velocity tool을 사용하기 위해 필요한 jar 파일을 lib에 넣어야 한다.
    • velocity-dep-*.jar : velocity 그리고 관련된 클래스 파일
    • velocity-tools-*.jar : velocity tool
    • commons-digester
    • commons-collections
    • commons-beanutils
  • /WEB-INF/velocity 를 velocity template 루트로 잡는다.
  • /WEB-INF/velocity/VM_global_library.vm 가 디폴트 매크로 파일이 된다.
  • /WEB-INF/toolbox.xml 은 velocity tool의 설정이다.
  • 각 설정파일의 위치를 변경하려면 *-servlet.xml에서 한다.

*-servlet.xml

  • -servlet.xml 에 velocity 관련 설정을 넣어 사용할 수 있다.

SpringMVC를 참고할 것.

velocity properties

velocity 관련 설정은 별도의 velocity.properties를 만들어 할 수도 있지만, *-servlet.xml에서 직접 할 수도 있다. 'velocityConfig' 부분의 'velocityProperties' 부분에 property를 추가하면 된다. velocity property의 전체 항목은 velocity jar 파일의 /org/apache/velocity/runtime/default/velocity.properties 에서 확인할 수 있다.

VM_global_library.vm

예를들어 다음과 같이 만들 수 있다.

#macro (xhtml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html 
   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
#end

VTL (Velocity Template Language) 문법

간단한 예제

<html>
<body>
#set ($foo = "Velocity")
Hello $foo World!
</body>
<html>

코멘트

## 로 시작하면 한 줄 코멘트

## 한 줄 코멘트 single-line comment

#* 로 시작하고 *#로 끝나면, 여러 줄 코멘트

#*
 여러 줄 코멘트. 
 여기에 표시되는 내용은 
 Velocity Template Engine이 무시해버린다.
*#

#** 로 시작하고 *#로 끝나면, 블록 코멘트. 사실 여러 줄 코멘트와 다를 것은 별로 없다. 저자나 버전 등을 넣는데 주로 사용한다.

#**
 This is a VTL comment block and
 may be used to store such information
 as the document author and versioning
 information:
 @author
 @version 5
*#

변수 Variable

변수는 $로 시작하며, [a-zA-Z0-9-_] 문자가 변수에 사용될 수 있다.

#set로 변수에 값을 세팅할 수 있다.

#set ($foo = "bar")

원래는 ${foo} 형태가 정식적인(formal) 표현이다. 텍스트 중간에 변수가 들어갈 때 잘못 파싱되는 것을 방지하기 위해, 반드시 이 형태를 사용해야 할 경우가 있다.

Jack is a $vicemaniac.
Jack is a ${vice}maniac.

프라퍼티 Property

변수 안의 프라퍼티에 접근할 수 있다.

$customer.address
$purchase.total

Java Beans 표준의 property 규칙이 그대로 사용된다. (getX(), setX() 등)

메소드 Method

변수로부터 메소드를 곧바로 실행할 수도 있다.

$customer.getAddress()
$date.format("yyyy-MM-dd", $createTime)

조용한 레퍼런스 Quiet Reference

만약 $foo 라고 썼는데 foo 라는 이름의 객체가 존재하지 않는다면, $foo 라는 글자가 결과에 그대로 표현된다. 객체가 존재하지 않을 때 아무것도 표현되지 않게 하려면, $ 다음에 !를 붙인다.

<input type="text" name="email" value="$email"/>
<input type="text" name="email" value="$!email"/>

물론 정식적인 표현도 가능하다.

<input type="text" name="email" value="$!{email}"/>

escaping

'$' 를 표현하려면 \$ 로 한다. '\$' 는 '\\$' 로 표시한다.

혹은 다음과 같이 할 수 있다.

#set ($dollar = "$")
$dollar

지시자 Directive

지시자는 #로 시작한다. ${..}와 같은 이유로, #{..} 표현도 가능하다.

#if($a==1)true enough#elseno way!#end
#if($a==1)true enough#{else}no way!#end

#set

변수에 값을 지정하기 위해 사용한다.

#set ($primate = "monkey") ## literal
#set ($monkey = $bill) ## variable reference
#set ($monkey.Friend = "monica") ## string literal
#set ($monkey.Blame = $whitehouse.Leak) ## property reference
#set ($monkey.Plan = $spindoctor.weave($web)) ## method reference
#set ($monkey.Number = 123) ## number literal
#set ($monkey.Say = ["Not", $my, "fault"]) ## ArrayList
#set ($monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map

#set ($value = $foo + 1)
#set ($value = $bar - 1)
#set ($value = $foo * $bar)
#set ($value = $foo / $bar)

같은 변수에 다른 값을 넣으면, 마지막 넣은 값이 저장된다.

값을 unset 하는 기능은 없다.

Literal

set 할때 문자열은 큰따옴표(") 로 감싸진다. 이 안에 변수가 있으면, 그것도 해석(parse)된다.

#set( $directoryRoot = "www" )
#set( $templateName = "index.vm" )
#set( $template = "$directoryRoot/$templateName" )
$template

결과값은

www/index.vm

하지만 작은따옴표(')로 감싸면 해석되지 않는다.

#set( $foo = "bar" )
$foo
#set( $blargh = '$foo' )
$blargh

결과는

bar
$foo

조건문 if-else

#if ($foo < 10)
   Go North
#elseif ($foo == 10)
   Go East
#elseif ($bar == 6)
   Go South
#else
   Go West
#end

== 연산은 primitive, string, object를 비교하는데, object의 경우 toString()의 값이 비교된다.

AND 연산 : &&

#if ($foo && $bar)
   This AND that
#end

OR 연산 : ||

#if ($foo || $bar)
   This OR That
#end

NOT 연산 : !

#if (!$foo)
  NOT that
#end

$!foo 와 !$foo 를 혼동하지 말 것!

반복문 Loops

$allProducts가 List나 Array인 경우에는 이렇게 한다.

#foreach( $product in $allProducts )
   $product
#end

$allProducts가 Map이나 Hashtable이라면, 이렇게 할 수 있다.

#foreach( $key in $allProducts.keySet() )
   Key: $key -> Value: $allProducts.get($key)
#end

현재 루프 카운트는 $velocityCount로 알아올 수 있다.

#foreach( $customer in $customerList )
   $velocityCount : $customer.Name
#end

$velocityCount 이름과 0부터 시작하는지 1부터 시작하는지 등은 설정 가능하다.

include

#include ("one.txt")
#include ("one.gif","two.txt","three.htm")
#include ("greetings.txt", $seasonalstock)

파일의 내용을 그대로 include한다. 여러 파일을 한꺼번에 include할 수 있다. 파일 이름에 변수가 들어갈 수 있다.

parse

#parse ("me.vm")

파일을 파싱해서 그 결과를 include한다. 한번에 하나의 파일만 가능하다.

Count down.
#set ($count = 8)
#parse ("parsefoo.vm")
All done with dofoo.vm!
#set ($count = $count - 1)
#if ($count > 0)
   #parse ("parsefoo.vm")
#else
   All done with parsefoo.vm!
#end

재귀적으로 사용 가능한데, 깊이가 정해져있다. 깊이는 설정 가능하고, 디폴트로 10이다.

stop

#stop

파싱을 멈춘다.

매크로

일종의 함수 같은 것이다.

다음과 같이 정의하고,

#macro (d)
   <tr><td></td></tr>
#end

다음과 같이 사용한다.

#d()

파라미터를 매크로 이름 뒤에 변수로 받을 수 있다.

#macro (callme $a)
   $a $a $a
#end

이렇게 사용한다.

#callme ($foo.bar())

Velocity Tool

Cookie Tool

$cookie.foo.value
$cookie.add("cookieName", "cookieValue")

Import Tool

$import.read("http://www.rolizen.com/import/url")

Parameter Tool

$params.foo
$params.getString("foo")
$params.getNumber("foo")
$params.getInt("foo")

Alternator Tool

예를들어, 루프를 돌면서 table의 tr을 찍는데, 홀수줄은 흰색으로, 짝수줄은 회색으로 찍고 싶은 경우,

#set ($color = $alternator.auto(["fff", "eee"))
#foreach ($item in $listItems)
<tr style="background-color:#$color">...</tr>
#end

Date Tool

$date                                          -> 2007. 2. 5 오후 3:14:43 
$date.get("yyyy-MM-dd HH:mm:ss")               -> 2007-02-05 15:14:43
$date.format("yyyy-MM-dd HH:mm:ss", $myDate)   -> 2007-02-03 16:31:34

Number Tool

#set ($val = 1234567)
$number.format("currency", $val)   -> ₩1,234,567
$number.format("integer", $val)    -> 1,234,567
$number.format("0,000", $val)      -> 1,234,567
$number.format("0,0000", $val)     -> 123,4567
$number.format("0", $val)          -> 1234567

Escape Tool

$html                        -> "bread" & "butter"
$esc.html($html)             -> "bread" & "butter"
$xml                         -> "bread" & "butter"
$esc.xml($xml)               -> "bread" & "butter"
$javascript                  -> He didn't say, "Stop!"
$esc.javascript($javascript) -> He didn\'t say, \"Stop!\"
$esc.dollar                  -> $
$esc.d                       -> $
$esc.hash                    -> #
$esc.h                       -> #
$esc.backslash               -> \
$esc.b                       -> \
$esc.quote                   -> "
$esc.q                       -> "
$esc.singleQuote             -> '
$esc.s                       -> '
$esc.exclamation             -> !
$esc.e                       -> !

Iterator Tool

List Tool

List나 Array에서 엘리먼트를 get / set 할 수 있다.

$primes                    -> new int[] {2, 3, 5, 7}
$list.size($primes)        -> 4
$list.get($primes, 2)      -> 5
$list.set($primes, 2, 1)   -> (primes[2] becomes 1)
$list.get($primes, 2)      -> 1
$list.isEmpty($primes)     -> false
$list.contains($primes, 7) -> true

Math Tool

Sorter Tool

Velocity Tool 만드는 법

일반적인 Tool

그냥 일반적인 class를 만들면 된다. public한 field와 method를 사용할 수 있다.

context 를 갖는 Tool

public class MemberUtil {
   private HttpServletRequest request;
   private HttpSession session;
   private MemInfoData meminfo;

   public void init(Object obj) {
      ChainedContext cc = (ChainedContext)obj;
      this.request = cc.getRequest();
      this.session = request.getSession(true);
      meminfo = (MemInfoData)session.getAttribute(MemInfoData.MEMINFO_SESSION_KEY);
      if (!validMemInfo(meminfo))
         meminfo = null;
   }

   private boolean validMemInfo(MemInfoData mid) {
      return (mid != null) && (mid.getMemNo() > 0) && (mid.getOpenid() != null);
   }

   public HttpServletRequest getRequest() {
      return request;
   }

   public HttpSession getSession() {
      return session;
   }

   public MemInfoData getMeminfo() {
      return meminfo;
   }

   public boolean isLogin() {
      return (meminfo != null);
   }
}

위와 같이 init() 메소드를 이용해 context를 받을 수 있다.

참고사이트  : http://velocity.apache.org

출처 :http://technet.ui2.co.kr/wiki/index.php/Velocity

Posted by 1010
98..Etc/velocity2009. 1. 23. 15:04
반응형

Velocity 무엇인가?

Velocity 자바 기반의 템플릿 엔진이다.

Velocity 페이지 디자이너들이 자바 코드안에서 정의된 메소들에 접근하는 것을 도와준다. 이것은 페이지 디자이너들이 자바 개발자들과 함께 Model-View-Controller(MVC) 아키텍쳐에 따른 사이트를 각자의 영역에서 최선의 결과를 가져오도록 도와준다는 것을 의미한다.

Velocity 페이지로부터 자바 코드를 분리할 있고, 웹사이트를 계속 오랫동안 유지할 있으며, 자바 서버 페이지(JSP) 실용적인 대안을 제공한다.

Velocity 무엇을 있나?

당신이 진흙(Mud) 판매하는 "온라인 진흙 가게" 페이지 디자이너 이라고 가정해보자. 그리고 고객들은 다양한 종류와 많은 수량의 진흙을 주문하여 당신의 가게는 날로 번성하고 있다.

고객들은 사용자 이름과 패스워드를 입력하고 당신의 사이트에 로그인하여 자신이 이전에 주문했던 주문목록을 조회하고, 다른 진흙을 수도 있다. 모든 고객에 관한 정보는 당신의 데이타 베이스안에 저장되고 있다.

데이타 베이스에 따르면 특별히 설악산에서 만든 진흙이 매우 인기가 좋으며, '설악산 진흙'보다 인기가 일본산 빨간 진흙도 정기적으로 일본에서 수입하고 있다.

그러던 어느날 당신은 '설악산 진흙' 흥미를 느끼는 수많은 고객들과의 특별한 거래를 찾는데 Velocity 사용하지 않는 지에 대한 의문을 갖게된다.

Velocity 웹페이지를 통한 당신의 온라인 방문객들에게 진흙 판매를 쉽게 해준다. 진흙 가게의 웹사이트 디자이너인 당신은 고객이 사이트 로그인 후에 보게 특별한 페이지를 원하고 있다.

명심하라. 당신은 개발자들이 데이터베이스에서 필요한 정보를 어떻게 추출하는지에 대해 걱정할 필요가 없다. 당신은 단지 그것이 올바르게 작동한다는 것만 기억하면 된다. 그렇게 되면 당신은 당신만의 페이지 디자인을 하게 되고, 개발자들은 그들만의 일을 하게 된다.

이런 결과로, 당신은 로그인한 사용자에게 나타낼 동적인 정보를 아래와 같이 velocity Template Language(VTL) 문장을 사용해 웹페이지에 넣을 있게 된다.

 
Hello, $customer.Name! <br>
$flogger.getPromotion( $mud )

$customer 현재 로그인한 사용자에 대한 정보를 가지고 있고, $promotion 로그인한 고객별로 데이타 베이스를 조회에 해당 고객에 맞는 추천 상품을 소개하는 일을 한다.

그래서 '설악산 진흙' 오랫동안 구입해온 기록을 가진 고객이 로그인 했을 '설악산 진흙 현재 대폭 세일중!!' 이라는 메시지를 정면에서 보게 것이다.

Velocity 힘과 유연함은 이렇게 VTL 레퍼런스와 함께 당신에게 제공된다.

VTL (Velocity Template Language)

VTL Velocity에서 템플릿 개발에 사용되는 언어로 레퍼런스(Reference), 디렉티브(Directive), 그리고 주석(Comment)으로 구성된다.

레퍼런스

${variable}

컨텍스트에서 제공되는 변수에 대한 레퍼런스

${variable.property}

속성에 대한 레퍼런스

${variable.method(args)}

메소드 대한 레퍼런스

디렉티브

#set

레퍼런스의 값을 설정

#if #elseif #else

조건문 제어

#foreach

반복문 제어

#include

파싱되지 않는 로컬 파일 출력

#parse

파싱되는 로컬 템플릿 출력

#stop

템플릿 엔진의 동작 정지

#macro

반복적으로 사용될 매크로 정의

주석

##

줄짜리 주석

#* .... *#

여러 줄에 걸친 주석

VTL 표에서 정리한 것처럼 너무나 단순하기 때문에 흔히 성냥갑 표지에 적을 있을 만큼 작은 API라고 불려진다.

이는 작업을 개발자와 디자이너가 함께 진행해 나간다는 점을 감안하면 매우 바람직한 일이라고 있다.

VTL 통해 작성된 벨로시티 템플릿(vm 파일) 다음과 같은 패턴을 통해 처리 된다.

// 벨로시티 템플릿 엔진의 초기화
//
초기화 설정은 velocity.properties 파일을 사용함
Velocity.init("velocity.properties");

//
자바 클래스와 템플릿간의 정보 전달에 사용할 컨텍스트 객체 생성
//
컨텍스트 객체는 해시 테이블을 상속받으므로 (, ) 순서쌍 형태로 값을 저장 
//
) context.put("members", memberDAO.getMembers());
//
이렇게 해서 컨텍스트에 저장된 값들은 템플릿에서 레퍼런스를 이용해서 참조됨
//
컨텍스트에 담긴 값이 컬렉션일 경우 #foreach 디렉티브를 통해 하나씩 참조 가능 
VelocityContext context = new VelocityContext();
Template template = null;

//
로직과 연결되어 사용될 템플릿 파일을 선택
template = Velocity.getTemplate("HelloWorld.vm");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

//
템플릿과 컨텍스트를 렌더링해서  결과를 출력 
if ( template != null)
  template.merge(context, writer);

writer.flush();
writer.close();

템플릿 엔진이 동작하는 방식을 정리해 보면, 개발자는 사용자에게 보여 디자인을 위해 VTL 이용한 템플릿 파일을 작성하고, 처리를 위한 코드를 개발한다.

자바 코드와 템플릿 간의 필요한 정보 전달은 컨텍스트 객체를 통해 이루어진다.

이러한 2개의 파일을 입력받아 벨로시티는 템플릿을 토대로 렌더링한 결과 페이지를 출력하게 되는 것이다.

템플릿에 어떤 내용이 담겨 있느냐에 따라 결과 페이지는 일반 텍스트가 수도 있고, HTML이나 SQL, PostScript, XML 등도 있다.

 

 

Velocticy 템플릿 언어 (VTL)

Velocticy 템플릿 언어(velocity Template Language : VTL) 페이지에서 동적인 내용을 구체화하기 가장 쉽고, 가장 간결하고 가장 확실한 방법을 제공하는 수단이다.

심지어 프로그래밍 해본 경험이 적거나 전혀 없는 페이지 개발자도 웹사이트에서 동적인 내용를 구체화 하는데 VTL 금방 사용할 있다.

VTL 웹사이트에서 동적인 내용을 끼워넣는데 필요한 레퍼런스를 사용한다. 레퍼런스의 타입은 variable이다.

Variables 자바 코드에서 정의된 것에 대해 언급할 있는 레퍼런스의 타입 이거나, 또는 웹페이지 자체의 VTL 에서 지원하는 타입일 있다.

아래는 HTML 문서안에 삽입될 있는 VTL문의 예제다.

 
#set ( $a = "velocity" ) 

VTL문은 모든 VTL문처럼 #기호로 시작하고 set 명령어를 포함하고 있다. 온라인 고객이 당신의 페이지를 요청할 , Velocticy 템플릿 엔진은 당신의 페이지에 명시된 모든 #기호를 검색한다. VTL 시작할 #기호와 VTL에서 아무일도 않는 #기호들을 분리한다.

예제에 표시된 set 명령어는 둥근괄호 안에서 사용하며 특정 변수에 값를 부여하는 일을 한다. 변수는 좌변에, 변수의 값는 우변에 나열되며 좌변과 우변은 = 기호로 구분되어 진다.

위의 예에서, 변수는 '$a'이고 변수에 할당된 값은 'Velocity'이다. 변수는 다른 모든 레퍼런스들처럼 $기호로 시작한다. 값은 항상 인용부호 사이에 존재한다.

Velocticy 문자열(String) 타입만 변수에 할당할 있기 때문에 다른 데이타 타입들과의 혼란은 없다.

정리해보면 아래와 같다.

*      레퍼런스 $ 시작하고 어떤 것을 얻는데 사용된다.

*      명령어 # 시작하고 어떤 동작을 수행하는데 사용된다.

예제에서 #set 변수에게 값을 할당하는데 사용되고 $a 변수는 템플릿에서 "velocity" 출력하는데 사용되었다.

안녕 velocity

변수에 값을 할당했으면, 당신의 HTML 문서내 어디서나 변수를 레퍼런스할 있다. 다음의 예에서 $foo 값이 할당되고 레퍼런스 되는 모습을 있다.

 
#set ($ foo = "velocity" )
Hello #foo World!

문장은 결국 웹페이지에 "Hello Velocity World!" 출력할 것이다.

VTL 명령어들을 포함한 문장들을 좀더 읽기 쉽게 만들기 위해, 굳이 그럴 필요는 없지만 가급적 VTL문장을 새로운 줄에서 시작하도록 권장한다.

set 명령어는 나중에 매우 세부적으로 다시 살펴보게 것이다.

주석 처리

주석은 velocity 템플릿 엔진에 의해 해석되지 않는 설명문이다. 주석은 당신의 오래된 기억을 상기시키거나, 당신의 VTL문이 무엇을 하고 있는지, 또는 당신이 찾는 다른 다른 목적들을 설명하기에 유용한 방법이다.

아래에 VTL 주석의 예가 있다.

 
##This is a single line Comment.

한줄 주석문은 ## 시작하고 라인의 끝에서 끝난다. 당신이 여러 줄의 주석을 사용한다면, 다수의 한줄 주석을 여러 줄에 필요는 없다.

문장이 #* 시작하고 *# 끝나는 Multi-line 주석이 이런 상황에 매우 유용하다.

 
#*
Thus begins a multi-line comment. Online visitors won't
see this text because the velocity Templating Engine will
ignore it.
*#

아래 나오는 번째 타입의 주석은 문서의 저자와 버전정보와 같은 메타정보를 저장하는데 사용될 있다.

 
#**
This is a VTL comment block and
may be used to store such information
as the document author and versioning
information:
@author
@version 5
*#

참조 (References)

VTL 에서 지원하는 세가지 타입의 레퍼런스가 있다.

*      변수

*      속성

*      메소드

개발자들은 디자이너가 VTL 이용하는 템플릿에서 개발자가 설정한 레퍼런스를 정확히 사용하기 위해 레퍼런스의 특별한 이름을 지어주어야 한다.

레퍼런스로 오고 가는 모든 것은 문자열(String) 객체로 처리된다. 만약 $foo(Integer 타입이라 가정한다) 표현하는 객체가 있다면 Velocity 문자열 객체를 얻기위한 매소드로 .toString() 요청 것이다.

변수 (Variables)

변수의 표기법은 VTL 식별자로부터 불려온 '$'기호로 시작된다. VTL 식별자는 알파벳 (a...z, or A...Z)으로 시작해야 하며 나머지는 아래의 문자들로 제한된다.

*      alphabetic (a .. z, A .. Z)

*      numeric (0 .. 9)

*      hyphen ("-")

*      underscore ("_")

여기 VTL안에서 유효한 변수 레퍼런스의 예가 나온다.

 
$foo
$mudSlinger
$mud-slinger
$mud_slinger
$mudSlinger1

VTL 변수가 $foo로써 레퍼런스 , 변수는 템플릿안의 set 명령어나 자바 코드로부터 값을 얻을 있다.

예를 들어 자바 변수 $foo "value bar"라는 값을 가지고 있다면, "value bar" 웹페이지내에 정의된 모든 $foo 대체 하게 된다.

만약 다음 문장이 웹페이지 내에 정의된다면....

 
#set ( $foo = "bar" )

결과는 명령어 하위에 나오는 모든 $foo "bar" 대체할 것이다.

속성 (properties)

VTL 레퍼런스의 두번째 특징은 속성이다.

속성은 특유의 포맷을 가진다. 표기법은 기호(".") 다른 VTL 식별자가 뒤에 따르는 '$' 기호로 구성된다. 아래는 VTL안의 유효한 속성 레퍼런스의 예이다.

 
$customer.Address
$purchase.Total

예제에서 $customer.Address 두가지 의미을 가질 있다.

*      customer 객체의 멤버 변수 Address 레퍼런스 한다.

*      customer 객체의 메소드 getAddress() 레퍼런스 한다.

, $customer.getAddress() $customer.Address 생략해서 사용할 있다. 페이지가 요청될 , Velocity 이들 가능성을 이치에 맞는지 분별하여 적당한 값은 반환하게 된다.

메소드 (Method)

메소드는 자바코드 안에서 정의되며, 계산을 하거나 어떤 값을 얻는 것과 같이 유용한 무언가를 수행한다. 아래는 유효한 메소드 레퍼런스의 예이다.

 
$customer.getAddress()
$purchase.getTotal()
$page.setTitle( "My Home page" )
$person.setAttributes( ["Strange", "Weird", "Excited"] )

예제에서 나온 $customer.getAddress() $purchase.getTotal() 앞선 예제에서 나온 $customer.Address $purchase.Total 레퍼런스의 결과와 정확히 일치한다.

그러나 $page.setTitle( "My Home page" ) 같이 메소드에서는 인자를 넘길 있다는 점이 속성과 다르다. 참고로 $person.setAttributes( "Strange", "Weird", "Excited"? ) 인자로 문자열 배열을 넘기고 있다.

형식적인 레퍼런스 표기법 (Formal Reference Notation)

앞서 나온 것은 레퍼런스에 대한 속기 표기법이었다. 이제 형식적 표기법에 대해 살펴보자.

 
${mudSlinger}
${customer.Address}
${purchase.getTotal()}

거의 모든 경우에 당신은 레퍼런스를 위하여 앞서 나온 속기 표기법을 사용할 것이지만, 어떤 경우에는 형식적 표기법이 정확한 프로세스를 위하여 필요할 수도 있다.

만약 당신이 $vice라는 변수를 사용하는데 변수 바로 뒤에 "fly"라는 문장이 뒤따른다고 생각해보자. 속기 표기법을 사용할 경우의 다음 예제를 살펴보면....

 
Jack is a $vicefly

예제에 나온 $vicefly라는 변수는 우리가 희망한 변수가 아니다. 결과로 Velocity $vice 아닌 $vicefly 변수로 가정해서 처리하게 된다. 결국 화면에는 우리가 예상하지 못한 $vicefly 그대로 표시될 것이다.

아래 형식적 표기법을 통해 문제를 해결할 있다.

 
Jack is a ${vice}fly

이제 Velocity $vicefly 아닌 $vice 변수라는 것을 알게 된다. 기억하자. 형식적 표기법은 레퍼런스들이 템플릿 안에서 텍스트에 직접 붙어 있을 유용하게 사용된다.

숨겨진 레퍼런스 표기법 (Quiet Reference Notation)

Velocity 사전에 정의되지 않은 변수를 만나게 되면, 변수값을 그대로 화면에 출력하게 된다.

다음의 예제를 살펴보자.

 
<input type="text" name="email" value="$email" />

위에 나온 $email 사전에 정의되지 않았을 경우 화면에 나오는 텍스트필드의 초기값에는 $email이라는 값이 그대로 표시될 것이다. 이것은 우리가 원하는 결과가 아니다.

이제 다음처럼 예제를 바꿔보자.

 
<input type="text" name="email" value="$!email"/>

이제 화면에는 텍스트필드의 값이 공백이 출력될 것이다. 형식적 표기법을 사용한 다음 예제도 같은 결과를 가져온다.

 
<input type="text" name="email" value="$!{email}"/>

값이 설정되지 않은 변수를 화면에 출력하지 않을 경우 숨겨진 레퍼런스 표기법은 아주 유용하다.

Dollar($)표시의 경우는 어떻게 하는가?

만약 당신이 페이지 내에서 "나는 농부의 가게에서 $2.50 주고 4파운드의 감자를 샀습니다.!" 라는 문자열을 표시해야 한다고 가정하자.

VTL에서는 앞서 보았듯이 $ # 같은 특별한 캐릭터들을 사용하고 있어서 언뜻 보면 문자열이 제대로 표시가 안될 수도 있을 같다.

그러나 VTL 식별자는 항상 대문자나 소문자의 영문자로 시작하기 때문에 문장은 아무런 문제가 없다.

escape 캐릭터의 사용

만약 당신이 화면에 $email 출력해야 한다고 가정하자. 그러나 이미 $email 값이 설정된 상태라고 하자. 그러면 화면에는 당신이 원하지 않는 $email 대한 설정값이 화면에 표시될 것이다.

아래 예제가 있다.

 
#set ( $email = "foo" )
$email

경우 화면에는 foo라는 문자열이 출력되어 당신이 원하는 $email이라는 문자는 출력할 없게 된다.

이경우 다음과 같이 escape 캐릭터를 사용하면 된다.

 
#set( $email = "foo" )
$email
\$email
 
\\$email
\\\$email

결과는 아래와 같이 나올 것이다.

 
foo
$email
 
\foo
\$email

만약 $email 사전에 정의되지 않았다고 가정해보면 어떻게 될까? 결과는 아래와 같을 것이다.

 
$email
\$email
\\$email
\\\$email

 

 

Velocity 문법(지시어)

앞서 배운 레퍼런스(변수) 디자이너들이 페이지에 동적인 내용을 생성할 있도록 도와준다.
반면에 이번에 살펴볼 디렉티브(명령어) 디자이너들이 실제적으로 웹사이트의 뷰와 컨텐츠를 관리하도록 도와준다.

#set

명령어 #set 레퍼런스의 값을 설정할 사용된다. 값은 변수 레퍼런스나 속성 레퍼런스 모두에 할당될 있고, 이것은 아래에 보이는 것처럼 괄호 안에서 명명된다.

#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )

괄호안의 좌측에 위치하는 변수(이하 LHS 표기, 우측 변수는 RHS 표기) 아래에 나오는 레퍼런스 또는 속성 타입이어야 한다.

*       Variable reference

*       String literal

*       Property reference

*       Method reference

*       Number literal

*       ArrayList

아래는 위의 타입들에 예제이다.

#set( $monkey = $bill ) ## variable reference
#set( $monkey.Friend = "monica" ) ## string literal
#set( $monkey.Blame = $whitehouse.Leak ) ## property reference
 
#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference
#set( $monkey.Number = 123 ) ## number literal
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList

마지막 줄에서 대괄호로 표시된 element ArrayList class 요소를 정의한다. 그래서 예를 들면, 당신은 $monkey.Say.get(0) 이용해서 첫번째 배열요소(여기서는 "Not") 접근할 있다.

또한 간단한 수학적 표현도 가능하다.

#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )

null 체크

만약 RHS 속성 또는 값이 null 메소드 레퍼런스 라면, LHS 할당되지 않을 것이다. 문맥에서 현재의 레퍼런스를 매커니즘으로 제거하는 것은 불가능하다. 이런 점은 Velocity 초보자들이 흔히 혼동 하는 실수다.

예를 들면....

#set( $result = $query.criteria("name") )
The result of the first query is $result
 
#set( $result = $query.criteria("address") )
The result of the second query is $result

위에서 만약 $query.criteria("name") 문자열 "bill" return되고, $query.criteria("address") null return되면, VTL 결과는 아래와 같이 출력될 것이다.

The result of the first query is bill
 
The result of the second query is bill

이것은 property 또는 매소드 레퍼런스를 거쳐 #set 레퍼런스를 시도한 ,

1.    foreach 반복문을 만드는 초보자들을 혼동케하는 경향이 있다.

이때는 아래와 같이 null 의심가는 레퍼런스를 #if 명령어를 가지고 시험한다.

#set( $criteria = ["name", "address"] )
 
#foreach( $criterion in $criteria )
 
    #set( $result = $query.criteria($criterion) )
 
    #if( $result )
        Query was successful
    #end
 
#end

위의 예에서, query 성공하였는지 결정하는데 있어 $result 결과값에 의존하는 것은 현명한 결정이 아니다. $result 위에서 처럼 조건절 이전에 #set 통해 설정 되어진 후에는 $result null 다시 되돌릴 없다. (#if #foreach 명령어의 세부사항들이 문서의 뒤에 다루어질 것이다.)

이에대한 하나의 해결책은 $reult false 사전에 설정하는 방법이다. 그런 다음 $query.criteria( ) 호출이 실패하면, 당신은 $result null임을 체크할 있게 된다.

#set( $criteria = ["name", "address"] )
 
#foreach( $criterion in $criteria )
 
    #set( $result = false )
    #set( $result = $query.criteria($criterion) )
 
    #if( $result )
        Query was successful
    #end
 
#end

몇몇의 다른 Velocity 명령어들과 다르게, #set 디렉티브는 #end 문을 가지지 않는다는 점도 참고하라.

문자열 (String literals)

명령어 #set 사용할 따옴표로 지정된 문자열은 아래 예제처럼 파싱되어 출력된다.

#set( $directoryRoot = "www" )
#set( $templateName = "index.vm" )
#set( $template = "$directoryRoot/$templateName" )
$template

당연하겠지만, 결과는 아래와 같다.

www/index.vm

그러나 문자열이 작은 따옴표일 때는 파싱되지 않는다.

#set( $foo = "bar" )
$foo
#set( $blargh = '$foo' )
$blargh

결과는 아래와 같다.

bar
$foo

Velocity에서 파싱되지 않은 텍스트를 출력하기 위해 위에서 처럼 작은 따옴표를 사용할 있다.
설정은 velocity.properties 설정파일에서 stringliterals.interpolate=false 설정함에 따라 기본설정을 바꿀 수도 있다.

조건절 (If / ElseIf / Else)

Velocity에서 #if 명령어는 문장이 참인 조건에서 웹페이지가 생성될 포함될 문자열을 지정할 있다.

#if( $foo )
   Velocity!
#end

위에서 #if 명령어는 변수 $foo 참인지 결정하기 위해 사용되며 아래 2가지 상황일 있다.

*       $foo 참인 값을 갖는 boolean(true/false)이다.

*       $foo null 아니다.

Velocity 문맥은 항상 객체(Object)로써 유지된다는 것을 기억하라. 그래서 우리가 boolean이라고 말할 , 그것은 Boolean(class)으로 표현될 것이다.

예제에서 #if #end 사이에 들어있는 content 참이면 결과가 나올 것이다. 여기서는 $foo 참이면, "Velocity!" 출력될 것이고, 반대로, $foo null값이거나 false이면 아무런 내용도 표시되지 않을 것이다.

명령어 #elseif 또는 #else #if 요소와 함께 사용될 있다. 다음의 예제에서, $foo 15 값를 갖고 $bar 6 값을 갖는다고 가정해보자.

#if( $foo > 10 )
    Go North
#elseif( $foo == 10 )
    Go East
#elseif( $bar == 6 )
    Go South
#else
    Go West
#end

예제에서 $foo 10보다 크면 첫번째 비교들이 실패하게 된다. 다음 $bar 6 비교되어 참이 되고, 그래서 결과는 "Go South" 된다.

참고 : '==' 비교되는 변수는 같은 Object 타입이어야 한다. 그렇지 않으면 결과는 항상 false 것이다.

논리 연산

Velocity 논리 연산자 AND, OR, NOT 지원한다. 아래 예제가 나온다.

## logical AND
 
#if( $foo && $bar )
   This AND that
#end

위에서 #if() 명령은 단지 $foo $bar 참인지만 평가할 것이다. 만약 $foo false라면, 결과는 false 되며 $bar 평가되지 않을 것이다. 만약 $foo 참이라면, Velocity $bar 값을 체크하게 된다. 만약 $bar 참이면, 결과는 true 되고 화면에는 "This And that" 나타날 것이다. $bar false라면, 그때 결과는 false이므로 결과는 없을 것입니다.

논리 연산자 OR 같은 방법으로 작동한다. 아래 예제가 나온다.

## logical OR
 
#if( $foo || $bar )
    This OR that
#end

OR 연산에 대해 별도의 설명은 하지 않는다. 아래는 부정연산의 예제다.

##logical NOT
 
#if( !$foo )
  NOT that
#end

여기서, $foo 참이라면, !$foo false 평가하고, 아무런 출력이 없게된다. 만약에 $foo false라면, !$foo 참으로 평가되어 화면에서 "NOT that" 출력될 것이다.

주의 : 이것을 완전하게 앞서 배운 숨긴(quiet) 레퍼런스와 혼동하지 않도록 조심하라. 숨긴 레퍼런스의 형식은 $!foo 이다.

반복문 (Loops)

명령어 #foreach 반복문을 사용할 필요하다.

<ul>
#foreach( $product in $allProducts )
    <li>$product</li>
#end
</ul>

예제에서 #foreach loop $allProducts 컬렉션(object) List 안의 전체 product 대해 반복문을 수행하도록 한다. loop 통해서 $allProducts 내에 담긴 Object $product 변수로써 레퍼런스하게 된다.

위에 나온 $allProducts 변수에 사용되는 타입은 아래와 같다.

*       Vector

*       Hashtable

*       Array

이제 $allProduct Hashtable이라고 가정하자.
만약 당신이 Hashtable 담긴 키값을 검색해야 한다면, 아래와 같은 코드를 사용하면 된다.

 
<ul>
#foreach( $key in $allProducts.keySet() )
    <li>Key : $key -> value : $allProducts.get($key)</li>
#end
</ul>

또한 Velocity 당신이 반복문의 횟수(loop counter) 얻을 있는 간단한 방법을 제공한다.

<table>
#foreach( $customer in $customerList )
    <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>

velocity.properties 파일에 명시되어있는, loop counter 변수 레퍼런스를 위한 기본값은 $velocityCount이다. 기본값에 따라 카운터가 1에서 시작하지만, 이것은 velocity.properties 파일안에서 0 이나 1 모두로 설정할 있다. 아래는 velocity.properties 파일에 지정된 관련 설정 내용이다.

# Default name of the loop counter
# variable reference.
directive.foreach.counter.name = velocityCount
 
# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1

인클루드 (Include)

명령어 #include 템플릿에 local 파일을 끼워넣을 있도록 해준다. local file #include 명령이 정의된 위치에 정확히 삽입된다.

아래는 #include 참고할 사항이다.

*       파일의 내용은 템플릿 엔진을 통해 파싱되지 않는다.

*       안전상의 이유로, 파일은 오직 TEMPLATE ROOT 아래에만 위치해야 한다.

#include( "one.txt" )

위에서 처럼 #include 명령이 요청한 파일은 따옴표로 지정된다. 만약 하나 이상의 파일이 포함된다면, 콤마(,) 구분되어야 한다.

#include( "one.gif", "two.txt", "three.htm" )

포함되는 파일은 파일 이름 대신에 변수를 사용할 수도 있다. 아래 파일이름과 변수 모두를 지정하는 에제가 나온다.

#include( "greetings.txt", $seasonalstock )

파싱 (Parse)

명령어 #parse 템플릿 디자이너가 VTL 지정되어 있는 동적인 템플릿을 포함하는 local file 끼워넣도록 해준다. Velocity 파일에 명명된 VTL 분석하고 평가된 결과를 #parse 명령이 정의된 위치에 정확히 삽입한다.

아래는 #parse 참고할 사항이다.

*       파일의 내용은 템플릿 엔진을 통해 파싱된다.

*       안전상의 이유로, 파일은 오직 TEMPLATE ROOT 아래에만 위치해야 한다.

#parse( "me.vm" )

앞서 나온 #include 명령처럼, #parse 역시 변수를 취할 있다. 주의해야 것은 #include 명령과 다르게, #parse 단지 하나의 파일만을 취할 있다는 점이다.

Velocity 또한 #parse 문장을 포함하고 있는 템플릿을 #parse 인자로 가질 있다.
파싱되는 파일의 제한을 위한 최적의 기본값은 10이며 velocity.properties 파일내에 directive.maxdepth=10 이라는 설정을 통해 이를 제어할 있다.

아래 예제를 보자.
1) default.vm

Count down.
#set( $count = 8 )
#parse( "parsefoo.vm" )
All done with dofoo.vm!

2) parsefoo.vm

#set( $count = $count - 1 )
#if( $count > 0 )
    #parse( "parsefoo.vm" )
#else
    All done with parsefoo.vm!
#end

예제에 따라 default.vm에서 $count 8부터 count down하면서 parsefoo.vm 파싱하게 된다.

그리고 count 0 도달할 , Velocity "All done with parsefoo.vm!" 이라는 메세지를 표시하고, 시점에서, 제어권은 default.vm으로 돌아가 "All done with dofoo.vm!" 이라는 메시지를 출력할 것이다.

중지 (Stop)

명령어 #stop 템플릿 엔진의 실행과 return 강제로 멈추도록 하는데 사용한다.
보통 디버깅(debugging) 목적으로 사용된다.

#stop

다음으로 Velocity 나머지 특징과 기타 살펴볼 내용들에 대해 설명을 계속한다.

수학적인 기능 (Math)

Velocity #set 명령어를 가지고 템플릿들에서 사용될 있는 수학적인 기능들을 제공한다. 다음의 식들은 각각 덧셈, 뺄셈, 곱샘 그리고 나눗셈에 대한 예제이다.

#set( $foo = $bar + 3 )
#set( $foo = $bar - 4 )
#set( $foo = $bar * 6 )
#set( $foo = $bar / 2 )
 
#set( $foo = $bar % 5 )

수학적인 기능은 오직 정수만 (.... -2, -1, 0, 1, 2 ....) 가능하다는 점에 주의하라.

범위 연산 (Range Operator)

범위 연산은 #set #foreach 구문 사이에서 이용될 있다. 범위연산자는 다음의 구조를 가진다.

[n..m]

예제에서 n m 모두 정수여야 한다. m 큰지 n 작은지는 문제가 되지 않는다. n m사이에서 반복문이 순환될 것이기 때문이다.

다음은 범위연산의 사용 예제를 보여주고 있다.

First example:
#foreach( $foo in [1..5] )
$foo
#end
 
Second example:
#foreach( $bar in [2..-2] )
$bar
#end
 
Third example:
#set( $arr = [0..1] )
#foreach( $i in $arr )
$i
#end
 
Fourth example:
[1..3]

결과는 아래와 같다.

First example:
1 2 3 4 5
 
Second example:
2 1 0 -1 -2
 
Third example:
0 1
 
Fourth example:
[1..3]

 

 

Velocity 문법(매크로)

매크로

명령어 #macro VTL 템플릿에서 반복되는 문장을 정의하는데 사용된다.

매크로는 간단하고 복잡한 시나리오 모두에서 매우 유용하게 쓰인다. 매크로는 keystrokes 저장하고 typographic error 최소화할 목적으로 만들어졌다.

#macro( d )
<tr><td></td></tr>
#end

예제에서 정의되는 Velocimacro d 이다. 매크로는 아래와 같은 방법으로 호출된다.

#d()

템플릿이 불려질 , Velocity 아래와 같은 결과로 #d() 대체하게 된다.

<tr><td></td></tr>

또한 Velocimacro 인자의 수를 취할 수도 있다. 심지어 앞선 예제에서 보여진 zero argument 조차 하나의 옵션이다.

그러나 Velocimacro 불려질 , 그것은 정의된 수만큼의 argument 함께 불려야 합니다. 많은 Velocimacros 위에서 정의된 하나보다 많이 관련됩니다. 여기 색과 array, 개의 argument 취한Velocimacro 있습니다.

#macro( tablerows $color $somelist )
        #foreach( $something in $somelist )
               <tr><td bgcolor=$color>$something</td></tr>
        #end
#end

예제에서 정의되는 매크로, #tablerow 개의 argument 취한다. 첫번째 argument $color 대체하고 두번째 argument $somelist 대체하게 된다.

VTL 템플릿 안으로 넣어질 있는 것은 모두 매크로 안으로 지정될 있다. 위에서 #tablerows 매크로는 foreach 명령어를 사용했다. #tablerows 매크로 정의를 보면 두개의 #end 명령이 있다. 예상하겠지만 첫번째는 #foreach 속하고, 두번째는 매크로 정의를 마치는데 사용되는 것이다.

아래에 위에서 정의한 #tablerow 매크로를 사용하는 예제가 나온다.

#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )
#set( $color = "blue" )
<table>
    #tablerows( $color $greatlakes )
</table>

변수 $greatlakes $somelist 대체함에 유의하면서 아래 결과를 살펴보자.

<table>
        <tr><td bgcolor="blue">Superior</td></tr>
        <tr><td bgcolor="blue">Michigan</td></tr>
        <tr><td bgcolor="blue">Huron</td></tr>
        <tr><td bgcolor="blue">Erie</td></tr>
        <tr><td bgcolor="blue">Ontario</td></tr>
</table>

매크로는 하나의 Velocity 템플릿 안에서 inline으로 정의될 있으나 이렇게 정의한 매크로는 다른 템플릿에서는 사용할 없다. 매크로가 모든 템플릿들에 공유될 있도록 정의하기 위해서 velocity.properties 설정파일 내에 template library (velocimacro.library) 지정하도록 한다.

공유되는 매크로의 이점은 많은 템플릿 들에서 매크로를 재정의할 필요를 줄여 작업량을 줄이고, 오류가 발생할 있는 기회를 줄인다는 점이다.

매크로 인자 (Arguments)

매크로에 정의되는 argument 다음의 VTL 요소들을 모두 취할 있다.

Reference : anything that starts with '$' 
 
String literal : something like "$foo" or 'hello' 
 
Number literal : 1, 2 etc 
 
IntegerRange : [ 1..2] or [$foo .. $bar] 
 
ObjectArray : [ "a", "b", "c"] 
 
boolean value true 
 
boolean value false 

velocity.properties에서의 매크로 관련 설정

*       velocimacro.library - 콤마(,) 구분된 모든 템플릿 라이브러리 목록. VM_global_library.vm.설정된 template path Velocimacro library 찾는데 사용됩니다.

*       velocimacro.permissions.allow.inline - true(기본값)/false. 속성은 매크로가 표준 템플릿 내에서 inline으로 정의될 있는지를 결정한다.

*       velocimacro.permissions.allow.inline.to.replace.global - true/false(기본값). 만약 템플릿 내에서 inline으로 정의된 매크로가 velocimacro.library 설정된 라이브러리의 매크로를 대체할 지를 설정한다. 만약 false라면 템플릿에 inline으로 정의된 매크로가 컨테이너 구동시 로드된 라이브러리의 매크로를 교체하는 것을 막는다.

*       velocimacro.permissions.allow.inline.local.scope - true/false(기본값). 속성은 inline으로 정의된 매크로가 정의하는 template 대해 'visible'인지 아닌지를 조절한다. 속성을 true 하면, 템플릿은 단지 정의되는 템플릿에 한해서만 유용한 inline VM 정의할 있게 된다.

*       velocimacro.context.localscope - true/false(기본값). true라면 매크로를 통한 #set() 명령으로 문맥의 모든 modification 매크로에 대해 'local' 고려되며 영구적으로 영향을 끼치지 않게 된다.

*       velocimacro.library.autoreload - true/false(기본값). 속성은 자동 로드되는 매크로를 조절한다. true 설정되면 요청된 매크로에 대한 원본 매크로 설정파일의 변화를 체크하여 필요시 해당 매크로를 리로드한다. 이것은 컨테이너 재기동 없이 매크로 라이브러리를 바꾸고 테스트 하도록 해준다. 모드는 오직 caching resource 안에서 off일때만 작동한다. ( : file.resource.loader.cache = false). 속성은 운영단계가 아닌 개발단계에서만 사용하도록 권장한다.

매크로의 인자로서 다른 매크로나 디렉티브(명령어) 이용할 있나?

다음 처럼 말이다.

#center( #bold("hello") ) 

그럴 없다. 명령은 타당하지 않다.

그러나 당신은 아래 예제처럼 문제를 우회하여 해결할 있다.

#set($stuff = "#bold('hello')" )
#center( $stuff )
#center( "#bold( 'hello' )" )

결과는 동일하다.

다른 예제를 살펴보자.

#macro( inner $foo )
  inner : $foo
#end
 
#macro( outer $foo )
   #set($bar = "outerlala")
   outer : $foo
#end
 
#set($bar = 'calltimelala')
#outer( "#inner($bar)" )

결과는 아래와 같다.

outer : inner : outerlala

어떻게 문자열을 연결해야 하나?

당신은 단순히 연결해야 문자열들을 같이 놓으면 된다. 아래 예제를 통해 살펴보라.

#set( $size = "Big" )
#set( $name = "Ben" )
 
The clock is $size$name.
#set( $size = "Big" )
#set( $name = "Ben" )
 
#set($clock = "$size$name" )
 
The clock is $clock.
#set( $size = "Big" )
#set( $name = "Ben" )
 
#set($clock = "${size}$name" )
 
The clock is $clock.

결과는 모두 동일하게 "The clock is BigBen' 된다.

 

프레임워크 내장 객체의 사용

TDF2에서 지원하는 Velocity 템플릿에서 사용가능한 내장 객체 레퍼런스를 소개한다.

*      $actionInstanceVariable

*      $req - 현재 HttpServletRequest

*      $res - 현재 HttpServletResponse

*      $stack - 현재 OgnlValueStack

*      $ognl - OgnlTool

*      $webwork - WebWorkUtil 인스탄스

*      $action - 현재 WebWork action

*      $taglib (또는 이와 유사한 ) - Velocity 매크로를 통한 JSP tag 라이브러리에 접근 가능

$actionInstanceVariable

당신이 만든 Action 클래스의 멤버변수들에 대해 $actionInstanceVariableName 으로써 Velocity 템플릿이 접근할 있도록 해준다.

만약 당신의 Action 클래스에서 아래와 같은 멤버변수를 가진다고 하자.

public class ProcessEditTableRowAction extends ActionSupport {
 
        private String fooString;
        ....
 
        public String getFooString() { 
               return fooString; 
        }
        ....

경우, Velocity 템플릿에서 아래와 같은 레퍼런스를 통해 멤버변수의 값을 꺼낼 있다.

$fooString

$req

당신이 사용하는 서블릿 환경(Tomcat, Resin, etc....)에서 생성되어 관리되는 현재의 HttpServletRequest 인스탄스

$res

당신이 사용하는 서블릿 환경(Tomcat, Resin, etc....)에서 생성되어 관리되는 현재의 HttpServletResponse 인스탄스

$stack

com.opensymphony.xwork.util.OgnlValueStack 인스탄스

$ognl

com.opensymphony.webwork.views.jsp.ui.OgnlTool 인스탄스

Jason/Patrick 의하면, OgnlTool static 클래스 멤버에 접근할 있는 아주 멋진 Tool이다. Velocity에서는 Context 설정되지 않은 클래스 변수나 메소드에 접근하는 기능을 제공하지 않는다. 그래서 당신은 템플릿 내에서 다음과 같은 메소드를 호출할 없다.

$java.lang.Math.random()

그러나 $ognl 이용하면 아래와 같은 구문이 가능해진다.

$ognl.findValue("@java.lang.Math@random()")

$webwork

com.opensymphony.webwork.util.WebWorkUtil 인스탄스

Mathew 따르면 $webwork 다른 객체를 인스탄스화(초기화) 있는 기능을 제공한다. Velocity에서는 Context 설정되지 않은 객체를 초기화하는 방법을 제공하지 않기 때문에 기능은 매우 유용하다.

객체를 초기화하기 위해 당신은 템플릿 내에서 다음과 같은 문장을 사용할 있다.

#set($object = $webwork.bean("com.foo.ClassName"))

$action

현재 템플릿을 호출한 Action 컨텍스트의 인스탄스

$taglib

TDF2에서는 디자이너와의 혼선을 피하기 위해 taglib 사용을 권장하지 않는다. 대부분의 지원 태그가 (form) 관련된 내용이고, 이것의 사용으로 많은 이점을 제공한다고 보기 어렵기 때문에 TDF2에서는 가급적 익숙한 HTML 표준 태그를 이용하기를 권장한다.

$taglib 대한 자세한 정보를 알고 싶다면 http://wiki.opensymphony.com/display/WW/UI+Tags?showChildren=true#children 방문하라.

 

아파치 벨로시티를 사용한 템플릿 기반의 자동 코드 생성 - 1

05/05/2004

상업적으로나 오픈소스로나 여러가지 형태로 제공되는 코드 생성기는 템플릿과 템플릿 엔진을 사용하고 있다. 기사에서 필자는 템플릿 기반의 코드 생성과 템플릿과 변환 방법, 그리고 그런 것들을 사용함으로써 얻게 막대한 이득에 대해 설명해보고자 한다. 그리고 벨로시티를 사용한 간단한 자바 코드 생성기를 만들어 것이다. 코드 생성기는 클래스를 XML 표현한 XML 파일을 입력으로 받아들여 XML 명시하고 있는 자바 코드를 생성하는 기능을 가지게 것이다. 생성과정은 결과물 코드로 뽑아낼 언어의 문법(신택스) 내부에 포함하고 있는 각각의 템플릿들에 의해 결정된다. 그리고 또한 다른 코드를 생성해내기 위하여 템플릿을 어떻게 사용하는지도 주목해서 보라.

템플릿과 변환

템플릿을 기반으로 변환을 소프트웨어 개발에 있어 엄청나게 광범위하게 사용된다. 많은 툴들이 문서의 포맷을 변환시키기 위하여 사용하기도 한다. XML 파일을 다른 특정 포맷으로 변환시키기 위하여 XSL 템플릿을 기반으로 하여 XSLT 사용하는 것이 예라고 있다. 그림1 템플릿 변환 과정에 있어 관계있는 4개의 컴포넌트를 보여주고 있다. 그것들은 다음과 같다:

데이터 모델: 특정한 구조를 이루며 데이터를 포함하고 있다. 데이터는 변환되어야 것들이며 변환 과정 중에 이용된다.
템플릿: 데이터 모델을 특정한 결과 코드로 포맷팅한다. 물론 그것을 위해서 템플릿은 내부에 데이터 모델의 레퍼런스를 가지고 사용하게 된다.
템플릿 엔진: 변환 과정을 직접 수행하는 어플리케이션이다. 입력으로 데이터 모델과 템플릿을 받아들여 템플릿에 적힌 데이터 모델의 레퍼런스를 실제 데이터 모델의 값으로 치환하여 템플릿을 통한 변환 과정을 수행한다.
결과물: 변환 과정을 거친 나오는 결과물

그림 1.템플릿 기반 변환

다음의 데이터 모델의 예를 한번 보자.:

#person.txt
 
$name=
길동
$surname=


길동씨의 이름과 성을 포함하고 있는 텍스트 파일이다. 우리는 다음과 같은 형태의 템플릿을 통해 이것을 변환시키고 싶어졌다.:

#person.template


안녕하시오. $surname 가고 이름은 $name 이오. 템플릿또한 텍스트 파일이다. 두개의 데이터 모델에 대한 레퍼런스를 포함하고 있는데 $name $surname이란 레퍼런스가 그것이다.

만약 템플릿 엔진 어플리케이션 이름이 transform이라면 다음과 같이 데이터 모델과 위의 템플릿을 넘겨주어 다음과 같이 변환을 수행할 수가 있다.:

> transform person.txt person.template
결과물은:

 

안녕하시오. 가고 이름은 길동 이오. 템플릿 엔진은 데이터 모델로부터 얻어낸홍길동이라는 값을 $name $surname 레이블을 치환하였다.

한마디: 템플릿 기반의 변환에서 가장 중요한 점은 어떠한 결과물을 뽑아내는 프로그램 자체를 건드리지 않고도 결과물의 포맷을 맘대로 바꿀 있다는 점이다. 결과물을 바꾸고 싶으면 단지 해야 일은 템플릿을 조금 수정하는 뿐이다. 여기 다음의 템플릿을 한번 보라.:

#person2.template
 
***********************
이름 = $name
 = $surname
***********************


여기서는 위에서 사용했던 같은 데이터 모델과 새로운 템플릿 사용하여 변환 과정을 수행해 보겠다.:

> transform person.txt person2.template


결과로는:

***********************
이름 = 길동
 =
***********************


위에서 보았던 것과 같이 단지 템플릿만 수정함으로 결과를 조작할 수가 있다.

템플릿 기반 코드 생성

코드 생성과정또한 분명하게 위에서와 같은 변환 과정이다. 데이터 모델은 뽑아낼 코드의 중심이 되는 엔티티의 정보를 담고 있는 것이라고 수가 있고 템플릿을 뽑아낼 결과물 코드의 언어 문법을 표현한다고 수가 있다.

또다른 작은 예로는 언어 독립적인 코드 생성을 보여준다. 여기 예를 보라.:

#student.txt
 
$name=Student
$base=Person


파일은 클래스 이름과 클래스의 베이스 클래스(부모 클래스) 명시하고 있다. 이것을 기반으로 자바 코드 Student 클래스를 뽑고 싶으면 다음과 같은 템플릿을 사용하면 된다.:

#javaclass.template
 
public class $name extends $base {
}


위의 데이터 모델과 템플릿을 입력받은 템플릿 엔진은 다음과 같은 변환 결과를 출력할 것이다.:

public class Student extends Person {
}


Student
클래스의 정의 코드다. 우리는 데이터 모델과 템플릿으로부터 코드 생성을 시작할 수가 있다.

인터페이스를 만들려면 템플릿을 조금만 바꾸면 된다.:

#javainterface.template
 
public interface $name implements $base {
}


위의 템플릿을 템플릿 엔진에다 넣으면 다음과 같은 결과가 출력된다.

public interface Student implements Person {
}


엔진은 Student 클래스가 아닌 인터페이스로도 뽑게 준다. 여기에서의 장점은 데이터 모델이나 템플릿 엔진 둘다 건드릴 필요 없이 작업을 했다는 것이다.

그리고 언어 독립성을 보여주기 위해 C++코드를 만들 있게 템플릿을 작성해 보자.:

#cpp.template
 
class $name : public $base
{
}


결과물은:

class Student : public Person
{
}


C++
에서의 Student클래스 정의가 나왔다. 물론 데이터 모델이나 엔진을 고치지 않았다. 우리는 같은 것을 기반으로 템플릿만 바꿔서 다른 언어의 코드를 만들어 것이다! 이건 주목할만한 것인데 디자인되고 템플릿을 기반으로 하는 코드 생성기는 단지 템플릿만 바꿔도 다른 언어의 코드를 생성할 있도록 준다. 그래서 우리는 언어에 종속적이지 않고 디자인된 객체 모델을 만들어야 하는 것이다.

아파치 벨로시티

이전 예제에서 $ 시작되는 문자열을 데이터 모델로 치환시켜주는 가상의 간단한 템플릿 엔진을 가정하고 설명을 해왔다. 이제 진짜 코드를 생성하기 위해서 진짜 템플릿 엔진을 사용해 보도록 하자.

아파치 벨로시티 템플릿 엔진은 자카르타 오픈 소스 툴이다. VTL(벨로시티 템플릿 랭귀지) 라고 불리는 간단한 템플릿 언어를 기반으로 동작한다. 벨로시티는 자바를 기반으로 동작하도록 제작되었으며 벨로시티 컨텍스트에 연결된 일반 자바 클래스를 데이터 모델로써 사용한다. 변환 과정은 템플릿과 컨텍스트를 입력으로 받아 템플릿에 명시된 포맷대로의 결과물을 내는 것으로 이루어진다. 변환 과정 중에 템플릿의 레이블들은 컨텍스트에 포함된 실제 데이터로 치환된다.

나는 샘플 코드를 J2SE 1.4.2 벨로시티 1.4 기반으로 작성했고 테스트도 보았다. 이를 사용하기 위해서는 클래스패스에 개의 jar 파일 - velocity-1.4-rc1.jar and velocity-dep-1.4-rc1.jar. – 포함해야 한다.

실전에서의 벨로시티

다음 예제는 벨로시티를 사용한 간단한 코드 생성기인데 멤버 변수와 접근자 메소드(get/set 메소드) 포함한 간단한 자바 클래스를 생성하는 기능을 갖고 있다. 데이터 모델은 클래스들의 이름과 클래스들의 애트리뷰트 이름을 명시하고 있는 XML 파일로써 제공된다 여기 입력 데이터 모델 파일을 한번 보라.:

<?xml version="1.0" encoding="UTF-8"?>
<!-- order.xml --!>
<Content>  
       
  <Class name="Customer">
    <Attribute name="code" type="int"/>
    <Attribute name="description" type="String"/>
  </Class>
   
  <Class name="Order">
    <Attribute name="number" type="int"/>
    <Attribute name="date" type="Date"/>        
    <Attribute name="customer" type="Customer"/>        
  </Class>    
 
</Content>

 

XML 파일 구조는 말할 것도 없이 쉽다. 엘레먼트는 클래스들 의미하며 요소는 클래스의 데이터 멤버를 의미한다. 예제는 Customer 클래스와 Order 클래스를 명시하고 있다. 코드 생성기는 문서를 읽어들여 Customer클래스와 Order클래스를 생성해낼 것이다.

다음으로 생성기를 구현해 보자. 첫번째 일은 XML데이터 구조를 표현하기 위한 내부 구조를 만드는 것이다. 그러기 위해 두개의 자바 클래스를 만들 것인데 위의 요소를 표현하기 위한 것이다. 표현하기 위한 디스크립터 클래스는 다음과 같다.:

// ClassDescriptor.java
package com.codegenerator.example1;
 
import java.util.*;
 
public class ClassDescriptor {
  private String name;
  private ArrayList attributes = new ArrayList();
  public void setName(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
  public void addAttribute(AttributeDescriptor attribute) {
    attributes.add(attribute);
  }
  public ArrayList getAttributes() {
    return attributes;
  }
}


ClassDescriptor
클래스는 요소에 명시된 데이터를 담기 위해 사용된다. Name 애트리뷰트는 클래스 이름을 담기 위해 사용하고 attributes 여러 개의 AttributeDescriptor 담기 위하여 사용되는데 AttributeDescriptor클래스는 ClassDescriptor 마찬가지로 요소의 내용을 담기 위해 사용되는 클래스이다. 다음을 보라:

// AttributeDescriptor.java
 
package com.codegenerator.example1;
 
import java.util.*;
public class AttributeDescriptor {
  private String name;
  private String type;
  public void setName(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
  public void setType(String type) {
    this.type = type;
  }
  public String getType() {
    return this.type;
  }
}

XML파일을 디스크립터 클래스들에 담기 위해 SAX파서를 사용하는데 다음과 같이 한다.:

package com.codegenerator.example1;
 
import java.util.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
 
public class ClassDescriptorImporter extends DefaultHandler {
 
  private ArrayList classes = new ArrayList();
 
  public ArrayList getClasses() {
    return classes;
  }
 
  public void startElement(String uri, String name,
    String qName, Attributes attr) throws SAXException {
 
    // Imports <Class>  
    if (name.equals("Class")) {
      ClassDescriptor cl = new ClassDescriptor();
      cl.setName(attr.getValue("name"));
      classes.add(cl);
    }
 
    // Imports <Attribute>
    else if (name.equals("Attribute")) {
      AttributeDescriptor at = new AttributeDescriptor();
      at.setName(attr.getValue("name"));
      at.setType(attr.getValue("type"));
      ClassDescriptor parent = 
        (ClassDescriptor) classes.get(classes.size()-1);
      parent.addAttribute(at);
 
    }
 
    else if (name.equals("Content")) {
    }
 
    else throw new SAXException("Element " + name + " not valid");
  }  
}

 

ClassDescriptorImport 클래스가 하는 일은 SAX 기본 핸들러를 익스텐즈하여 XML로부터 디스크립터 클래스로 데이터를 변환하는 것이다. 위에서 있듯이, 요소가 한번씩 처리될 때마다 ClassDescriptor 클래스의 새로운 인스턴스를 만들어내고 핸들러의 ArrayList 삽입한다. 또한 파서는 요소를 처리할 때마다 새로운 ClassAttribute클래스를 생성해내고 부모 ClassDescriptor 인스턴스에 그것을 삽입한다. 파싱 작업의 마지막에 classes변수는 XML문서에 명시된 모든 클래스들의 디스크립터 클래스를 가지게 된다.getClasses 메소드는 ArrayList 반환한다.

시점에서 벨로시티가 등장한다. 자바 클래스와 get/set메소드를 만들어내기 위해 작성된 VTL템플릿은 다음과 같다.:

## class.vm
 
import java.util.*;
 
public class $class.Name {
 
#foreach($att in $class.Attributes)  
  // $att.Name
  private $att.Type $att.Name;
  public $att.Type get$utility.firstToUpperCase($att.Name)() {
    return this.$att.Name;
  }    
  public void set$utility.firstToUpperCase($att.Name)($att.Type $att.Name) {
    this.$att.Name = $att.Name;
  }
       
#end
}


$class
라는 레이블은 ClassDescriptor 인스턴스를 가리킨다. 따라서 $class.Name 결국 ClassDescriptor.getName 호출함으로 얻어내는 결과를 출력하는 것이다. ( 실제로 $class.Name $class.getName() 축약형인데 모든 get 으로 시작하는 메소드에 대하여 이런 축약형이 적용된다.). 해당 ClassDescriptor 속한 AttributeDescriptor들의 리스트를 참조하기 위해서는 $class.Attributes 라는 레이블을 사용하면 된다. #foreach 구문은 List $class.Attributes 포함된 모든 항목에 대해 루프를 실행한다. 루프 안쪽의 구문은 $att.Name $att.Type 따른 데이터 멤버와 get/set 메소를 정의하고 있다.

$utility.firstToUpperCase 레이블은 사용자가 정의한 유틸리티 클래스를 호출하게 하는데 인자로 받은 문자열의 글자를 대문자로 바꿔주는 기능을 가지고 있따. 메소드는 매우 유용한데 예를 들면 number라는 데이터 멤버로부터 getNumber라는 메소드명을 얻어 사용하면 된다.

코드 생성기

이제 남은건 메인 어플리케이션이다. 그것은 XML파일을 읽어서 디스크립터 클래스에 값을 집어넣고 벨로시티를 호출해 템플릿을 통한 변환 작업을 수행하게 된다.

기사에서 ClassGenerator라는 전체 어플리케이션의 소스를 얻어낼 수가 있다. 가장 중요한 메소드는 start() 메소드다. 여기에 구현체가 있으니 한번 보라.:

public static void start(String modelFile, String templateFile)
  throws Exception {
 
  // Imports XML
  FileInputStream input = new FileInputStream(modelFile);
  xmlReader.parse(new InputSource(input));
  input.close();
  classes = cdImporter.getClasses(); // ClassDescriptor Array
 
  // Generates Java classes source code
  // by using Apache Velocity
  GeneratorUtility utility = new GeneratorUtility();
  for (int i = 0; i < classes.size(); i++) {
 
    VelocityContext context = new VelocityContext();
    ClassDescriptor cl = (ClassDescriptor) classes.get(i);
    context.put("class", cl);
    context.put("utility", utility);
 
    Template template = Velocity.getTemplate(templateFile);
 
    BufferedWriter writer =
      new BufferedWriter(new FileWriter(cl.getName()+".java"));
 
    template.merge(context, writer);
    writer.flush();
    writer.close();
 
    System.out.println("Class " + cl.getName() + " generated!");
  }
}


메소드는 입력으로 XML 템플릿 파일명을 받는다. 메소드 내에서는 이전에 설명된 ClassDescriptorImporter 클래스의 cdImporter 인스턴스와 관계지어진 xmlReader 사용하여 데이터를 읽어들이게 된다. 당신이 있듯이 getClasses메소드를 통하여 클래스로 뽑아내어질 클래스들의 디스크립터 클래스들을 얻어낼 수가 있다. 루핑 코드 안에서 생성되어지는 context객체는 특히 중요한데 왜냐하면 그것은 디스크립터 클래스 인스턴스와 템플릿간의 연결을 제공하기 때문이다. 사실 Context.put 메소드는 자바 객체를 템플릿 레이블과 매핑을 시키게 된다. 다음과 같은 구문을 실행하는 것이 그런 매핑을 수행한다.:

context.put("class", cl);
context.put("utility", utility);


클래스 디스크립터의 인스턴스인 cl 객체는 템플릿에서 $class 레이블로 접근할 수가 있고 유틸리티 클래스는 $utility 레이블을 이용해서 접근할 수가 있다. 마지막의 유틸리티 클래스는 GeneratorUtility 클래스의 인스턴스로 filrstInUpperCase() 메소드를 사용하기 위하여 컨텍스트에 삽입한다.

컨텍스트에 템플릿에서 처리할 데이터를 put 다음에는 start() 메소드에서 제공받은 대로 특정 템플릿 파일에 대한 Template 객체를 생성하고 merge 메소드를 호출한다. 그러면 템플릿 기반의 변환 작업이 수행된다. 컨텍스트의 데이터는 템플릿에 의해 처리되고 결과는 결과 witer 인스턴스의 스트림에 쓰여지게 된다.

아래 예제에서 코드생성기를 데이터 모델로 ordedr.xml , 템플릿으로 class.vm 입력으로 사용하여 돌려보면 Customer.java 파일을 얻게 것이다. 실제 구현 코드를 한번 보자:

import java.util.*;
 
public class Customer {
 
  // code
  private int code;
  public int getCode() {
    return this.code;
  }    
  public void setCode(int code) {
    this.code = code;
  }
       
  // description
  private String description;
  public String getDescription() {
    return this.description;
  }    
  public void setDescription(String description) {
    this.description = description;
  }
 
}

 

import java.util.*;
 
public class Order {
 
  // number
  private int number;
  public int getNumber() {
    return this.number;
  }    
  public void setNumber(int number) {
    this.number = number;
  }
       
  // date
  private Date date;
  public Date getDate() {
    return this.date;
  }    
  public void setDate(Date date) {
    this.date = date;
  }
 
  // customer
  private Customer customer;
  public Customer getCustomer() {
    return this.customer;
  }    
  public void setCustomer(Customer customer) {
    this.customer = customer;
  }
}

 

결론

템플릿 기반의 코드 생성기를 개발하면 가지 경우에 그것을 사용할 수가 있다.:

1.    다른 클래스의 생성을 위해 데이터 모델을 변경할 .

2.    다른 프로그래밍 언어에 맞는 템플릿을 제공하여 다른 언어의 코드를 뽑아내고 싶을 .

두가지 사용예는 코드 생성기 자체를 건드리지 않고 수행할 있다. 따라서 템플릿 기반의 코드 생성기는 특정 언어의 코드만 뽑아내게 설계된 생성기에 비해 훨씬 유연하다.

기사의 2장에서는 훨씬 복잡한 상황에서의 템플릿 코드 생성을 알아 것이다. 특별히 필자는 Internal Model Object(아래 참고자료 7) 사용한 템플릿의 사용법에 대해 알아볼 것이며 특정 언어의 코드 생성에 종속적인 벨로시티 컨텍스트를 비종속적인 컨텍스트로 작성하는 방법에 대한 패턴을 알아볼 것이다.

 

Posted by 1010
98..Etc/velocity2009. 1. 23. 14:59
반응형
VTL (Velocity Template Language)에 대해서는 여지껏 접해본바 없는 상황인지라 문법 익히기에도 급급하다.
대충 문법 정의 문서를 살펴보니 그리 어려운 언어는 아니라는 결론을 얻었다.

HTML 사용 하는거야 그냥 똑같이 쓰면 되고, 그 안에 스크립트를 끼워 넣는 것인데...
좀 더 쓰다 보면 익숙해지겠지... :-)

자.. 이제 익숙해지는 단계 이전까지는 뭔가 도움이 될만한 것들을 찾아봐야 하는데, 역시나 이클립스를 무시할 수가 없다. Velocity 코드 작성을 위한 Plug-In이 분명 존재할 것이란걸 믿고 찾아봤더니...
세상에나... 정말로 있다!!

Eclipse 사이트의 Plug-In Central 화면 캡춰



이제 설치를 해보자.

Velocity WebEditor - Eclipse Plugin : 아래 다운로드 클릭
상단에 링크된 파일을 다운받아서 압축을 해제하면 plugin 디렉토리가 생성되고 그 안에 실제로 설치에 필요한 디렉토리 및 파일들이 존재한다.


com.hudson.velocityweb_1.0.8 디렉토리를 Eclipse 설치 디렉토리 아래 plugins 디렉토리 하위에 복사.

Eclipse가 실행 중이었다면 재실행 해야 반영된다.


VM 파일을 수정하는 화면이다. 가장 도움이 되는 기능이 Syntex Coloring 과 Code Assist 기능이 지원된다는 것.
이제 눈을 부릅뜨고 코딩하는 일만 남았다.

조금이라도 빨리 퇴근하길 바라는 마음에서... ㅠ_ㅠ
Posted by 1010
반응형

전체 쿠키 정보를 Text 로 출력한다 . 모든 쿠키에 대한 정보를 알아볼려면  document.cookie 를 호출하면 된다. 집어 넣는 곳은 cookieOut 이라는 DIV 내에 Text 를 출력하는  로직이다.
// 모든 쿠키출력
function viewCookie()
{
   if( document.cookie.length > 0 )
      cookieOut.innerText = document.cookie;
   else
      cookieOut.innerText = "저장된 쿠키가 없습니다.";
}
// 출력화면
<DIV id = "cookieOut"></DIV>


저장된 쿠키값을 쿠키명으로 검색해서 넘겨주는 함수이다.
// param : 쿠키명
// return : 쿠키값
function getCookie( cookieName )
{
   var search = cookieName + "=";
   var cookie = document.cookie;

   // 현재 쿠키가 존재할 경우
   if( cookie.length > 0 )
   {
       startIndex = cookie.indexOf( cookieName );// 해당 쿠키명이 존재하는지 검색후 위치정보를 리턴.

       if( startIndex != -1 ) // 존재한다
      {
         startIndex += cookieName.length;// 값을 얻어내기 위해 시작 인덱스 조절
         endIndex = cookie.indexOf( ";", startIndex );// 값을 얻어내기 위해 종료 인덱스 추출
         if( endIndex == -1) endIndex = cookie.length; // 만약 종료 인덱스 못찾으면 쿠키 전체길이로 설정

         return unescape( cookie.substring( startIndex + 1, endIndex ) );// 쿠키값을 추출하여 리턴
      } else {
         return false; // 존재하지 않을때
      }
   } else {
      return false; // 쿠키 아예없을때
   }
}

쿠키값을 설정한다. 파라미터로는 쿠키명, 쿠키값, 쿠키날짜를 넘긴다
function setCookie( cookieName, cookieValue, expireDate )
{
   var today = new Date();
   today.setDate( today.getDate() + parseInt( expireDate ) );
   document.cookie = cookieName + "=" + escape( cookieValue ) + "; path=/; expires=" +                
           today.toGMTString() + ";"
}


쿠키명을 넘겨 해당하는 쿠키를 삭제한다
function deleteCookie( cookieName )
{
   var expireDate = new Date();
 
   //어제 날짜를 쿠키 소멸 날짜로 설정한다.
   expireDate.setDate( expireDate.getDate() - 1 );
   document.cookie = cookieName + "= " + "; expires=" + expireDate.toGMTString() + "; path=/";
}

Posted by 1010
98..Etc/velocity2009. 1. 23. 14:50
반응형

JSTL과 Velocity를 활용한 UI 레이어 구현 방법

Table of Contents

JSTL

소개

  • J2EE 소형 클라이언트 기술인 JSP(JavaServer Pages)가 지난 몇 년 동안 널리 일반화되면서 독립적인 개발자들은 많은 사용자 정
    의 JSP 태그 라이브러리를 만들었습니다. 이러한 태그 라이브러리는 대부분 서로 다른 목표를 달성하도록 작성되었지만 반복, 조건 등의 일
    반적인 작업을 위한 유사한 솔루션을 제공하는 경향이 있습니다.
    유사하고 일반적이 문제점을 해결하는 독립적인 태그 라이브러리에 대한 필요성을 줄이기 위해 Java Community Process(JSR 52)의 지
    원하에 JSTL(JavaServer Pages Standard Tag Library)이 개발되었습니다. JSTL은 이러한 일반 기능을 처리하는 하나의 표준 솔루션
    을 제공합니다. (말그대로 표준태그라이브러리)
  • JSTL의 주요 강점 중 하나는 서블릿 컨텍스트에 저장된 데이타 같은 애플리케이션 데이타를 액세스 및 조작하는 쉬운 방법을 제공하는 간
    단한 EL을 사용할 수 있다는 것입니다.

EL 에 대하여

설치 방법

  • http://cvs.apache.org/builds/jakarta-taglibs/nightly/ 에서 다운
    \jakarta-taglibs-20051024\jakarta-taglibs\standard\lib
    에서 jstl 과 standard 파일 을 이 두개의 jar 파일을 우리의 웹애플리케이션의 /WEB-INF/lib 폴더에 넣습니다
    그 다음 tld 폴더의 tld 파일을 /WEB-INF/lib/tld 폴더 아래 넣습니다.
  • web.xml 에
     
        <!-- jstl 1.2 taglig -->
         <taglib>
           <taglib-uri>jstl-c</taglib-uri>
           <taglib-location>/WEB-INF/tlds/jstl/c.tld</taglib-location>
        </taglib>
        <taglib>
           <taglib-uri>jstl-fmt</taglib-uri>
           <taglib-location>/WEB-INF/tlds/jstl/fmt.tld</taglib-location>
        </taglib>
        <taglib>
          <taglib-uri>jstl-fn</taglib-uri>
          <taglib-location>/WEB-INF/tlds/jstl/fn.tld</taglib-location>
        </taglib>
        

    를 추가한다.

  • jsp 에 추가
     
         <%@ taglib uri="jstl-c" prefix="c" %>
        <%@ taglib uri="jstl-fmt" prefix="fmt" %>
        <%@ taglib uri="jstl-fn" prefix="fn" %>
         

사용 예(기본 문법)

Area Subfunction Prefix Description
Core Variable support c 변수지원
Core Flow control c 흐름제어
Core URL management c URL 처리
Core Miscellaneous c  
XML Core x XML 코어
XML Flow control x 흐름 제어
XML Transformation x XML 변환
I18n Locale fmt 지역
I18n Message formatting fmt 메시지 형식
I18n Number and date formatting fmt 숫자 및 날짜 형식
Database SQL sql SQL
Functions Collection length fn 콜렉션 처리
Functions String manipulation fn String 처리

http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html 참고

  • 변수지원태그
    set: <c:set var="varName" scope="session" value="someValue">
    var속성은 값을 지정할 변수의 이름
    <c:set t a r g e t ="" property="userName" value="someValue">
    target : 빈 프로퍼티나 맵 값을 설정한다.(Object)
    var와 target을 동시에 사용할 수 없다.
    scope속성은 변수가 위치하는 영역(page,request,session,application)
    value :저장하는 값
    remove :<c:remove var="varName" scope="session">
    var :삭제할 변수의 이름
    scope 속성은 삭제할 변수의 영역
    out : <c:out value="">
    value속성은 출력하려는 값
    catch : <c:catch var="">
    </c:catch>
    예외사항이 한번이라도 발생시 </c:catch>로 점프
    var에 정의 된 객체를 페이지 생존범위에 자동으로 묶어 나중에 var에 정의된 변수이름을 사용할 수 있다.
    예외 발생시
    : var 속성 사용시 exception 객체를 설정.
    <c:catch> 문 밖으로 제어가 떨어진다
 
    <c:set var="num1" value="${20}" />
	<c:set var="num2">
		10.5
	</c:set>
	
	<c:set var="today" value="<%= new java.util.Date()%>" /><br>

	변수 num1 = ${num1} <br>
	변수 num2 = ${num2} <br>
	num1 + num2 = ${num1+num2}<br>
	오늘은 ${today}입니다.
	
	<c:remove var="num1" scope="page" />
	
	<p>
	삭제한 후의  num1=${num1} <br>
	삭제한 후의 num1 + num2 = ${num1 + num2}
   
 
       <c:catch var="myException">
     	It's catch
         <% int x = 10/0; %>
         실행안됨.
       </c:catch>
       <c:if test="${myException != null}">
           발생된 예외는 : ${myException.message} <br>
       </c:if>
     
  • URL 관련
    import : <c:import url=""/>
    url속성에 명기한 파일을 현재 컨텐츠에 포함
    param : <c:param name="" value=""/>
    <jsp:param />과 같은 역할
    url : <c:url value="" var=""/>
    value에 들어있는 상대 경로 뒤에 jsessionid를 추가한다.(쿠키를 사용 못하는 경우)
    var : 옵션 속성으로 url을 참조하기 위해쓴다.
    redirect :<c:redirect url="' context=""/>
    context : url경로의 이름
 
    <c:import url="Header.jsp" >
	<c:param name="subTitle" value="This is subTitle"/>
    </c:import>
   
  • 흐름제어 태그
    if : <c:if test="조건"> </c:if>
    test속성의 값에는 "조건"이 오는데 이 조건문의 결과값이 true 면 처리
     
       <c:if test="true">
         무조건 수행<br>
        </c:if>
    
        <c:if test="${param.name == 'bk'}">
          name 파라미터의 값이 ${param.name}입니다 <br>
        </c:if>
    
        <c:if test="${param.name eq 'bk'}">
          name 파라미터의 값이 ${param.name}입니다 <br>
        </c:if>
    
        <c:if test="${18 < param.age}">
    	 당신의 나이는 18세 이상입니다.
        </c:if>   
       

    choose,when,otherwise : <c:choose>
    <c:when test="조건">
    </c:when>
    <c:otherwise>
    </c:otherwise>
    </c:choose>
    choose 태그는 자바의 switch 문과 if-else 의 혼합한 형태, 다수의 조건문을 하나의 블록에서 수행하고자 할때 사용
    -> switch문과의 차이점은 중간에 빠져 나가지 못한다는 것이다.
    -> when 의 어느 하나에도 실행되지 않을때 otherwise 실행
    -> otherswise 태그가 반드시 있어야 하는것은 아니다.

 
     <c:choose>
       <c:when test="${param.name == 'bk' }">
	<li>당신의 이름은 ${param.name}입니다.
     </c:when>
     <c:when test="${param.age > 18 }">
	<li>당신은 18세 이상입니다.
     </c:when>

     <c:otherwise>
	<li> 당신은 'bk'가 아니고 18세 이상이 아닙니다.
     </c:otherwise>
     </c:choose> 
    

forEach : <c:forEach var="변수" items="아이템" begin="시작값" end="끝값" step="증가값">
</c:forEach>
item 속성에 올수 있는 것들로는 Map,배열,Collection 이 있다.
varStatus는 javax.servlet.jsp.jstl.core.LoopTagStatus 객체 인스턴스변수를 만들며 count라는 프로퍼티가 있어 몇번의 회전인지 알 수있다.

 
       <c:forEach var="i" begin="1" end="9">
	<li>4 *${i} = ${4 *i}
       </c:forEach>

       <h4>int 형 배열</h4>

       <c:forEach var="i" items="${intArray}" begin="2" end="4">
	[${i}]
       </c:forEach>

       <h4>Map</h4>
       <c:forEach var="i" items="${map}">
	  ${i.key} = ${i.value}<br>
       </c:forEach>

       <c:forEach var="member" items="${memberList}" varStatus="memberLoopCount">
	  회원 $(memberLoopCount.count} : ${member} <br>
       </c:forEach>
     

forTokens : <c:forTockens var="token" items="문자열" delins="구분자">
</c:forTockens>
forTokens 태그는 StringTokenizer 와 같은 기능을 제공한다.

 
       <c:forTokens var="token" items="빨강색, 주황색, 노란색, 초록색, 파랑색, 남색, 보라색" delims=",">
     	${token}<br>
       </c:forTokens>
     
  • 숫자 및 날짜 지원 형식
    The JSTL formatting actions allow various data elements in a JSP page, such as numbers,dates and times
    to be formatted and parsed in a locale-sensitive or customized manner.

formatNumber : 숫자 형식을 표현

 
 
      number  : <fmt:formatNumber value="9876543.61" type="number"/>
      currency: <fmt:formatNumber value="9876543.61" type="currency"/>
      percent : <fmt:formatNumber type="percent">9876543.61</fmt:formatNumber>

      pattern=".000"    :<fmt:formatNumber value="9876543.61" pattern=".000" />
      pattern="#,#00.0#":<fmt:formatNumber value="9876543.612345" pattern="#,#00.0#"/>
    

parseNumber : 정해진 패턴을 문자열에서 수치를 파싱해내는 태그
formatDate :날짜 형식을 표현

 
      <jsp:useBean id="now" class="java.util.Date"/>
	
         <c:out value="${now}"/>
           date: <fmt:formatDate value="${now}" type="date"/>
           time: <fmt:formatDate value="${now}" type="time"/>
           both: <fmt:formatDate value="${now}" type="both"/>

           default:<fmt:formatDate value="${now}"
                        type="both" dateStyle="default" timeStyle="default"/>
           short  :<fmt:formatDate value="${now}"
                        type="both" dateStyle="short"   timeStyle="short"  />
           medium :<fmt:formatDate value="${now}"
                        type="both" dateStyle="medium"  timeStyle="medium" />
           long   :<fmt:formatDate value="${now}"
                        type="both" dateStyle="long"    timeStyle="long"   />
           full   :<fmt:formatDate value="${now}"
                        type="both" dateStyle="full"    timeStyle="full"   />

          pattern="yyyy년MM월dd일 HH시mm분ss초"
             <fmt:formatDate value="${now}" type="both"
                             pattern="yyyy년MM월dd일 HH시mm분ss초"/>
            
         <fmt:formatDate value="${now}" pattern="yyyy/MM/dd" />

parseDate :정해진 패턴의 문자열에서 날짜를 파싱해내는 태그
timeZone : <fmt:timeZone value=""/>

setTimeZone : <fmt:timeZone value="" var="" scope=""/>

  • 국제화
    message <fmt:message
    setLocale <fmt:setLocale
    bundle <fmt:bundle
    setBundle <fmt:setBundle
    param <fmt:param
    requestEncoding <fmt:requestEncoding
  • SQL
    <sql:query sql="sqlQuery" var="varName" [scope="{page|request|session|application}"]
    [dataSource="dataSource"] [maxRows="maxRows"] [startRow="startRow"]>
    <sql:param>
    </sql:query>
         <sql:query var="customers" dataSource="${dataSource}">
          SELECT * FROM customers
          WHERE country ='China'
          ORDER BY lastname
         </sql:query>
         
         <table>
          <c:forEach var="row" items="">
             <tr>
               <td><c:out value="${row.lastName}"/></td>
               <td><c:out value="${row.firstName}"/></td>
               <td><c:out value="${row.address}"/></td>
             </tr>
          </c:forEach>
         </table>
       

<sql:update>
<sql:setDataSource>
<sql:param>
<sql:dateParam>

  • XML 코어
    <x:parse>
    <x:out>
    <x:set>
  • 흐름제어
    <x:if>
    <x:choose>
    <x:when>
    <x:otherwise>
    <x:forEach>
  • XML 변환
    <x:transform>
    <x:param>
  • function
    contains
    containsIgnoreCase
    endsWith
    escapeXml
    indexOf
    join
    length
    replace
    split
    startsWith
    substring
    substringAfter
    substringBefore
    toLowerCase
    toUpperCase
    trim
         <c:if test="${fn:contains(name, searchString)}">
         <c:if test="${fn:containsIgnoreCase(name, searchString)}">
         <c:if test="${fn:endsWith(filename, ".txt")}">
         ${fn:escapeXml(param:info)}
         ${fn:indexOf(name, "-")}
         ${fn:join(array, ";")} 
         You have ${fn:length(shoppingCart.products)} in your shopping cart.
         ${fn:replace(text, "-", "•")}
         ${fn:split(customerNames, ";")}
         <c:if test="${fn:startsWith(product.id, "100-")}">
         P.O. Box: ${fn:substring(zip, 6, -1)}
         P.O. Box: ${fn:substringAfter(zip, "-")}
         Zip (without P.O. Box): ${fn:substringBefore(zip, "-")}
         Product name: ${fn.toLowerCase(product.name)}
         Product name: ${fn.UpperCase(product.name)}
         Name: ${fn.trim(name)}
       

Velocity

Velocity

소개

  • 벨로시티란 자바 기반의 템플릿 엔진입니다.
    벨로시티를 활용하면 간단하면서도 강력한 템플릿 언어를 통하여 자바 코드에 정의된 객체를 액세스할 수 있습니다.
    벨로시티를 웹 개발에 사용하면, 웹 디자이너는 자바 프로그래머와 병렬로 작업을 할 수 있으며 MVC(모델-뷰-컨트롤러) 모델에 따라 웹 사이트를 개발할 수 있습니다. 더 자세히 설명하면 웹 페이지 디자이너의 경우 보기 좋은 사이트를 만드는 데만 집중하면 되고, 프로그래머는 잘 동작하는 코드를 만드는 데만 집중하면 된다는 뜻입니다.
    벨로시티는 웹 페이지와 자바 코드를 분리하여, 장기적인 측면에서 볼 때 웹 사이트를 손쉽게 유지보수할 수 있도록 하고, 자바 서버 페이지 (JSP) 또는 PHP를 대체할 수 있는 방안을 제시합니다. 벨로시티의 쓰임새는 웹 사이트에 국한되지 않습니다. 예를 들면, 템플릿으로부터 SQL이나 포스트스크립트, 또는 XML(XML 변환에 대해서는 벨로시티 툴 중 하나인 아나키아(Anakia)를 참조)문서를 생성하는 데 쓰일 수 있습니다. 벨로시티는 스탠드얼론 유틸리티처럼 사용하여 소스 코드나 리포트를 생성할 수도 있고, 다른 시스템의 컴포넌트로 통합할 수도 있습니다. 또한 벨로시티는 터빈 (또다른 자카르타 서브 프로젝트 중 하나) 웹 애플리케이션 프레임웍에 템플릿 서비스를 제공합니다. 벨로시티와 터빈을 조합하면 진정한 MVC 모델에 따라 웹 애플리케이션을 개발할 수 있습니다

설치 방법

  • web.xml 수정
     
       <servlet>
         <servlet-name>velocity</servlet-name>
            <servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet
         </servlet-class>
         <init-param>
            <param-name>org.apache.velocity.toolbox</param-name>
            <param-value>/WEB-INF/velocity-toolbox.xml</param-value>
         </init-param>
         <init-param>
            <param-name>org.apache.velocity.properties</param-name>
            <param-value>/WEB-INF/velocity.properties</param-value>
           </init-param>
         <load-on-startup>10</load-on-startup>
       </servlet>
       <servlet-mapping>
          <servlet-name>velocity</servlet-name>
          <url-pattern>*.vm</url-pattern>
       </servlet-mapping>
     
  • 파일 생성
    velocity.properties 파일
    velocity-toolbox.xml 을 생성 한 후 web_inf/lib 아래 둡니다.
    velocity-toolbox.xml
    <tool>
       <key>date</key>
       <scope>application</scope>
       <class>org.apache.velocity.tools.generic.DateTool</class>
     </tool>
    
      <tool>
      <key>math</key>
      <scope>application</scope>
      <class>org.apache.velocity.tools.generic.MathTool</class>
    </tool>
     ...
    

사용 예(기본 문법)

Velocity Template Language(VTL) 은 Template 에서 사용되는 Velocity 고유의 언어를 의미합니다.

  • References(참조형)
    Variables(변수) - 다음과 같이 $를 먼저 쓰고 그 뒤에 식별자를 적어주는 방식으로 사용
    ex) $foo
    Property(특성) - $ 다음에 식별자를 쓰고, 마침표(.)후에 다시 식별자의 형태로 사용
    ex) $foo.name
    Method(메소드) - $다음에 식별자를 쓰고 마침표 후에 호출할 메소드의 이름을 적는다
    ex)$foo.getName()
  • Directive(지시형)
    #set - reference 의 값을 설정한다.
    #if/elseif/else - 조건문 제어
    #foreach ---- 제어
    #include - velocity 로 파싱되지 않는 파일의 출력
    #parse -velocity 로 파싱된 파일 출력
    #stop -template 엔진의 정지
    #macro - 반복적으로 사용할 vm정의
  • Comment (주석)
      ## - 한줄짜리 주석
      #* ... *# 여러줄 짜리 주석
      
     ##This is an example velocity template
     #set($this = "Velocity")
       $this is great! But It's so hard.

     #foreach($name in $list)
       $name is great!
     #end

     #set($condition = true)
     #if ($condition)
        The condition is true!
     #else
       The condition is false
     #end
  

http://jakarta.apache.org/velocity/docs/vtl-reference-guide.html

Tool box 에 대해

VelocityTools is a collection of Velocity subprojects with a common goal of creating tools and infrastructure for building both web and non-web applications using the Velocity template engine.

  • Generic Tool (http://jakarta.apache.org/velocity/tools/generic/)
    *DateTool : A tool for manipulating and formatting dates
    *MathTool :A tool for performing floating point math.
    *NumberTool :A tool for formatting numbers
    *IteratorTool :A convenience tool to use with #foreach loops. It wraps a list to let the designer specify a
    condition to terminate the loop, and reuse the same list in different loops.
    *RenderTool:A tool to evaluate and render arbitrary strings of VTL (Velocity Template Language).
          Example uses:
      $date                         -> Oct 19, 2003 9:54:50 PM
      $date.long                    -> October 19, 2003 9:54:50 PM PDT
      $date.medium_time             -> 9:54:50 PM
      $date.full_date               -> Sunday, October 19, 2003
      $date.get('default','short')  -> Oct 19, 2003 9:54 PM
      $date.get('yyyy-M-d H:m:s')   -> 2003-10-19 21:54:50
     
      $myDate                        -> Tue Oct 07 03:14:50 PDT 2003
      $date.format('medium',$myDate) -> Oct 7, 2003 3:14:50 AM 
    
    
        
  • VelocityView (http://jakarta.apache.org/velocity/tools/view/)

JSTL 과 Velocity

같은 로직에 대해 두가지를 사용하여 각각 구현

다양한 View Technology에 대한 실행 속도 비교.

현재 개발중 우리들이 많이 사용하는 View 기술들을 이용하여 실행속도를 비교해 보면 다음 그래프와 같다.

이 그래프는 100명의 동시 접속자에 대한 테스트를 진행한 결과이다. 이 그래프는 Expert One-on-One J2EE Design and Development 책의 Chapter 15의 Web-Tier Performance Issues에서 인용하였다.

위와 같이 테스트를 진행한 결과 JSP는 초당 54페이지, Velocity는 초당 112페이지, XMLC는 초당 128 페이지, XSLT는 6,7페이지를 서비스하였다. 이 부분에서 눈여겨 볼 부분은 Velocity에 대한 결과라할 수 있다. 국내에서는 아직까지 많이 사용되지 않는 기술이지만 위의 실행 결과를 보면 사용할만한 가치가 있다는 것을 확인할 수 있다.

참고문헌

문서에 대하여

최초작성자 : 박재성
최초작성일 : 2005년 10월 15일
버전 : 1.0
문서이력 :

  • 2005년 10월 15일 박재성 문서 최초 생성 : 강좌 문서 템플릿 및 JSP와 Velocity에 대한 속도 비교문서 추가
Posted by 1010
98..Etc/velocity2009. 1. 23. 14:49
반응형
http://technet.ui2.co.kr/wiki/index.php/Velocity  velocity wiki 페이지

velocity 를 기본적으로 사용하기 위한 jar  파일 목록이다.
velocity-dep-*.jar : velocity 그리고 관련된 클래스 파일
velocity-tools-*.jar : velocity tool
commons-digester
commons-collections
commons-beanutils

1. VTL(Velocity Template Language) 장점
@ UI 디자이너와 개발자의 병렬 개발 가능
@ 각각의 영역에 집중가능
@ 유지보수 용의
@ JSP,PHP 대체방안 제시

2. VTL 문장은 # 으로 시작하며  변수명은 $ 로 표시한다.
# set( $foo = "Velocity")

3. 주석처리방법
한줄 : ##
여러줄 : #*  *#

4. 자바객체사용해서 하위 객체 접근이 가능하다
$ custom.Address
$ custom.getAddress()

5. 값을 불러오는 여러가지 방법
$ customer.address 를 다음과 같이 표현할수 있다.
$ getaddress()
$ getAddress()
$ get("address")
$ isAddress()

6. 중간에 변수가 들어가서 잘못 파싱되는것을 방지하기위해
쓰는 방식인데
기본적으로 이렇게 처리하는 버릇을 들이자.
Jack is a $vicemaniac.
Jack is a ${vice}maniac.

7. 값이 없을 시에 공백처리를 원할때
<input type="text" name="email" value="$!email>
좀더 안전하기를 원하면 value="$!{email}"

8. #set 지시자 사용시 큰따옴포("") 안의 내용은 파싱되어 그 결과물을 출력한다.
#set( $template = "$directoryRoot / $templateName")

9. '' 작은 따옴표는 파싱되지 않고 내용이 그대로 출력되지만
velocity.properties 안의 Stringliterals.interpolote = false 값을 바꿈으로서 파싱이 되도록 설정한다.

10. for 문으로 반복문을 처리하고 싶을때
iterator 와 비슷한 형태의 구조이다.
#foreach($page in $boardList)
<!-- 처리하고자 하는 내용 -->
#end

11. if 문을 쓰고싶을때
#if($velocityCount <= 3)
   $item
#end
Posted by 1010
반응형

첨부파일이 아니라 내용에 붙였습니다

xmls x = new xmls(...)에서

x.domLoad(...);

....

x.domWrite(...);

이런 방식으로 사용하시면 됩니다

자세한 설명은 생략하겠습니다

xml의 구조에 대해서 조금만 아신다면 금방 파악이 되실 겁니다

상용으로 잘 사용하고 있습니다

붙이다 보니 tab이 먹지 않아서 정렬이 안되어 있는데

copy해서 editor에서 정리한 다음 보십시오


import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

// xercesImpl.jar를 복사한다
// java_home/jre/lib/src.zip에 있음
import org.apache.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.*;
/*****
XML 문서의 구조
- 최상위 요소를 root라고 한다
  XML 문서는 단 하나의 root요소만을 가질 수 있다. 이를 흔히 top level이라고 한다
  root요소가 2개 이상일 경우에는 에러가 발생한다
- root요소 앞에는 XML 선언을 담고 있는 프롤로그가 올 수 있다
  XML 문서마다 사용된 XML 버전 정보를 프롤로그에 넣어주는것이 좋다
  <?xml version="1.0" ?>과 같이 버전 정보가 포함될 수 있다
  <?xml version="1.0" encoding="utf-8"?>
  <?xml version="1.0" encoding="euc-kr"?> encoding정보도 포함될 수 있다
  반드시 <?xml... 은 붙여야 한다
- 요소는 반드시 <와 >로 둘러싼 tag로 구성된다
  element와 attribute로 나뉘어 진다
  <tag>text</tag>
  <tag attribute="text">
  <tag attribute="text"></tag>
  <tag attribute="text"/>
  <tag></tag>
  <tag/>
- 주석은 <!--  -->이다

DOM (Document Object Model)
- XML문서를 메모리상에 올려놓은 다음 데이타를 찾아 들어가는 방식을 사용한다
- 큰 문서일경우 무조건 다 읽기 때문에 로드 시간이 걸리거나 메모리를 낭비하게 된다
- 문서 편집을 할 수 있다
- 데이타를 저장되어 있는 순서대로 받는다
SAX (Simple API for XML)
- 큰 문서를 효율적으로 분석하기 위해서 사용한다
- 이벤트가 발생하면 그에 해당하는 데이타를 추출한다. 속도가 DOM에 비해서 빠르다
- 읽기 전용이다. 문서를 편집할 수 없다
- 데이타를 SAX가 주는 순서대로 받는다. 파서가 문서를 탐색하는 순서에 대해서 어떠한 작업도 할 수 없다
- 원하는 요소만 골라서 읽을 수 있다
-----------------------------------------------------------------------------------------
현재 Java SAX Parser의 종류
- Xerces (Apache Foundation DOM & SAX)
  SAX와 DOMahen를 다룰 수 있게하는 XML API를 위하여 Apache Group의 프로젝트이다
  org.apache.xerces.parser를 사용한다
- Crimson (Sun Project X, JAXP Default Parser)
  Sun ProjectX의 일환으로 JAXP의 default parser로 채택되어져 있으며 XMLReader 인터페이스를 구현하므로
  SAX API를 이용하여 여러가지 다양한 파싱기능을 사용할 수 있다
- JAXP (Sun, Java API for XML Processing)
  Xerces처럼 DOM과 SAX 둘 다를 사용할 수 있도록 지원해주는 API이다
  한가지 다른점은 SAX API의 인터페이스를 직접 구현한 클래스를 제공하는것이 아니라
  abstract 계층을 한단계 얹은 형태를 제공한다
- Xalan은 xslt 프로세서이다. xsl을 이용하기 위해 필요하다
*****/

public class Xmls
{
 public static final int NONE = 0;
 public static final int DOM = 1;
 public static final int SAX = 2;
 // DOM
 private DocumentBuilderFactory dbFactory;
 private DocumentBuilder dBuilder;
 private Document document = null;
 private TransformerFactory tFactory;
 private Transformer transformer;
 // SAX
 private javax.xml.parsers.SAXParserFactory spFactory;
 private javax.xml.parsers.SAXParser sParser;
 private org.xml.sax.helpers.DefaultHandler defHandler;
// private SAXDbHandler defHandler = null;

 // type이 DOM이면 DOM방식으로 아니면 SAX 방식으로 처리한다
 public Xmls (int Type, boolean valid, org.xml.sax.helpers.DefaultHandler defHandler) throws Exception
 {
  if (Type == DOM)
      {
   dbFactory = DocumentBuilderFactory.newInstance();
   dbFactory.setValidating(valid);  // check를 넘겨주어도 된다
         dBuilder = dbFactory.newDocumentBuilder();
         // 출력할때 사용한다
   tFactory = TransformerFactory.newInstance();
         transformer = tFactory.newTransformer();
      }
  else
      {
         this.defHandler = defHandler;
         spFactory = javax.xml.parsers.SAXParserFactory.newInstance();
   sParser = spFactory.newSAXParser();
      // xslt 출력
//         TransformerFactory factory = TransformerFactory.newInstance();
//         Transformer transformer = factory.newTransformer(new SAXSource(new InputSource(stylesheetFile)));
//         transformer.transform(new SAXSource(new InputSource(XMLFilename)), new StreamResult(resultFilename));
      }
 }

 //******************** DOM 방식의 method
 // xml 문서를 읽는다
 // 버전 정보는 반드시 <?xml... 은 붙여야 한다. 아니면 에러가 발생한다
 public void domLoad (InputStream in) throws Exception
 {
  document = dBuilder.parse(in);
 }

 public void domLoad (String xmlPath) throws Exception
 {
  document = dBuilder.parse(new File(xmlPath));
 }

 public Document domGetDocument ()
 {
  return document;
 }

 // xml 문자열을 parsing한다
 // x.domParse("<node>가</node>");
 public void domParse (String xmlString) throws Exception
 {
  StringReader sr = new StringReader(xmlString);
  InputSource is = new InputSource(sr);

  document = dBuilder.parse(is);
 }

 // encoding이 null이거나 ""으면 setting하지 않는다
 public void domWrite (OutputStream out, String encoding) throws Exception
 {
  setEncoding(encoding);

  // javax.xml.transform.dom.
  DOMSource source = new DOMSource(document);
  StreamResult result = new StreamResult(out);
  transformer.transform(source, result);
 }

 public void domWrite (PrintWriter out, String encoding) throws Exception
 {
  StringWriter sw = new StringWriter();

  setEncoding(encoding);

  DOMSource source = new DOMSource(document);
  StreamResult result = new StreamResult(sw);
  transformer.transform(source, result);

  out.print(sw.toString());
 }

 // setEncoding("euc-kr");
 public void domWrite (String xmlPath, String encoding) throws Exception
 {
  setEncoding(encoding);

  // javax.xml.transform.dom.
  DOMSource source = new DOMSource(document);
  StreamResult result = new StreamResult(new File(xmlPath));
  transformer.transform(source, result);
 }

 // 모든 처리가 끝난 다음 마지막에 부른다
 public void domClose ()
 {
  this.document = null;
 }

 // element와 attribute를 새로 만들고 싶으면 아래의 순서대로 부른다
 // x.domAppendElement("personnel/person", "nation", "korea");
 // x.domAppendAttribute("personnel/person/nation", "capital", "서울");
 // node마다 각각의 값을 주기 위해서 String[] elementValue를 넘긴다
 public void domAppendAttribute (String xpath, String attrName, String[] attrValue) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Element element;

  // append하기 때문에 attribute는 반드시 unique한 값을 가져야 하기 때문에 갯수가 맞지 않으면 에러를 발생시킨다
  if (nodes.getLength() != attrValue.length) throw new Exception("node 갯수와 value 갯수가 맞지 않습니다.");

  for (int i = 0; i < nodes.getLength(); i++)
      {
      element = (Element)nodes.item(i);
      element.setAttribute(attrName, attrValue[i]);
      }
 }

 // 해당 attribute node를 삭제하고 싶으면 domDeleteElement를 사용한다
 public void domDeleteAttribute (String xpath, String attrName) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Element element;

  for (int i = 0; i < nodes.getLength(); i++)
   {
      element = (Element)nodes.item(i);
      element.removeAttribute(attrName);
      }
 }

 // elementValue가 없으면 text node를 append하지 않는다
 // x.domAppendElement("personnel/person", "nation", String[] k = { "korea" });
 // node마다 각각의 값을 주기 위해서 String[] elementValue를 넘긴다
 public void domAppendElement (String xpath, String elementName, String[] elementValue) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Element element, element2;
  Text node;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      // loop안에서 선언한다. 모든 node에 append가 된다
   element = document.createElement(elementName);
   // nodes의 갯수와 elementValue의 갯수가 달라도 된다
      if (i < elementValue.length && Codes.checkNull(elementValue[i]) == false)
    {
    node = document.createTextNode(elementValue[i]);
          element.appendChild(node);
    }
      element2 = (Element)nodes.item(i);
      element2.appendChild(element);
      }
 }

 // x.domDeleteElement("personnel/person")
 // 하위 node 전체가 삭제된다
 public void domDeleteElement (String xpath) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Node node;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      node = nodes.item(i);
      node.getParentNode().removeChild(node);  // 부모 노드에서 자식 노드(자신)를 삭제
      }
 }

 // xml 문자열을 파싱해서 해당 노드에 child로 붙인다
 // x.domAppendParse("personnel/person", "<node2><node3></node3></node2>");
 // x.domAppendAttribute("personnel/person/node2", "id", new String[] { "1", "2", "3", "4", "5", "6"  });
 // x.domAppendParse("personnel/person", "<node2><node3 id=\"1\">가</node3></node2>");
 public void domAppendParse (String xpath, String xmlString) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Document tempDoc = makeTempDoc(xmlString);
  Node node;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      // loop안에 선언해야 한다.
   node = tempDoc.getDocumentElement();
   node = document.importNode(node, true);
      nodes.item(i).appendChild(node);
      }
 }

 // 기존의 노드에 값만 추가 시킨다
 // x.domAppendTextNode("personnel/person/node2/node3", "가");
 public void domAppendTextNode (String xpath, String[] txtValue) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  Text node;

  for (int i = 0; i < nodes.getLength(); i++)
      {
   // nodes의 갯수와 txtValue의 갯수가 달라도 된다
      if (i < txtValue.length && Codes.checkNull(txtValue[i]) == false)
    {
    node = document.createTextNode(txtValue[i]);
       nodes.item(i).appendChild(node);
    }
      }
 }

 // xpath="personnel/person/email"
 // attr, element 모두 xpath로 지정하면 갯수를 돌려준다
 public int domGetNodeCount (String xpath) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);

  return nodes.getLength();
 }

 // xpath="personnel/person", attr="id"
 // 해당 값의 index 값을 돌려준다. 중복값이 있으면 처음 발견되는 값의 index를 돌려준다
 public int domGetIndexAttribute (String xpath, String attrName, String attrValue) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  NamedNodeMap map;
  Node node, node2;
  String value = null;
  int idx = -1;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      node = nodes.item(i);
      map = node.getAttributes();
      node2 = map.getNamedItem(attrName);
      if (node2 != null && Codes.checkNull(attrValue) == false)
       {
          value = node2.getNodeValue();
       if (attrValue.equals(value)) { idx = i;  break;  }
       }
      }

  return idx;
 }

 public ArrayList domGetAttribute (String xpath, String attrName) throws Exception
 {
  return getAttribute(xpath, attrName, -1);
 }

 //** attr과 value의 갯수가 다를 수 있기 때문에 원하는 index의 attribute값이 아닐수도 있다
 // dom일 경우는 xml의 순서대로 읽어오기 때문에 index로의 처리가 가능하다
 public String domGetAttribute (String xpath, String attrName, int index) throws Exception
 {
  return (String)getAttribute(xpath, attrName, index).get(0);
 }

 // xpath="personnel/person", attr="id"
 public void domSetAttribute (String xpath, String attrName, String attrValue) throws Exception
 {
  setAttribute(xpath, attrName, null, new String[] { attrValue }, -1, 0);
 }

 // attribute는 unique하기 때문에 origs, news가 가능하다. index로 변경하지 않아도 된다
 // origValue는 원래 값, newValue는 새로운 값. origValue 값이 null이거나 ""이면 전체를 newValue 값으로 setting한다
 // 대소문자를 구분하고 싶지 않으면 외부에서 대소문자로 변환해서 넘겨준다
 public void domSetAttribute (String xpath, String attrName, String origValue, String newValue) throws Exception
 {
  setAttribute(xpath, attrName, origValue, new String[] { newValue }, -1, 0);
 }

 // 해당 index의 attribute를 수정한다
 public void domSetAttribute (String xpath, String attrName, String attrValue, int index) throws Exception
 {
  setAttribute(xpath, attrName, null, new String[] { attrValue }, index, 0);
 }

 // 기존의 attribute값을 변경한다
 public void domSetAttribute (String xpath, String attrName, String[] attrValue) throws Exception
 {
  setAttribute(xpath, attrName, null, attrValue, -1, attrValue.length);
 }

 // xpath에 해당하는 값이 여러개이면 여러개 하나면 하나만 돌려준다
 // xpath="personnel/person/email"
 public ArrayList domGetValue (String xpath) throws Exception
 {
  return getValue(xpath, -1);
 }

 //** attr과 value의 갯수가 다를 수 있기 때문에 원하는 index의 attribute값이 아닐수도 있다
 // dom일 경우는 xml의 순서대로 읽어오기 때문에 index로의 처리가 가능하다
 public String domGetValue (String xpath, int index) throws Exception
 {
  return (String)getValue(xpath, index).get(0);
 }

 // domSetAttribute하고 다르다. attribute는 unique하기 때문에 origs, news가 가능하다
 // xpath="personnel/person/email"
 public void domSetValue (String xpath, String value) throws Exception
 {
  setValue(xpath, new String[] { value }, -1, 0);
 }

 //** attr과 value의 갯수가 다를 수 있기 때문에 원하는 index의 attribute값이 아닐수도 있다
 // dom일 경우는 xml의 순서대로 읽어오기 때문에 index로의 처리가 가능하다
 public void domSetValue (String xpath, String value, int index) throws Exception
 {
  setValue(xpath, new String[] { value }, index, 0);
 }

 public void domSetValue (String xpath, String[] value) throws Exception
 {
  setValue(xpath, value, -1, value.length);
 }

 // domWrite할때 사용한다
 // setEncoding("euc-kr");
 private void setEncoding (String encoding)
 {
  if (Codes.checkNull(encoding)) return;

  transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
 }

 private Document makeTempDoc (String nodeString) throws Exception
 {
  StringReader sr = new StringReader(nodeString);
  InputSource is = new InputSource(sr);

  return dBuilder.parse(is);
 }

 private ArrayList getAttribute (String xpath, String attrName, int index) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  NamedNodeMap map;
  Node node, node2;
  ArrayList al = new ArrayList();
  String value = null;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      if (index >= 0 && i != index) continue;

      node = nodes.item(i);
      map = node.getAttributes();      // 같은 node를 찾는다
      node2 = map.getNamedItem(attrName);
      if (node2 != null)
    {
       value = node2.getNodeValue();
          al.add(value);
    }
      }

  return al;
 }

 private void setAttribute (String xpath, String attrName, String attrValue, String[] setValue, int index, int length) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  NamedNodeMap map;
  Node node, node2;
  String value = null;
  int off;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      if (length > 0 && i >= length) break;
   if (index >= 0 && i != index) continue;

      node = nodes.item(i);
      map = node.getAttributes();
      node2 = map.getNamedItem(attrName);
   off = (length > 0) ? i : 0;
      if (node2 != null)
    {
       if (index > -1 || Codes.checkNull(attrValue)) node2.setNodeValue(setValue[off]);
          else
        {
           value = node2.getNodeValue();
        if (attrValue.equals(value)) { node2.setNodeValue(setValue[off]);  break; }
        }
    }
      }
 }

 private ArrayList getValue (String xpath, int index) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  NodeList children;
  Node node;
  Node childNode;
  ArrayList al = new ArrayList();
  // value를 리턴하기 위해서 string 변수를 선언
  String value = null;

  // 여러개의 element에서 하나의 태그가 빠지면 nodes.getLength()의 갯수가 아예 줄어든다
  // al.add(Integer.toString(nodes.getLength()));
  for (int i = 0; i < nodes.getLength(); i++)
      {
   if (index >= 0 && i != index) continue;

      node = nodes.item(i);
      if (node.hasChildNodes())
    {
    // child node가 있는 node type은 element와 document뿐이다
    if (node.getNodeType() == Node.ELEMENT_NODE)
        {
     // Element 인 경우에는 자식노드를 검색해서 자식 노드중 텍스트 노드, 그러니까
     // 태그 사이의 텍스트 값을 리턴하자 일단.
        children = node.getChildNodes();
        for (int j = 0; j < children.getLength(); j++)
         {
      childNode = children.item(j);
      if (childNode.getNodeType() == Node.TEXT_NODE)
          {
       // 자식노드를 순환하다가 TextNode 발견하면 value로 세팅.
       // out.println(childNode.getNodeName());
          value = childNode.getNodeValue();
          al.add(value);
          }
      }
        }
    else
        {
        /*
        <personnel>
          <person id="Big.Boss">
            <name><family>Boss</family> <given>Big</given></name>
            <email>chief@foo.com</email>
            <link subordinates="one.worker two.worker three.worker four.worker five.worker"/>
          </person>
        </personnel>
        -- person이나 name일 경우 값이 없다.
        */
     // Document 인 경우에는 Node value라는 개념이 애매하니까..
     // 전체 String 을 리턴하거나 null값을리턴해야 하는데 일단 null을 리턴하기로 하자.
     // Do nothing
        }
    }
      else
    {
    // 자식노드가 없는 Attribute나 Text노드, CDATASection등의 값을 질의한 경우. getNodeValue를 이용.
    value = node.getNodeValue();
    al.add(value);
    }
      }

  return al;
 }

 private void setValue (String xpath, String[] value, int index, int length) throws Exception
 {
  NodeList nodes = XPathAPI.selectNodeList(document, xpath);
  NodeList children;
  Node node;
  int off;

  for (int i = 0; i < nodes.getLength(); i++)
      {
      if (length > 0 && i >= length) break;
   if (index >= 0 && i != index) continue;

      off = (length > 0) ? i : 0;
      node = nodes.item(i);
      if (node.hasChildNodes())
    {
    // 기존 Text노드를 삭제하고 다시 setting해야 한다
    // 삭제하지 않으면 기존값에 새로운값이 붙여서 처리된다
    children = node.getChildNodes();
    for (int j = 0; j < children.getLength(); j++)
        {
        if (children.item(j) instanceof Text) node.removeChild(children.item(j));
        }
    if (node.getNodeType() == Node.ELEMENT_NODE) node.appendChild((Text)document.createTextNode(value[off]));
    else                                         node.setNodeValue(value[off]);
    }
      else
    {
    /*
    자식노드가 없는 Attribute나 Text노드, CDATASection등의 값을 질의한 경우.
    person, link인 경우에 해당
       <personnel>
         <person id="Big.Boss">
           <name><family>Boss</family> <given>Big</given></name>
           <email>chief@foo.com</email>
           <link subordinates="one.worker two.worker three.worker four.worker five.worker"/>
         </person>
       </personnel>
    */
    if (node.getNodeType() == Node.ELEMENT_NODE) node.appendChild((Text)document.createTextNode(value[off]));
    else                                         node.setNodeValue(value[off]);
    }
      }
 }

 //******************** SAX 방식의 method
    // defHandler는 saxLoad를 부를때 외부에서 받는다
 // overriding을 해야 하기 때문에 외부에서 defHandler를 control을 할 수 있게 한다.
 public void saxLoad (InputStream in) throws Exception
 {
  sParser.parse(in, defHandler);
 }

 public void saxLoad (String xmlPath) throws Exception
 {
     sParser.parse(new File(xmlPath), defHandler);
 }

 public org.xml.sax.helpers.DefaultHandler saxGetDefHandler ()
 {
  return defHandler;
 }
}

Posted by 1010
반응형

이 글에서는 Java 2 Java 2, Enterprise Edition, v 1.4 를 사용합니다. 다운로드



SUN JAVA STREAMING XML PARSER 소개

XML을 사용하는 대부분의 Java 개발자는 SAX (Simple API for XML) 라이브러리와 DOM(Document Object Model) 라이브러리에 익숙할 것이다. SAX는 이벤트 기반의 API이며, 이는 일반적으로 프로그래머가 파서와 몇 개의 리스너를 등록하고, 특정 XML 문법 생성자(예를 들어 요소나 속성)가 도착되면 리스너 메소드가 호출된다는 의미이다. 그 반대로 DOM은 트리 기반의 아케텍처를 가지며, 전체 문서를 스캔하여 마주치는 각각의 문법 생성자의 오브젝트 트리를 구축한다. 프로그래머는 스캔이 완료된 후 오브젝트 트리에 접근하여 수정할 수 있다

이 두 방법 모두 각각의 결점을 가지고 있다: 리스너를 이용하는 이벤트 기반의 API는 일반적으로 다루기 힘들다. 리스너들이 파서에 의해 조종되기 때문이다. 트리 기반의 API는 스캔되는 문서의 양에 비해 과도한 양의 메모리를 소모할 수 있다. 이제 Java 개발자들이 XML 을 스캔하는데 이용할 수 있는 세 번째 API가 등장하였다. StAX (Streaming API for XML parse)가 그것이다.

SJSXP란?

SJSXP(Sun Java Streaming XML Parser)는 StAX를 빠른 속도로 구현한다. 썬마이크로시스템즈와 협력하고 있는 BEA Systems, XML-guru James Clark, Stefan Haustein, Aleksandr Slominski (XmlPull 개발자들), 그리고 JCP의 다른 멤버들은 JSR 173를 구현하는 것으로써 StAX를 개발하였다. StAX은 공유 인터페이스들에 기반하는, 파서(parser) 독립적인 Java API이다.

SJSXP는 Java Web Services Developer Pack v1.5에 포함되어있다. SJSXP에 대해 처음으로 알아차릴만한 것은 이것이 스트림 API에 기반한다는 것이다. 즉, 개발자가 어느 한 노드에 접근하기 위해 전체 문서를 읽을 필요가 없다. 또한, 파서를 시작하여 파서가 데이터를 이벤트 리스너 메소드에 "push"하도록 허용하는 법칙을 따르지 않는다. 대신에 SJSXP는 "pull" 메소드를 구현하며, 이 메소드는 정렬 포인터를 문서에서 현재 스캔되고 있는 지점에 유지한다. 이는 종종 커서(cursor)라고 불린다. 사용자는 단순히 커서가 현재 가리키고 있는 노드에 대한 파서를 요청하면 된다.

XML 문서 파싱에 SJSXP 이용하기

SJSXP를 이용하여 XML 문서를 읽는 것은 아주 쉽다. 대부분의 작업은 javax.xml.stream.XMLStreamReader 인터페이스를 구현하는 오브젝트를 통해 이뤄진다. 이 인터페이스는 XML 문서의 첫 부분에서 마지막까지 이동되는 커서를 나타낸다. 몇 가지 명심해야할 것이 있다. 커서는 항상 하나의 아이템(시작 태그 요소, 진행 명령, DTD 선언 등)만을 가리켜야 한다. 또한 커서는 항상 앞으로 움직여야 하며 (뒤로 움직일 수 없다), 다음에 무엇이 나타나는지 미리 보기를 실행할 수 없다. 다음의 코드 발췌에서 파일로부터 XML을 읽는 XMLStreamReader를 얻을 수 있다.

   URL url = Class.forName("MyClassName").getResource(
           "sample.xml");            
   InputStream in = url.openStream();
   XMLInputFactory factory = XMLInputFactory.newInstance();
   XMLStreamReader parser = factory.createXMLStreamReader(in);

그 후 다음 코드를 이용하여 XML 파일을 반복할 수 있다.

   while(parser.hasNext()) {
             
         eventType = parser.next();
         switch (eventType) {

              case START_ELEMENT:
              //  Do something
              break;
              case END_ELEMENT:
              //  Do something
              break;
              //  And so on ...
         }
     }

XMLStreamReaderhasNext() 메소드는 XML 파일에서 또다른 유효한 아이템이 있는지 확인한다. 만약 있다면, 커서가 다음 아이템으로 넘어가게하기 위해 next() 메소드를 사용할 수 있다. next() 메소드는 만나게되는 문법상 생성자(아이템)의 타입을 가리키는 인티거 코드를 리턴한다.

XMLInputStreamReader에는 몇 개의 get 메소드가 있어서 커서가 가리키는 XML 아이템의 내용을 얻는 데 사용할 수 있다. 첫번째 메소드는 getEventType()이다:

   public int getEventType()

메소드는 커서가 있는 곳에서 파서가 찾은 아이템의 타입을 식별하는 integer 코드를 리턴한다. next() 메소드에 의해 리턴되는 것과 같은 코드이다. 아이템은 XMLInputStream 상수 중 하나에 의해 식별된다.

  XMLStreamConstants.START_DOCUMENT 
  XMLStreamConstants.END_DOCUMENT 
  XMLStreamConstants.START_ELEMENT 
  XMLStreamConstants.END_ELEMENT 
  XMLStreamConstants.ATTRIBUTE 
  XMLStreamConstants.CHARACTERS 
  XMLStreamConstants.CDATA 
  XMLStreamConstants.SPACE 
  XMLStreamConstants.COMMENT 
  XMLStreamConstants.DTD 
  XMLStreamConstants.START_ENTITY 
  XMLStreamConstants.END_ENTITY 
  XMLStreamConstants.ENTITY_DECLARATION 
  XMLStreamConstants.ENTITY_REFERENCE 
  XMLStreamConstants.NAMESPACE 
  XMLStreamConstants.NOTATION_DECLARATION 
  XMLStreamConstants.PROCESSING_INSTRUCTION 

만약 아이템에 이름이 있는 경우, getName()getLocalName() 메소드를 사용하여 이름을 얻을 수 있다. 후자는 어떤 다른 정보(예; 확인된 네임스페이스가 없는 요소의 이름) 없이 이름 자체를 산출한다.

   public Qname getName()
   public String getLocalName()

만약 당신이 현재 아이템의 네임스페이스를 식별하고 싶다면 getNamespaceURI() 메소드를 사용 할 수 있다.

   public String getNamespaceURI()

만약 DTD 선언 내의 텍스트나 요소 안의 텍스트 등과 같은 동반되는 텍스트가 있을 때에는 다음 메소드들을 사용하여 얻을 수 있다.(후자는 요소를 위해 단독으로 사용 될 수 있다)

   public String getText()
   public String getElementText()

만약 요소가 그것과 관계 되는 속성을 가진다면 getAttributeCount() 메소드를 사용하여 현재 요소가 가진 속성들의 갯수를 얻을 수 있다. 그 후 getAttributeName()getAttributeValue() 메소드를 사용하여 각각의 정보를 검색 할 수 있다.

   public int getAttributeCount()
   public Qname getAttributeName(int index)
   public String getAttributeValue(int index)

만약 속성의 로컬 이름과 요소의 네임스페이스 URI를 안다면, 또한 다음의 메소드를 이용하여 속성값을 얻을 수 있다.

   public String getAttributeValue(
     String elementNamespaceURI, String localAttributeName) 

추측했겠지만, 모든 접근자 메소드가 특정 상태에 적용가능한 것이 아니다. 예를 들어, 현재 DTD를 프로세싱 중이라면 getElementText()을 호출할 수 없다. 만약 이를 호출한다면, 파서가 충돌하는 이벤트 타입을 식별했다는 XMLStreamException을 얻게 되거나 메소드가 스스로 널(null) 값을 리턴하게 될 것이다.

XMLInputFactory 클래스의 setProperty() 메소드를 사용하여 몇 가지 파서 속성을 시작할 수 있다. 예를 들어, 다음은 파서와 마주치는 엔티티 레퍼런스는 교체될 것이라고 지정한다.

   factory.setProperty(
     XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, 
       Boolean.TRUE);

파서가 외부 엔티티를 지원하는 것을 막기 위해 다음과 같이 설정한다.

   factory.setProperty(
     XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, 
       Boolean.FALSE);

파서가 네임스페이스를 알아차리게하기 위해 다음과 같이 설정한다.

   factory.setProperty(
     XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);

SJSXP의 현재 버전에서는 다음의 명령은 허용되지만 파서는 확인되지 않는다는 것을 유의하기 바란다.

   factory.setProperty(XMLInputFactory.IS_VALIDATING, 
     Boolean.TRUE);

만약 이 XMLInputFactory 특성들 중 어느 하나라도 가능하게 된다면 setXMLReporter() 메소드를 사용하여 파서가 만나게되는 오류를 제어할 수 있다. 파서가 만나는 오류의 타입을 가장 빨리 정확하게 결정할 수 있는 방법은 setXMLReporter() 메소드와 상호 작용하는 익명의 이너 클래스를 사용하는 것이다. 이는 다음과 같다.

   factory.setXMLReporter(new XMLReporter() {
     public void report(String message, String errorType,
       Object relatedInformation, Location location) {
         System.err.println("Error in " 
          + location.getLocationURI());
         System.err.println("at line " 
          + location.getLineNumber()
          + ", column " + location.getColumnNumber());
         System.err.println(message);
     }
   });

XML 문서 작성에 SJSXP 사용하기

XML 결과를 작성하는 것은 SJSXP를 이용하면 쉽다. 이 경우, XMLStreamReader 인터페이스 대신에 XMLStreamWriter 인터페이스를 사용할 수 있다. XMLStreamWriter 인터페이스는 작성하는 요소, 속성, 코멘트, 텍스트를 비롯해 XML 문서의 모든 부분을 작성하기 위한 직접적인 메소드를 제공한다. 다음의 예제에서는 어떻게 이 인터페이스를 얻어서 XML 문서를 작성하는데 사용하는지 보여준다.

   XMLOutputFactory xof =  XMLOutputFactory.newInstance();
   XMLStreamWriter xtw = 
     xof.createXMLStreamWriter(new FileWriter("myFile"));

   xtw.writeComment(
     "all elements here are in the HTML namespace");
   xtw.writeStartDocument("utf-8","1.0");
   xtw.setPrefix("html", "http://www.w3.org/TR/REC-html40");
   xtw.writeStartElement(
     "http://www.w3.org/TR/REC-html40","html");
   xtw.writeNamespace(
     "html", "http://www.w3.org/TR/REC-html40");
   xtw.writeStartElement(
     "http://www.w3.org/TR/REC-html40","head");
   xtw.writeStartElement(
     "http://www.w3.org/TR/REC-html40","title");
   xtw.writeCharacters("Java Information");
   xtw.writeEndElement();
   xtw.writeEndElement();

   xtw.writeStartElement(
     "http://www.w3.org/TR/REC-html40","body");
   xtw.writeStartElement("http://www.w3.org/TR/REC-html40","p");
   xtw.writeCharacters("Java homepage is ");
   xtw.writeStartElement("http://www.w3.org/TR/REC-html40","a");
   xtw.writeAttribute("href","http://java.sun.com");
   xtw.writeCharacters("here");
   xtw.writeEndElement();
   xtw.writeEndElement();
   xtw.writeEndElement();
   xtw.writeEndElement();
   xtw.writeEndDocument();

   xtw.flush();
   xtw.close();

각 요소를 작성하는 것이 끝나면 사용자는 라이터(writer)를 날려보내고 닫아야한다.

이전의 코드는 다음의 XML로 결과가 나타난다.(여기서는 쉽게 읽을 수 있게 라인 별로 나타내었다.)

   <!--all elements here are explicitly in the HTML namespace-->
   <?xml version="1.0" encoding="utf-8"?>
   <html:html xmlns:html="http://www.w3.org/TR/REC-html40">
   <html:head>
   <html:title>Java Information</html:title>
   </html:head>
   <html:body>
   <html:p>
   Java information is 
   <html:a href="http://frob.com">here</html:a>
   </html:p>
   </html:body>
   </html:html>

XML 문서 필터링

만약 각각의 아이템 타입을 스캔하고 싶지 않다면 들어오는 XML 문서에 대한 필터를 생성할 수 있다. 이를 위해서는 javax.xml.stream.StreamFilter 인터페이스를 구현하는 클래스를 생성한다. 이 인터페이스는 단지 accept() 메소드만으로 구성된다. 이 메소드는 XMLStreamReader 오브젝트를 허용하고 원시 Boolean을 리턴한다. StreamFilter의 일반적인 구현은 다음과 같다.

   public class MyStreamFilter implements StreamFilter {

       public boolean accept(XMLStreamReader reader) {
           if(!reader.isStartElement() && !reader.isEndElement())
               return false;
           else
               return true;
       }
   }

그 다음으로 XMLInputFactorycreateFilteredReader() 메소드를 호출하여 필터링된 리더(reader)를 생성하고 이를 원래 XML 스트림 리더와 StreamFilter 구현에 모두 전달한다. 다음과 같다.

   factory.createFilteredReader(
     factory.createXMLStreamReader(in), new MyStreamFilter());

SJSXP의 더 자세한 정보는 Sun Java Streaming XML Parser release notes를 참고하기 바란다.

Sun Java Streaming XML Parser 예제 코드 구동하기

  1. 이번 테크팁에 대한 샘플 아카이브(ttfeb2005sjsxp.jar)를 다운로드한다.

  2. Java Web Services Developer Pack Downloads page에서 Java WSDP 1.5를 다운로드, 설치한다.

  3. 예제 압축파일을 다운로드 받은 디렉토리를 변경하고, 다음과 같이 샘플 아카이브에 대한 JAR 파일의 압축을 푼다.
         jar xvf ttfeb2005sjsxp.jar
    
  4. 사용자의 classpathttfeb2005sjsxp.jarjsr173_api.jar를 포함하도록 설정한다. 이들은 Java WSDP 1.5 installation의 sjsxp/lib 디렉토리에 위치하고 있다.

  5. SJSXPInput를 컴파일하고 구동한다.

    다음의 각각의 XML 아이템과 유사한 엔트리가 나타날 것이다.
       Event Type (Code=11): DTD
       Without a Name
       With Text: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
       Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
       transitional.dtd">
      -----------------------------
    
  6. SJSXPOutput를 컴파일하고 구동한다. 결과는 XMLOutputFile라는 이름의 파일에 보내지며, 위의 결과 예제에 보여지는 요소들을 포함할 것이다.
Posted by 1010
반응형

//인터넷 XML 날씨 정보를 파싱 (DomParser.java)


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DomParser {

        private static Document xmlDoc = null;
        private static String XML_URL = "http://weather.unisys.com/forexml.cgi?seoul";
        private static String XML_NODE = "observation";
        private static String XML_CITY = "city";
        private static String XML_TIME = "time";
        private static String XML_SKIES = "skies";
        private static String XML_TEMP = "temp.C";

        public static void main(String[] args) {
                printXmlFromUrl(XML_URL);
        }

        private static void printXmlFromUrl(String urlString) {
                try {
                        URL url = new URL(urlString);

                        try {
                                URLConnection urlConnection = url.openConnection();
                                HttpURLConnection httpConnection = (HttpURLConnection)urlConnection;

                                int responseCode = httpConnection.getResponseCode();
                                if (responseCode == HttpURLConnection.HTTP_OK) {
                                        InputStream inputStream = httpConnection.getInputStream();

                                        // Parsing XML Document
                                        createDomParser(inputStream);
                                        String[] xmlData = getByTagName(XML_NODE);
                                        for (int i = 0; i < xmlData.length; i++) {
                                                System.out.println(xmlData[i]);
                                        }

                                        inputStream.close();
                                } else {
                                        System.out.println("HTTP Response is not \"HTTP Status-Code 200: OK.\"");
                                }
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                } catch (MalformedURLException e) { 
                        e.printStackTrace();
                }
        }

        private static void createDomParser(InputStream inputStream) {

                // Use factory to create a DOM document
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setIgnoringElementContentWhitespace(true);
                DocumentBuilder builder = null;

                try { // Get a DOM parser from the Factory
                        builder = factory.newDocumentBuilder();
                } catch (ParserConfigurationException e) {
                        e.printStackTrace();
                        return;
                }

                try { // Request the DOM parser to parse the file
                        xmlDoc = builder.parse(inputStream);
                } catch (SAXException e) {
                        e.printStackTrace();
                        return;
                } catch (IOException e) {
                        e.printStackTrace();
                        return;
                }
        }

        private static String[] getByTagName(String tagName) {

                if (!(xmlDoc == null)) {
                        NodeList nodes = xmlDoc.getElementsByTagName(tagName);
                        NamedNodeMap nodeMap = nodes.item(0).getAttributes();

                        String[] values = new String[4];
                        values[0] = nodeMap.getNamedItem(XML_CITY).getNodeValue();
                        values[1] = nodeMap.getNamedItem(XML_TIME).getNodeValue();
                        values[2] = nodeMap.getNamedItem(XML_SKIES).getNodeValue();
                        values[3] = nodeMap.getNamedItem(XML_TEMP).getNodeValue();
                        return values;
                }
                return null;
        }
}

Posted by 1010
반응형

XML Parser 함수들

함수

리턴 값

설명

xml_error_string(code)

string

제공된 오류 code와 결홥된 오류 메시지를 리턴한다.

xml_get_current_byte_index(parser)

integer

XML 파서를 위해 현제 바이트 인덱스를 리턴한다.

xml_get_current_column_number(parser)

integer

지정된 parser를 위해 현재 행 번호를 리턴한다.

xml_get_current_line_number(parser)

integer

지정된 parser를 위해 현재 줄 번호를 리턴한다.

xml_get_error_code(parser)

integer

마지막으로 발생한 xml,파서의 올에대한 오류 코드를 리턴한다.

xml_parse(parser, data, [is_final])

integer

지정된 data를 분석한다.

xml_parser_create([encoding_parameter])

integer

xml 파서를 작성한다.

xml_parser_free(parser)

Boolean

지정된 xml parser를 해제한다.

xml_parser_get_option(parser, option)

Mixed

지정된 parser에 대한 지정된 option의 값을 리턴한다.

xml_parser_set_option(parser, option, value)

integer

지정된 parser를 위해 option을 지정된 value로 설정한다.

xml_set_character_data_handler(parser, handler)

integer

문자 데이터 핸들러를 등록한다.

xml_set_default_handler(parser, handler)

integer

기본 핸들러를 등록한다.

xml_set_element_handler(parser, handler)

integer

시작과 끝 구성 요소 핸들러를 등록한다.

xml_set_external_entity_ref_handler(parser, handler)

integer

외부 엔티티 참조 핸들러를 등록한다.

xml_set_notation_decl_handler(parser, handler)

integer

표기법 선언 핸들러를 등록한다.

xml_set_processing_instruction_handler(parser, handler)

integer

처리 지시어 핸들러를 등록한다.

xml_set_unparsed_entity_decl_handler(parser, handler)

integer

분석되지 않은 엔티티 선어 핸들러를 등록한다.



[ xml_parser_create() ]

XML 파서 컨텍스트를 만든다.

int xml_parser_create(string [encoding_parameter]);

encoding_parameter : 파서가 사용할 문자 소스 암호화. 일단 설정된 소스 암호화는 나중에 변경할 수 없다. 가능한 값으로는 ISO-8859-1(default) , US-ASCII, UTF-8



[ xml_set_element_handler()]

"start()"와 “end()"ㅅ구성 요소 핸들러 함수들을 XML 파서에 등록한다.

int xml_set_element_handler( int parser, string startElementHandler , string endElementHandler);

parser : XML 파서의 핸들러. 시작과 끝 구성 요소 핸들러들이 등록되어있다.

startElementHandler : 시작 구성 요소 핸들러 함수의 이름. 만약 null이 지정되면 시작 구성 요소 핸들러가 등록되지 않은 것이다.

endElementHandler : 끝 구성 요소 핸들러 함수의 이름. 만약 null이 지정되면 끝 구성 요소 핸들러가 등록되지 않는다.


< satartElementHandler(int parser, string name, string attribs[]); >

parser : 이함수를 호출하고 있는 XML 파서에 대한 참조

name : 구성 요소의 이름

attribs() : 구성 요소의 속성들을 포함하고 있는 조합배열


< endElementHandler(int parser, string name); >

parser : 이 함수를 호출하고 있는 XML 파서로의 참조

name 구성요소 이름



[ xml_set_character_data_handler() ]

XML 파서에 문자 데이터 핸들러를 등록한다.

int xml_set_character_data_handler( int parser, string characterDataHandler);

parser : 문자 데이터 핸들러가 등록된 XML 파서를 위한 핸들

characterDataHandler : 문자 데이터 핸들러 함수의 이름. 만약 null이 지정되면 문자 데이터 핸들러가 등록되지 않는다.


< characterDataHandler( int parser, string data); >

parser : 이 함수를 호출 중인 XML 파서로의 참조

data : XML 문서에 제공되는 문자 데이터. 파서는 문자 데이터를 이TSms 그대로 리턴하며, 어떠한 공백 문자도 제거하지 않는다.



[ xml_parse() ]

XML 문서의 컨텐츠를 파서로 전달한다. 이 함수는 문서의 실제 분석을 수행한다(XML 문서에서 노드들을 만나면 등록된 적당한 핸들러들을 호출한다.).

이 함수는 XML 문서에 있는 다양한 노드 타입들에 대한 핸들러 함수들이 모두 파서에 등록된 후에 호출된다.

int xml_parse( int parser, string data, int [isFinal]);

parser : 제공된 데이터를 분석할 XML 파서의 핸들

data : XML 문서의 컨텐츠. XML 파일의 전체 컨텐츠는 한 번의 호출로 전달될 필요는 없다.

isFinal : 입력 데이터의 끝을 지정한다.

전달된 데이터의 분석이 가능하면 true를 리턴하고, 그렇지 않으면 false를 리턴한다. 실패이 경우 , 오류정보는 xml_get_error_code()와 xml_get_error_string()함수를 이용하여 발견 할 수 있다.



[ xml_get_error_code ]

XML 파서로부터 오류 코드를 리턴한다.

int xml_get_error_code( int parser);

parser : XML 파서으 핸들

분석에 실패하거나 유호한 XML파서가 아닐 경우 flase를 리턴한다.



[ xml_error_string ]

오류 코드에 따라 오류 메시지를 리턴한다.

string xml_get_error_code( int errorCode);

ErrorCode : xml_get_error_code() 함수가 리턴한 오류 코드





[ 예제 ]


<?
class RSSParser {
 var $feed_info = array();
 var $feed_articles = array();
 var $inchannel = FALSE;
 var $initem = FALSE;
 var $inimage = FALSE;
 var $current_item = array();
 var $current_el = FALSE;

 // 여는 태그 처리
 function startElement($parser, $name, $attrs)
 {
  $el = strtoupper($name);

  if ($el == 'RSS') {
   return;
  } else if ($el == 'CHANNEL') {
   $this->inchannel = TRUE;
  } else if ($el == 'ITEM') {
   $this->initem = TRUE;
  } else if ($el == 'IMAGE') {
   $this->inimage = TRUE;
  } else {
   $this->current_el = $el;
  }
 }

 // 닫는 태그 처리
 function endElement($parser, $name)
 {
  $el = strtoupper($name);

  if ($el == 'RSS') {
   return;
  } else if ($el == 'CHANNEL') {
   $this->inchannel = FALSE;
  } else if ($el == 'ITEM') {
   $this->feed_articles[] = $this->current_item;
   $this->current_item = array();
   $this->initem = FALSE;
  } else if ($el == 'IMAGE') {
   $this->inimage = FALSE;
  } else {
   $this->current_el = FALSE;
  }
 }

 // 태그 사이의 데이터 처리
 function characterData($parser, $data)
 {
  if ($this->initem) {
   if ($this->current_el) {
    $this->current_item[$this->current_el] .= $data;
   }
  } else if ($this->inimage) {
  } else if ($this->inchannel) {
   if ($this->current_el) {
    $this->feed_info[$this->current_el] .= $data;
   }
  }
 }
}

function parse_save_rss($document)
{
 // RSS 피드의 인코딩을 UTF-8에 맞춤
 if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/m', $document, $m)) {
  $in_enc = strtoupper($m[1]);
  if ($in_enc != 'UTF-8') {
   $document = preg_replace('/(<?xml.*encoding=[\'"])(.*?)([\'"].*?>)/m', '$1UTF-8$3', $document);
   $document = iconv($in_enc, 'UTF-8', $document);
  }
 }

 // XML 및 RSS 분석기 생성
 $xml_parser = xml_parser_create('UTF-8');
 $rss_parser = new RSSParser();

 xml_set_object($xml_parser, $rss_parser);
 xml_set_element_handler($xml_parser, "startElement", "endElement");
 xml_set_character_data_handler($xml_parser, "characterData");

 if (!xml_parse($xml_parser, $document, true)) {
  printf("XML error: %s at line %d\n",
    xml_error_string(xml_get_error_code($xml_parser)),
    xml_get_current_line_number($xml_parser));
 } else {
  // 분석결과를 DB에 저장
  $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password') or die('Could not connect: '.mysql_error());
  mysql_select_db('my_database') or die('Could not select database');

  foreach ($rss_parser->feed_articles as $article) {
   $published = date('Y-m-d H:i:s', strtotime($article['PUBDATE']));

   $query = sprintf("INSERT INTO feed_articles (source, title, link, description, published) VALUES ('%s', '%s', '%s', '%s', '%s')",
       mysql_real_escape_string($rss_parser->feed_info['TITLE']),
       mysql_real_escape_string($article['TITLE']),
       mysql_real_escape_string($article['LINK']),
       mysql_real_escape_string($article['DESCRIPTION']),
       $published);
   if (mysql_query($query, $link)) echo $query."\n";
  }
 }

 xml_parser_free($xml_parser);
}

// 읽어올 피드 목록
$feed_urls = array(
  'http://blog.rss.naver.com/kickthebaby.xml',
  'http://srlog.egloos.com/index.xml',
  'http://feeds.feedburner.com/tapestrydilbert'
  );

foreach ($feed_urls as $url) {
 $handle = fopen($url, 'r');
 if ($handle) {
  $document = '';
  while (!feof($handle)) {
   $document .= fgets($handle, 4096);
  }
  echo $url."\n";
  // 읽어온 피드를 분석하여 DB에 저장
  parse_save_rss($document);
  fclose($handle);
 }
}
?>

Posted by 1010
반응형

Parser 와 DOM 기초

  • Parser
    • XML 문서를 읽고 해석 : well-formed, valid 검사
    • 응용 개발시 파서 사용 이유 : 세부적인 XML 문법으로부터 프로그램 격리
         XML 문서 --> [파서] -->인터페이스--> [응용 프로그램]
    • 파서가 메모리에 DOM 트리를 생성 : XML 문서트리와 일치
  • 표준 API
    • DOM : 객체 기반 (Object-based) Interface
      - 메모리 상주 트리 이용, 응용에서 간단히 사용, p.208
    • SAX : 이벤트 기반 (Event-driven) Interface
      - 파서가 간단, 응용프로그램은 복잡
  • DOM 개요
    • 문서내 객체(element)를 조작하기 위한 인터페이스(API)
      -
      DOM level 1 : ’98.10 W3C Recommendation
      - DOM level 2 : 2000.11 W3C Recommendation
      - DOM level 3 : 2001.8 W3C Working Draft
    • 문서 전체가 아닌 문서 일부분에 대한 접근 가능
    • 대상 문서 : XML1.0 또는 HTML4.0
  • DOM의 역할
    • 구조의 탐색 : 각 요소와 속성에 대한 탐색/질의가 가능
    • 문서 구조의 조작 : 문서 구조에서 요소, 속성의 추가/수정/삭제가 가능
    • 컨텐츠의 조작 : 문서 요소에서 text 등 컨텐츠의 탐색/추가/수정/삭제가 가능

Document 객체

  • DOMDocument 객체 생성 및 읽기
    • Msxml2.DOMDocument 객체
    • async 속성, load 메쏘드, xml 속성
    MSXML 파서 설치할 경우   MSXML 파서 설치안한 경우  
    <HTML>
    <HEAD>
    <Script language="Javascript">
    function xload0()
    {
        var xmldoc = new
            ActiveXObject("Msxml2.DOMDocument");
        xmldoc.async = false;    xmldoc.load("ex07a.xml");
        alert(xmldoc.xml);
    }
    </script>
    </HEAD>
    <BODY>
    <input type="button" value="XML 로드0"
        onClick="xload0()">
    </BODY>
    </HTML>
     
    111<HTML>
    <HEAD>
    <Script language="Javascript">
    function xload1()
    {
        xmldoc.async = false;
        xmldoc.load("ex07a.xml");

        alert(xmldoc.xml);
    }
    </script>
    </HEAD>
    <BODY>
    <input type="button" value="XML 로드1"
        onClick="xload1()">
    <xml id="xmldoc"></xml>
    </BODY>
    </HTML>
    VBScript 의 경우
    <Script language="VbScript">
      Dim xmldoc
      Set xmldoc = CreateObject("Msxml2.DOMDocument")
      xmldoc.async = False;
      xmldoc.load("ex07a.xml");
      MsgBox xmldoc.xml
    </Script>
  • 신규 문서 작성 : loadXML 메쏘드
     xmldoc.async = false;
     xmldoc.loadXML( "<book><title>XML 입문</title><author>일지매</author></book>");
     alert(xmldoc.xml);
     
     xmldoc.async = false;
     xmldoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>");
     alert(xmldoc.xml);
     
  • 공백의 처리 : preserveWhiteSpace 속성
     xmldoc.async = false;
     xmldoc.preserveWhiteSpace = true;
     xmldoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>");
     alert(xmldoc.xml);
     
     xmldoc.async = false;
     xmldoc.preserveWhiteSpace = true;
     xmldoc.load("ex07a.xml");
     alert(xmldoc.xml);
     
  • XML 문서의 저장 : save 메쏘드
  • 에러 처리 : parseError, parseError.line, parseError.linepos, parseError.reason
     xmldoc.async = false;
     xmldoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </authors> </book>");
     alert(xmldoc.xml);
     
     xmldoc.async = false;
     xmldoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </authors> </book>");
     if (xmldoc.parseError)
        alert("에러 위치 : " + xmldoc.parseError.line + "번째 라인 " + xmldoc.parseError.linepos 
                  + "번째 문자\n\n에러 이유 : " + xmldoc.parseError.reason);
     else
    alert(xmldoc.xml);
     
  • 루트 노드 찾기 : documentElement 속성
     xmldoc.async = false;
     xmldoc.load("ex07a.xml");
     var xmlroot = xmldoc.documentElement;
     alert(xmlroot.nodeName);
     
     xmldoc.async = false;
     xmldoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>");

     var xmlroot = xmldoc.documentElement;
     alert(xmlroot.nodeName);

     
  • 임의의 노드 찾기 : getElementsByTagName("tagName")
  • 노드의 추가 메쏘드 : 뒤에 설명
    • createElement(name), createTextNode(data), createAttribute(name), createComment(data), createProcessingInstruction(target,data), createCDATASection(data), createEntityReference(name)

Node 객체

  • nodeName, nodeType, nodeValue, attributes, text 속성
    • nodeType = 1(element), 2(attribute), 3(text) , 4(CDATA), ...  : 표7.1 [p.215]
     xmldoc.load("ex07a.xml");
     var xmlroot = xmldoc.documentElement;
     alert('nodeName: '+xmlroot.nodeName+'\nnodeType: '+xmlroot.nodeType+
           '\nnodeValue: '+xmlroot.nodeValue+'\nattributes: '+xmlroot.attributes.length);
     alert(xmlroot.text);
     
  • Node의 운행(Traversal) 관련 속성
    • 관련속성
                                  -- previousSibling 
      ...  parentNode  -- **현재노드**    --  childNodes [ firstChild, … , lastChild ]
                                  -- nextSibling 
    • hasChildNodes() 메쏘드
  • NodeList 객체
    • length 속성, item(번호) 메쏘드
     xmldoc.load("ex07a.xml");
     var xmlroot = xmldoc.documentElement;
     if (xmlroot.hasChildNodes) {
         alert(xmlroot.childNodes.length);
         var curr = xmlroot.firstChild;
         alert(curr.xml);
         alert(curr.nodeName + curr.nodeType
          +curr.nodeValue+curr.attributes.length);
     }
     else alert('No Child');
     
     xmldoc.load("ex07a.xml");
     var xmlroot = xmldoc.documentElement;
     var curr = xmlroot.firstChild.nextSibling;
     alert(curr.xml);
     curr = curr.childNodes.item(2);
     alert(curr.xml);
     curr = curr.previousSibling;
     alert(curr.text);
     alert(curr.nodeName + curr.nodeType
          +curr.nodeValue+curr.attributes.length);
     
  • NamedNodeMap 객체 
    • getNamedItem("속성명"), setNamedItem(), removeNamedItem() 메쏘드
  • Attribute 객체 
    • name, value, specified 속성
     xmldoc.load("ex07a.xml");
     var attrs = xmlroot.firstChild.attributes;
     var attr0 = attrs.getNamedItem("InStock");
     alert(attr0.name + attr0.value + attr0.specified); 
  • 노드의 추가/삭제/수정 메쏘드 : 뒤에 설명
    • appendChild(child), insertBefore(child,before), removeChild(child),
      replaceChild(child,toReplace), cloneNode(deep)

임의 노드의 검색

  • 그 이름으로 검색
    • 노드리스트 = 문서.getElementsByTagName("tagName");
     xmldoc.load("ex07a.xml");
     var nlist =
       xmldoc.
    getElementsByTagName("book");
     for (i=0; i<nlist.length; i++)
            alert(nlist.item(i).xml);
     
     xmldoc.load("ex07a.xml");
     var nlist =
        xmldoc.
    getElementsByTagName("title");
     for (i=0; i<nlist.length; i++)
            alert(nlist.item(i).xml);
     
  • 패턴으로 검색
    • 노드리스트 = 노드.selectNode("query");
    • 노드 = 노드.selectSingleNode("query");
     xmldoc.load("ex07a.xml");
     var xroot = xmldoc.documentElement;
     var node1 = xroot.selectSingleNode("title");
     alert(node1.text);
     var tlist = xroot.selectNodes('//title');
     var alist = xroot.selectNodes('//author');
     for (i=0; i<alist.length; i++)  
        alert('['+i+'] '+alist.item(i).text+', '
               +tlist.item(i).text);

     
     xmldoc.load("ex07a.xml");
     var xroot = xmldoc.documentElement;
     var node1 = xroot.
        selectSingleNode
    ('//book[@InStock=0]');
     alert(node1.xml+'\n=> 재고가 없습니다.');
     var tlist = xroot.
        selectNodes
    ('//book[@InStock!=0]/title');
     for (i=0; i<tlist.length; i++)
        alert(tlist.item(i).text+'\n=>재고 있음.');

     

 

펌 -  http://mm.sookmyung.ac.kr/~sblim/lec/xml-int02/

MSDN - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/dom_reference.asp

Posted by 1010
카테고리 없음2009. 1. 23. 14:17
반응형
Apache AXIS 설치


기존에 썼던 글을 apache에 있는 영문글을영문글을 읽으면서 설치하느라...
고생이 심했다 ^^;;
결국 안되서;;; 다시 해본다 ㅠㅠ
글은  
http://ws.apache.org/axis/java/install.html 여기를 바탕으로
이번에는 그냥 다른 설명없이 설치설치 방법과 오류시 해결 방법 위주로 글을 쓰겠다..
필요한 부분은 copy andand paste로 해결

1. Apache Tomcat 4.1이상 필요(Full version설치 권장)
이런것까지는 설명 안 해도 되겠죠....

2.2. JDK 1.4이상 버전 설치 및 환경설정
설치 후 JAVA 환경환경 설정 -> 링크 참조
JAVA 환경 설정

3.3. AXIS 다운로드 및 압축 해제
http://ftp.kaist.ac.kr/pub/Apache/ws/axis/1_4/ 에서 axis-bin-1_4.zip   받아서 압축해제

참고로 나는 C:\DD4.1.7\Installation\axis-1_4 에 압축을 풀었다.
(이따가 환경 설정할 때 axis를 압축해제 곳의 위치가 중요하다.)

4. xml-xerces 다운 로드

In the Axis directory, you will find a WEB-INF sub-directory. This directory contains some basic configuration information, but can also be used to contain the dependencies and web services you wish to deploy.

Axis needs to be able to find an XML parser. If your application server or Java runtime does not make one visible to web applications, you need to download and add it. Java 1.4 includes the Crimson parser, so you can omit this stage, though the Axis team prefer Xerces.

To add an XML parser, acquire the JAXP 1.1 XML compliant parser of your choice. We recommend Xerces jars from the xml-xerces distribution, though others mostly work. Unless your JRE or app server has its own specific requirements, you can add the parser's libraries to axis/WEB-INF/lib.  The examples in this guide use Xerces.  This guide adds xml-apis.jar and xercesImpl.jar to the AXISCLASSPATH so that Axis can find the parser (see below).

If you get ClassNotFound errors relating to Xerces or DOM then you do not have an XML parser installed, or your CLASSPATH (or AXISCLASSPATH) variables are not correctly configured.


http://xml.apache.org/dist/xerces-j/
에서 Xerces-J-bin.2.9.1.zip   받아서 압축해제 후
( 참고로 나는 C:\DD4.1.7\Installation\xerces-2_9_1 압축을 풀었다. )

C:\DD4.1.7\Installation\xerces-2_9_1 디렉토리 안에 있는 xercesImpl.jar 파일과 xml-apis.jar 파일을 copy해서 C:\DD4.1.7\Installation\axis-1_4\webapps\axis\WEB-INF\lib와 CC :\DD4.1.7\Installation\axis-1_4\lib 디렉토리에 복사한다.

C:\DD4.1.7\Installation\axis-1_4\lib디렉토리에 2개의 파일을 복사해주는 이유는 5번에서 AXIS 환경변수를 설정하는데 위에 2개의 파일이 C:\DD4.1.7\Installation\axis-1_4\lib 디렉토리에 있어야 하는 듯하다... 후덜덜;;

5. AXIS 환경설정

Classpath setup

In order for these examples to work, java must be able to find axis.jar, commons-discovery.jar, commons-logging.jar, jaxrpc.jar, saaj.jar, log4j-1.2.8.jar (or whatever is appropriate for your chosen logging implementation), and the XML parser jar file or files (e.g., xerces.jar). These examples do this by adding these files to AXISCLASSPATH and then specifying the AXISCLASSPATH when you run them. Also for these examples, we have copied the xml-apis.jar and xercesImpl.jar files into the AXIS_LIB directory. An alternative would be to add your XML parser's jar file directly to the AXISCLASSPATH variable or to add all these files to your CLASSPATH variable.

On Windows, this can be done via the following. For this document we assume that you have installed Axis in C:\axis. To store this information permanently in WinNT/2000/XP you will need to right click on "My Computer" and select "Properties". Click the "Advanced" tab and create the new environmental variables. It is often better to use WordPad to create the variable string and then paste it into the appropriate text field.

<PRE class=code>set AXIS_HOME=c:\axisset AXIS_LIB=%AXIS_HOME%\libset AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar; %AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar</PRE>

Unix users have to do something similar. Below we have installed AXIS into /usr/axis and are using the bash shell. See your shell's documentation for differences. To make variables permeate you will need to add them to your shell's startup (dot) files. Again, see your shell's documentation.

<PRE class=code>set AXIS_HOME=/usr/axisset AXIS_LIB=$AXIS_HOME/libset AXISCLASSPATH=$AXIS_LIB/axis.jar:$AXIS_LIB/commons-discovery.jar: $AXIS_LIB/commons-logging.jar:$AXIS_LIB/jaxrpc.jar:$AXIS_LIB/saaj.jar: $AXIS_LIB/log4j-1.2.8.jar:$AXIS_LIB/xml-apis.jar:$AXIS_LIB/xercesImpl.jarexport AXIS_HOME; export AXIS_LIB; export AXISCLASSPATH</PRE>

To use Axis client code, you can select AXISCLASSPATH when invoking Java by entering

<PRE class=code>java -cp %AXISCLASSPATH% ...</PRE>

or

<PRE class=code>java -cp "$AXISCLASSPATH" ...</PRE>

depending on the platform. You may omit the quotes if your CLASSPATH doesn't have spaces in it.

Also, it is probably a good time to add the AXISCLASSPATH variable to your CLASSPATH variable. This will enable you to not include the AXISCLASSPATH variable when launching the examples in this guide. This document assumes that you have NOT done this.


환경 설정 방법은 위에 JAVA환경 설정(2번 과정)에서과정)에서 해 봤으므로 다른 설명은 안 하겠다.

AXIS_HOME = C:\DD4.1.7\Installation\axis-1_4
AXIS_LIBAXIS_LIB = %AXIS_HOME%\lib
AXISCLASSPATH = =%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar;
  %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;
  %AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

Note:Note: 위 설정에 있는 commons-discovery.jar은 3번에서 다운 받은 commons-discovery랑 이름이 다를것이다.. 무슨 이야기 인지 알겠죠?? ㅎ

6. AXIS를 Tomcat과 연동하기
연동하는 것은 그냥 어렵지 않다.

C:\DD4.1.7\Installation\axis-1_4\webapps\axis
C:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps에 복사해주면 된다.

즉 axis-1_4디렉토리 안에 webapps안에 있는 axis디렉토리를 Tomcat 5.5디렉토리 안에 있는 webapps에 복사해서 넣어주면 된다.

Result:
C:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps\axis


설치에 관한 모든 설정은 다 ...끝났다... 기타 필요한 것들은 따로 알아서 설치하도록 한다..

7. AXIS 테스트 해보기
tomcat을 실행한 후
http://localhost:8080/axis/index.jsp 을 해보자.
Note - 가끔 apache와 tomcat을 같은 것으로 아시는 분이 있는데( 참고로, 나도 그랬음 ^^;; )
다음 링크를 통해서 다시 한번 공부해 보자!! 공부해서 남 주니?? ^^
Apache와 Tomcat

일단 다음과다음과 같은 그림이 나오면 잘 된거 같다만.... 확인해 볼게 있다...
사용자
Validation - 설치 설정이 잘 되어 있는지 검사하는 것 같다.
Administer Axis와 SOAPMonitor은 따로 활성화를 해 주어야 한다.

'Validation'을 클릭해보자...
다음과 같은 그림이 보이면;;; 대략 난감하다;;;
이게 잘못 설치 된건지 아닌지 아직은 모르겠는데;; 뭔가 안된거 같다;;

사용자

다음 글을 읽어보자...

Validate Axis with happyaxis

Follow the link Validate the local installation's configuration
This will bring you to happyaxis.jsp a test page that verifies that needed and optional libraries are present. The URL for this will be something like
http://localhost:8080/axis/happyaxis.jsp

If any of the needed libraries are missing, Axis will not work.
You must not proceed until all needed libraries can be found, and this validation page is happy.
Optional components are optional; install them as your need arises. If you see nothing but an internal server error and an exception trace, then you probably have multiple XML parsers on the CLASSPATH (or AXISCLASSPATH), and this is causing version confusion. Eliminate the extra parsers, restart the app server and try again.


이런 젠장;; 제대로 안되었다는 이야기 같다;;
하핫;; 생각해보니까 나는 AXIS 환경 변수 설정을 안 했다;;;
뭐니;;; 이래서 뭐 알려주겠다고;;;

환경변수를 설정해줘도 안된다;;;
뭐가 필요한거지;;

일단 패스 하자...
나중에 해결해봅시다 ^^)b

이번에는 'Call'을 클릭해보자.

만약에 'tool.jar'파일이 필요하다고 하면은 해결 방법으로는 2가지가 있다.
1. C:\Program Files\Java\jdk1.5.0_13\lib 에 있는 tools.jar 파일을 C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\lib 에 복사해 둔다.

2. Tomcat configure에서 Java 탭으로 가서 Java Virtual Machine를 바꾸어주자.
기본적으로 Tomcat은 jre에 있는 jvm.dll을 이용하기 때문에 tools.jar이 필요한다.
C:\Program Files\Java\jdk1.5.0_13\jre\bin\client\jvm.dllFiles\Java\jdk1.5.0_13\jre\bin\client\jvm.dll

뭐 기본적인 설치는 다 끝난것 같다..
Posted by 1010
반응형
 

Xerces-J contains many useful samples to help you get up-and-running with writing XML applications. Many of the sample programs are even useful as standalone programs to help in testing the validity of XML documents and/or debugging applications.

The samples are organized either by API or by programming area in the following categories:

Posted by 1010
반응형
he XML parser world is a dynamic one. As standards change, the parsers change as well--XML parsers are becoming more sophisticated. For most programming projects, the parser, at minimum, must support DOM Level 2, SAX 2, XSLT, and Namespaces. All the parsers discussed here provide these capabilities; however, there are distinct differences in performance, reliability, and conformance to standards. In this article, I'll compare the latest parsers from Sun, Oracle, and the Apache Software Foundation.

Apache parser
The Apache parser version 1.2.3 (commonly known as Xerces) is an open-source effort based on IBM's XML4J parser. Xerces has full support for the W3C Document Object Model (DOM) Level 1 and the Simple API for XML (SAX) 1.0 and 2.0; however it currently has only limited support for XML Schemas, DOM Level 2 (version 1). Add the xerces.jar file to your CLASSPATH to use the parser. You can use Xalan, also available from Apache's Web site, for XSLT processing. You can configure both the DOM and SAX parsers. Xerces uses the SAX2 method getFeature() and setFeature() to query and set various parser features. For example, to create a validating DOM parser instance, you would write:

DOMParser domp = new DOMParser();
   try {
      domp.setFeature ("http://xml.org/dom/features/validation", true);
   } catch (SAXExcepton ex) {
      System.out.println(ex);
   }
Other modifiable features include support for Schemas and namespaces.

The following example shows a minimal program that counts the number of <servlet> tags in an XML file using the DOM. The second import line specifically refers to the Xerces parser. The main method creates a new DOMParser instance and then invokes its parse() method. If the parse operation succeeds, you can retrieve a Document object through which you can access and manipulate the DOM tree using standard DOM API calls. This simple example retrieves the "servlet" nodes and prints out the number of nodes retrieved.

import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;

public class DOM
{
    public static void main(String[] args) 
    {

        try {
            DOMParser parser = new DOMParser();
            parser.parse(args[0]);
            Document doc = parser.getDocument();

            NodeList nodes = doc.getElementsByTagName("servlet");
            System.out.println("There are " + nodes.getLength() + 
               " elements."); } catch (Exception ex) { System.out.println(ex); } } }

You can use SAX to accomplish the same task. SAX is event-oriented. In the following example, inherits from DefaultHandler, which has default implementations for all the SAX event handlers, and overrides two methods: startElement() and endDocument(). The parser calls the startElement() method each time it encounters a new element in the XML file. In the overridden startElement method, the code checks for the "servlet" tag, and increments the tagCounter counter variable.. When the parser reaches the end of the XML file, it calls the endDocument() method. The code prints out the counter variable at that point. Set the ContentHandler and the ErrorHandler properties of the the SAXParser() instance in the main() method , and then use the parse() method to start the actual parsing.

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;

public class SAX extends DefaultHandler
{    
      int tagCount = 0;

      public void startElement(String uri, String localName,
         String rawName, Attributes attributes)
      {
            if (rawName.equals("servlet")) {
               tagCount++;
            }
      }

      public void endDocument()
      {
            System.out.println("There are " + tagCount +
                " <servlet> elements.");
      }

      public static void main(String[] args)
      {
            try {
                  SAX SAXHandler = new SAX();

                  SAXParser parser = new SAXParser();
                  parser.setContentHandler(SAXHandler);
                  parser.setErrorHandler(SAXHandler);
                  parser.parse(args[0]);
            }
                  catch (Exception ex) {
                        System.out.println(ex);
                  }
      }
}

With Xerces installed and your CLASSPATH set, you can compile and run the above programs as follows:

javac DOM.java
javac SAX.java
C:\xml\code>java DOM web.xml
There are 6 <servlet> elements.
C:\xml\code>java SAX web.xml
There are 6 <servlet> elements.
Posted by 1010
반응형
============= common.jsp =============================

<%@ page contentType="text/html;charset=EUC-KR" %>
<% request.setCharacterEncoding("euc-kr"); %>
<%@ page import="java.util.*" %>
<%@ page import="java.net.*" %>
<%@ page import="javax.xml.parsers.*" %>
<%@ page import="org.w3c.dom.*" %>


<%!

 final String G_ROOT_URL="http://locahost:6973/test.cgi?";

 final String strVal(String str){
  if(str == null) str = "";
  return str.trim();
 }

 class T_DOC{
  String id;
  String sim;
  HashMap<String,String> hm_item=new HashMap<String,String>();
 }


 class SrchInfo{


  StringBuffer m_URL=new StringBuffer();
 
  SrchInfo(){
   m_URL.append(G_ROOT_URL);
  }
 
  public void SetQRY(String p_name,String p_value){
   m_URL.append(p_name + "=" + p_value + "&");
  }

  //  헤더 정보 변수
  String m_section_name;
  String m_usrspec;
  String m_idxname;
  String m_qryflag;
  String m_srtflag;
  String m_totcnt;
  String m_maxcnt;
  String m_outcnt;
  String m_pagenum;
 
  // 결과 정보
  ArrayList<T_DOC> m_DOCS=new ArrayList<T_DOC>();


  private DocumentBuilderFactory docBuilderFactory;

  private DocumentBuilder docBuilder;

  private Document doc;
  private NodeList nodeDOC;
 
  public void GetData(){

   try{
   
 // DocumentBuilderFactory 의 객체 생성
 DocumentBuilderFactory docBuilderFactory=DocumentBuilderFactory.newInstance();
 // factory로부터 DocumentBuilder 를 얻어온다.
 DocumentBuilder docBuilder=docBuilderFactory.newDocumentBuilder();

   // XML 문서로부터 DOM 객체를 만들어서 문서(Document) 로 반환 받는다.
   //System.out.println(p_xmlfile);
   
   Document doc=docBuilder.parse(m_URL.toString());
   
   //메타 정보 추출
   nodeDOC=doc.getElementsByTagName("section");
   
  m_section_name=nodeDOC.item(0).getAttributes().getNamedItem("name").getNodeValue();
 
  m_usrspec=nodeDOC.item(0).getChildNodes().item(1).getFirstChild().getNodeValue();
  m_idxname=nodeDOC.item(0).getChildNodes().item(3).getFirstChild().getNodeValue();
  m_qryflag=nodeDOC.item(0).getChildNodes().item(5).getFirstChild().getNodeValue();
  m_srtflag=nodeDOC.item(0).getChildNodes().item(7).getFirstChild().getNodeValue();
  m_totcnt=nodeDOC.item(0).getChildNodes().item(9).getFirstChild().getNodeValue();
  m_maxcnt=nodeDOC.item(0).getChildNodes().item(11).getFirstChild().getNodeValue();
  m_outcnt=nodeDOC.item(0).getChildNodes().item(13).getFirstChild().getNodeValue();
m_pagenum=nodeDOC.item(0).getChildNodes().item(15).getFirstChild().getNodeValue();
   
   
   int count=Integer.parseInt(m_outcnt);
   
   for ( int i=0 , idx=19; i < count ; i++ , idx+=2 ){
   
    T_DOC tmp_doc=new T_DOC();
   
tmp_doc.id=nodeDOC.item(0).getChildNodes().item(idx).getAttributes().getNamedItem("id").getNodeValue();
tmp_doc.sim=nodeDOC.item(0).getChildNodes().item(idx).getAttributes().getNamedItem("sim").getNodeValue();
 
    int child_cnt=nodeDOC.item(0).getChildNodes().item(idx).getChildNodes().getLength();
     
    for ( int j = 1 ; j < child_cnt ; j+=2 ) {
     
 String tag=nodeDOC.item(0).getChildNodes().item(idx).getChildNodes().item(j).getAttributes().getNamedItem("name").getNodeValue();
 String value=nodeDOC.item(0).getChildNodes().item(idx).getChildNodes().item(j).getFirstChild().getNodeValue();
     tmp_doc.hm_item.put(tag,value);
    }
   
    m_DOCS.add(tmp_doc);
   }
   
    }catch(java.lang.Exception e) {

               System.err.println("==GetData()]"+ e.toString());
               e.printStackTrace(System.out);
              // System.exit(-1);
       }
  }// end of  GetHeader
 
  public void GetResults(){

  }

}//end of class

%>


==================== index.jsp ===========================================

실제 사용 샘플 페이지
 
<%--   xml parse fs 2008 07 --%>
<%@ page contentType="text/html;charset=EUC-KR" %>
<% request.setCharacterEncoding("euc-kr"); %>
<%@ include file="common.jsp" %>

<%
 SrchInfo OB_SrchInfo=new SrchInfo();

 OB_SrchInfo.SetQRY("w","test");

 String qry=strVal(request.getParameter("qry"));
 
 if( qry.length() == 0 ) qry="*";


 OB_SrchInfo.SetQRY("q",URLEncoder.encode(qry));

 //  xml 파서 시작
 OB_SrchInfo.GetData();

 out.println("<xmp> "  + OB_SrchInfo.m_URL + "</xmp>" );

%>

 <HEAD>

 <TITLE>XML JAVA 파서 샘플 페이지</TITLE>

 </HEAD>

 <BODY>
 <P>
 <table>
 <form name=form action=index.jsp method=get>
  검색어:<input type=text name=qry value=<%= qry %>>
  <input type=submit value="검색">
 </form>

 </table>
 <검색 결과 헤더 정보> : <br>
  &nbsp;&nbsp;- 전체건수: <%= OB_SrchInfo.m_totcnt %> <br>
  &nbsp;&nbsp;- 요청건수(outmax값): <%= OB_SrchInfo.m_maxcnt %> <br>
  &nbsp;&nbsp;- 출력건수: <%= OB_SrchInfo.m_outcnt %> <br>
  &nbsp;&nbsp;- 출력페이지번호: <%= OB_SrchInfo.m_pagenum %> <br>

 <p>
 <검색 결과 데이터> :
 <p>

<%
 
 for(int i=0; i < OB_SrchInfo.m_DOCS.size() ; i++){
 
  T_DOC RESULT=OB_SrchInfo.m_DOCS.get(i);
 
  out.println( "DOC ID : " +  RESULT.id  + "<br>");
  out.println( "DOC SIM : " + RESULT.sim + "<br>");
  out.println( "제목 : " + RESULT.hm_item.get("TITLE=") + "<br>");
  out.println( "내용 : " + RESULT.hm_item.get("ARTICLE=") + "<p>");

 }
%>


실제 활용예 소스는 아니지만 좀 아는 사람이라면
실무에 패키지해서 유용하게 사용할수도 있을것이다~~
2008 07 fs

Posted by 1010
반응형

<html>
<head>
<script type="text/javascript">
function parseXML()
{
text="<note>";
text=text+"<to>Tove</to>";
text=text+"<from>Jani</from>";
text=text+"<heading>Reminder</heading>";
text=text+"<body>Don't forget me this weekend!</body>";
text=text+"</note>";
try //Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async="false";
  xmlDoc.loadXML(text);
  }
catch(e)
  {
  try //Firefox, Mozilla, Opera, etc.
  {
  parser=new DOMParser();
  xmlDoc=parser.parseFromString(text,"text/xml");
  }
  catch(e)
  {
  alert(e.message);
  return;
  }
}
document.getElementById("to").innerHTML=xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue;
document.getElementById("from").innerHTML=xmlDoc.getElementsByTagName("from")[0].childNodes[0].nodeValue;
document.getElementById("message").innerHTML=xmlDoc.getElementsByTagName("body")[0].childNodes[0].nodeValue;
}
</script>
</head>

<body onload="parseXML()">
<h1>W3Schools Internal Note</h1>
<p><b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span>
</p>
</body>
</html>


Posted by 1010
반응형

<html>
<head>
<script type="text/javascript">
function parseXML()
{
try //Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  }
catch(e)
  {
  try //Firefox, Mozilla, Opera, etc.
    {
    xmlDoc=document.implementation.createDocument("","",null);
    }
  catch(e)
    {
    alert(e.message);
    return;
    }
  }
xmlDoc.async=false;
xmlDoc.load("note.xml");
document.getElementById("to").innerHTML=xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue;
document.getElementById("from").innerHTML=xmlDoc.getElementsByTagName("from")[0].childNodes[0].nodeValue;
document.getElementById("message").innerHTML=xmlDoc.getElementsByTagName("body")[0].childNodes[0].nodeValue;
}
</script>
</head>

<body onload="parseXML()">
<h1>W3Schools Internal Note</h1>
<p><b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span>
</p>
</body>
</html>


Posted by 1010
02.Oracle/DataBase2009. 1. 22. 17:38
반응형

1. 날짜함수
 
 1)오라클의 날짜 형식
 
 우선은 날짜 함수를 들어가기전에 오라클의 날짜 형식이 어떻게 구성되나 알아보도록 하겠습니다.
 오라클은 날짜를 아래와 같이 내부적인 숫자 형식으로 관리됩니다.
 
 Centry.year.month.day.hours.minutes.seconds
 
 기본적으로 입력되는 형식 및 display 형식은 ''''DD-MON-YY'''' 이며,
 유효날짜는 January 1,4712 B.C ~ December 31,4712 A.D 사이입니다.
 머 여러분들이 사용하시기엔 무리없는 (^^;) 날짜겠져..
 
 또한 오라클에서는 현재 날짜와 시간을 리턴해주는 날짜 함수가 있습니다.
 아마 앞으로도 자주 사용하시겠지만, SYSDATE 란 함수입니다.
 이함수를 DUAL (저번 강의때 설명했던걸로 기억나는데요, 잘 모르시는 분은 이전강의를 참고해주세요..^^)
 을 사용하면 현재의 날짜를 확인하실 수 있습니다.

 SQL> SELECT SYSDATE FROM DUAL;

 SYSDATE
 --------
 03/11/27
 
 2) 날짜와 숫자의 계산
 위에서 날짜는 숫자 형식으로 관리 된다고 했죠? 그래서 날짜와 날짜끼리
 날짜와 숫자끼리의 연산이 가능합니다.
 그 연산된 결과는 아래와 같습니다.
 
  2-1) 날짜 - 날짜 = 숫자
   날짜에서 날짜를 빼면 그 날짜사이의 일 수가 나옵니다.
   오랜만에 emp table을 함 예로들어볼께요? 
   emp Table의 입사일을 기준으로 사람들이 입사한 기간이 얼마나 되나 함 알아볼까요?
  
   SQL> SELECT ENAME, HIREDATE, SYSDATE - HIREDATE
     2  FROM EMP;
  
   ENAME      HIREDATE SYSDATE-HIREDATE
   ---------- -------- ----------------
   SMITH      80/12/17       8380.01446
   ALLEN      81/02/20       8315.01446
   WARD       81/02/22       8313.01446
   JONES      81/04/02       8274.01446
   MARTIN     81/09/28       8095.01446
   BLAKE      81/05/01       8245.01446
   CLARK      81/06/09       8206.01446
   SCOTT      87/04/19       6066.01446
   KING       81/11/17       8045.01446
   TURNER     81/09/08       8115.01446
   ADAMS      87/05/23       6032.01446
   JAMES      81/12/03       8029.01446
   FORD       81/12/03       8029.01446
   MILLER     82/01/23       7978.01446
  
   위의 결과에서와 같이 SMITH와 같은 경우는 입사한지 현재일 기준으로 8380일이 지났음을 알수 있습니다.
  
  2-2) 날짜 + 날짜 => 에러 발생
   날짜와 날짜끼리는 더하기가 안됩니다.

   SQL> SELECT ENAME, HIREDATE, SYSDATE +  HIREDATE
     2   FROM EMP;
   SELECT ENAME, HIREDATE, SYSDATE +  HIREDATE
                                   *
   1행에 오류:
   ORA-00975: 날짜와 날짜의 가산은 할 수 없습니다
 
  2-3) 날짜 + 숫자 = 날짜
   날짜에 숫자를 더하면 해당 날짜에 숫자만큼의 기간이 더해집니다. (2003/11/27일에 테스트한것입니다.)
  
   SQL> SELECT SYSDATE + 2 FROM DUAL;
  
   SYSDATE+2
   --------
   03/11/29  
 
  2-4) 날짜 - 숫자 = 날짜
   날짜에 숫자를 빼면 해당 숫자만큼의 기간이 빼져서 나오게 됩니다.
   SQL> SELECT SYSDATE + 2 FROM DUAL;

   SYSDATE-2
   --------
   03/11/25
 
 
 
 그러면 본격적으로 날짜 함수에 대해서 들어가 볼까요?

 2) 날짜 함수
  가) ADD_MONTHS : 주어진 일자에 개월 단위의 가감을 원할때 사용합니다.
 
  EMP 테이블에서 SIMTH 직원의 입사일을 가지고 예를 들어보겠습니다.
  입사일을 두달씩 더하고 빼보겠습니다.
 
    1  SELECT ENAME, HIREDATE,
    2         ADD_MONTHS(HIREDATE, 2),
    3         ADD_MONTHS(HIREDATE, -2)
    4  FROM
    5         EMP
    6  WHERE
    7*        ENAME = ''''SMITH''''
  SQL> /
 
  ENAME      HIREDATE ADD_MONT ADD_MONT
  ---------- -------- -------- --------
  SMITH      80/12/17 81/02/17 80/10/17  
   
  결과를 보시면 알지만  SMITH 직원의 입사일은 80년 12월 17일 이지만 ADD_MONTHS 함수를 이용하여 2달을 더하면
  81년 2월 17일 두달을 빼면 80년 10월 17일이 나옴을 확인할 수 있습니다.
 
  나) MONTHS_BETWEEN : 주어진 두개의 일자 간격이 몇 개월인지를 보여줍니다.
 
  EMP 테이블에서 입사일자가 현재 일자로부터 몇개월이 됐는지 알아보겠습니다.
 
   SQL> SELECT ENAME, HIREDATE, SYSDATE, MONTHS_BETWEEN(SYSDATE, HIREDATE)
     2  FROM EMP;
  
   ENAME      HIREDATE SYSDATE  MONTHS_BETWEEN(SYSDATE,HIREDATE)
   ---------- -------- -------- --------------------------------
   SMITH      80/12/17 03/12/10                       275.806019
   ALLEN      81/02/20 03/12/10                       273.709244
   WARD       81/02/22 03/12/10                       273.644728
   JONES      81/04/02 03/12/10                       272.289889
   MARTIN     81/09/28 03/12/10                        266.45118
   BLAKE      81/05/01 03/12/10                       271.322148
   CLARK      81/06/09 03/12/10                       270.064083
   SCOTT      87/04/19 03/12/10                       199.741502
   KING       81/11/17 03/12/10                       264.806019
   TURNER     81/09/08 03/12/10                       267.096341
   ADAMS      87/05/23 03/12/10                        198.61247
  
   ENAME      HIREDATE SYSDATE  MONTHS_BETWEEN(SYSDATE,HIREDATE)
   ---------- -------- -------- --------------------------------
   JAMES      81/12/03 03/12/10                       264.257631
   FORD       81/12/03 03/12/10                       264.257631
   MILLER     82/01/23 03/12/10                        262.61247 
 
  다) LAST_DAY : 주어진 일자가 포함된 월의 말일을 알수 있습니다.
 
  현재날짜를 (2003-12-10) 통해서 월말이 어떻게 되는지 확인해보도록 하겠습니다.
 
  SQL> SELECT SYSDATE, LAST_DAY(SYSDATE) FROM DUAL;
 
  SYSDATE  LAST_DAY
  -------- --------
  03/12/10 03/12/31

  말일이 12월 31일임을 알 수 있습니다.
 
  라) SYSTIMESTAMP : DATABASE의 TIMEZONE을 포함한 시스템 날짜를 보여준다.
 
  SQL> SELECT SYSTIMESTAMP FROM DUAL;

  SYSTIMESTAMP
  ---------------------------------------------------------------------------
  03/12/11 00:07:32.000001 +09:00

  바) NEXT_DAY
    
  SYNTAX : NEXT_DAY (DATE, CHAR)
 
  DATE : 일자
  CHAR : 요일을 말합니다.(월/화/수/목/금/토/일) 위에 월요일 이렇게 해도 상관없습니다.
  이것은 DATABASE의 LANGUAGE 와 관련있습니다.
  지금 제가 테스트 하는 것은 한글로 셋팅되어 있기 때문에 가능한거구여...
  영문으로 셋팅되어 있으면.. MONDAY,TUESDAY.... 머 이렇게 되어야겠져..^^

  NEXT_DAY는 입력한 DATE(일자) 다음 주 입력한 요일의 일자를 보여줍니다.
 
  아래의 예를 보면 12월 10일 다음주 목요일의 날짜를 보여주는 것입니다.
 
  설명하려니 좀 어렵네여..ㅋㅋ 아래의 예를 보면 쉽게 이해되실듯..ㅋㅋ
   
  SQL> SELECT NEXT_DAY(SYSDATE,''''목요일'''') FROM DUAL;

  NEXT_DAY
  --------
  03/12/18
 
2. 변환함수
 : 오라클에서는 문자와 숫자, 문자와 날짜간의 데이터형 변환을 위해 함수를 제공합니다.
   숫자나 날짜가 문자로 변환되는데 필요한 함수가 TO_CHAR 이며,
   문자가 숫자로 변형될때는 TO_NUMBER,
   문자가 일자로 변형될 때 TO_DATE를 사용합니다.
   그럼 예제를 통하여 자세히 알아보겠습니다.
  
   1) TO_CHAR : 날짜를 문자로 바꾸어줍니다.
     
      SYNTAX : TO_CHAR (DATE, FORMAT)
     
      FORMAT은 DATE형을 문자로 바꿀때 쓰이는 변환 형식을 말합니다.
      자주쓰이는 것에 대해서 예와 함께 설명하도록 하겠습니다.
     
  가) YYYY 또는 SYYYY : 년도, S를 지정하면 기원전 년도에 - 가 붙음.
  
  SQL> SELECT TO_CHAR(SYSDATE, ''''YYYY''''), TO_CHAR(SYSDATE, ''''SYYYY'''')
    2  FROM DUAL;
 
  TO_CHAR(SYSDATE, ''''YYYY'''') TO_CHAR(SYSDATE, ''''SYYYY'''')
  ------------------------ ---------------------------
  2003                     2003
 
  나) YYY, YY, Y  : 년의 아래 3자리, 2자리, 1자리를 나타냅니다. 
  SQL> SELECT TO_CHAR(SYSDATE, ''''YYY''''), TO_CHAR(SYSDATE, ''''YY''''), TO_CHAR(SYSDATE, ''''Y'''')
    2  FROM DUAL;
 
  TO_ TO T
  --- -- -
  003 03 3
 
  다) SYEAR, YEAR : 년도를 철자로 나타냅니다.

  SQL> SELECT TO_CHAR(SYSDATE, ''''SYEAR''''), TO_CHAR(SYSDATE, ''''YEAR'''') FROM DUAL;

  TO_CHAR(SYSDATE,''''SYEAR'''')             TO_CHAR(SYSDATE,''''YEAR'''')
  ---------------------------------    ---------------------------------
        TWO THOUSAND THREE                   TWO THOUSAND THREE

  라) Q : 입력일자의 분기를 나타냅니다.
  SQL> SELECT TO_CHAR(SYSDATE, ''''Q'''') FROM DUAL;
 
  T
  -
  4 
 
  마) MM : 월을 나타냅니다.
  SQL> SELECT TO_CHAR(SYSDATE, ''''MM'''') FROM DUAL;
 
  TO
  --
  12 

  바) MONTH, MON : 월의 명칭, 3문자의 단축형을 나타냅니다.
  SQL> SELECT TO_CHAR(SYSDATE, ''''MONTH''''), TO_CHAR(SYSDATE, ''''MON'''') FROM DUAL;
 
  TO_CHAR(S TO_
  --------- ---
  DECEMBER  DEC
 
  사) DDD, DD, D : 년, 월, 주의 몇번째 날인가를 보여줌

  SQL> SELECT TO_CHAR(SYSDATE, ''''DDD''''), TO_CHAR(SYSDATE, ''''DD''''), TO_CHAR(SYSDATE, ''''D'''') FROM DUAL;
 
  TO_ TO T
  --- -- -
  345 11 5
 
  아) DAY, DY : 요일 또는 3문자의 단축형

  SQL> SELECT TO_CHAR(SYSDATE, ''''DAY''''), TO_CHAR(SYSDATE, ''''DY'''') FROM DUAL;
 
  TO_CHA TO
  ------ --
  목요일 목
 
  자) AM, PM : 오전 / 오후를 표시한다.

  SQL> SELECT TO_CHAR(SYSDATE, ''''AM''''), TO_CHAR(SYSDATE, ''''PM'''') FROM DUAL;
 
  TO_C TO_C
  ---- ----
  오전 오전
 
  차) HH, HH12 :  시각 (1-12)

  SQL> SELECT TO_CHAR(SYSDATE, ''''HH''''), TO_CHAR(SYSDATE, ''''HH12'''') FROM DUAL;
 
  TO TO
  -- --
  12 12
 
  카) HH24 : 시각 (0-23)

  SQL> SELECT TO_CHAR(SYSDATE, ''''HH24'''') FROM DUAL;
 
  TO
  --
  00 

  타) MI : 분

  SQL> SELECT TO_CHAR(SYSDATE, ''''MI'''') FROM DUAL;
 
  TO
  --
  34 

  하) SS : 초
 
  SQL> SELECT TO_CHAR(SYSDATE, ''''SS'''') FROM DUAL;
 
  TO
  --
  57 
 
  물론 위의 포멧을 적절히 조합시킬 수 있습니다.
  현재 시스템 날짜의 년월일 시분초 까지 한번 나타내도록 하겠습니다.

  SQL>  SELECT TO_CHAR(SYSDATE, ''''YYYY/MM/DD HH24:MI:SS'''') FROM DUAL;
 
  TO_CHAR(SYSDATE,''''YY
  -------------------
  2003/12/11 00:36:27 

 2) TO_CHAR (NUMBER, FORMAT) : 숫자를 문자로 변환할때도 TO_CHAR 함수를 사용합니다.
    숫자용 포멧은 아래와 같습니다.
   
    가) 9 : 숫자 출력
    나) 0 : 숫자 앞에 0 표시
    다) . : 소수점 자리 표시
    라) , : 지정한 위치에 , 표시
    마) $ : 달러 표시
    바) L : 국가별 화폐단위표시
    사) MI : 오른쪽에 마이너스 표시


    그럼 위의 포멧을 적용한 예를 살펴보겠습니다.   
   
   SQL> SELECT
     2  TO_CHAR(1234,''''09,999''''),
     3  TO_CHAR(1234.56,''''99,999.99''''),
     4  TO_CHAR(1234,''''$99,999''''),
     5  TO_CHAR(1234,''''L99,999''''),
     6  TO_CHAR(-1234,''''99,999MI'''')
     7  FROM DUAL;
  
   TO_CHAR TO_CHAR(12 TO_CHAR( TO_CHAR(1234,''''L99 TO_CHAR
   ------- ---------- -------- ----------------- -------
    01,234   1,234.56   $1,234           ₩1,234  1,234-   

 3) TO_NUMBER(CHAR, FORMAT) :  숫자로 변환가능한 문자열을 숫자로 변환시켜줍니다.
    FORMAT은 2) TO_CHAR (NUMBER, FORMAT)에서 사용했던 FORMART을 사용합니다.
   
  SQL> SELECT
    2  TO_NUMBER(''''1234''''),
    3  TO_NUMBER(''''123,123'''',''''999,999'''')
    4  FROM DUAL;
 
  TO_NUMBER(''''1234'''') TO_NUMBER(''''123,123'''',''''999,999'''')
  ----------------- ------------------------------
               1234                         123123   
 4) TO_DATE(CHAR, FROMAT) : 문자를 날짜로 변환시켜주며, DATE형의 문자형 변환시와 반대지만 사용형식은 동일합니다.
 
  SQL> SELECT TO_DATE(''''2003/12/11 00:36:27'''', ''''YYYY/MM/DD HH24:MI:SS'''') FROM DUAL;
 
  TO_DATE(
  --------
  03/12/11

Posted by 1010
05.JSP2009. 1. 22. 17:32
반응형

새로운 JSTL1.1 태그 라이브러리 지정자

JSTL1.1은 JSTL을 JSP2.0에 통합하기 위한 마이너 스펙 릴리즈이다. 눈에 띄는 변화는 JSTL1.0의 두개로 분리되었던 라이브러리가 EL과 JAVA표현식 모두를 사용할 수 있는 한가지 라이브러리로 통합된 것이다.
JSTL의 라이브러리들은 다음과 같은 지정자를 사용한다.

Library URI Prefix
Core http://java.sun.com/jsp/jstl/core C
XML precessiog http://java.sun.com/jsp/jstl/xml x
l18N formatting http://java.sun.com/jsp/jstl/fmt fmt
Database access http://java.sun.com/jsp/jstl/sql sql
Function http://java.sun.com/jsp/jstl/function fn

EF Function

함수명 함수설명
fn:contains(string, sbustring) string이 substring을 포함하면 return True
fn:containsIgnoreCase(string, sbustring) 대소문자 관계없이 string이 substring을 포함하면 return True
fn:endsWith(string, suffix) string이 suffix로 끝나면 return True
fn:escapeXml(string) stting에 XML과 HTML에서 특별한 의미를 가진 문자들이 있으면, XML엔티티 코드로 바꿔준뒤 문자열 반환
fn:indexOf(string, sbustring) string에서 substring이 처음으로 나타나는 인덱스 반환
fn:join(array, separator) array요소들을 separator를 구분자로 하여 연결해서 반환
fn:length(item) item이 배열이나 컬렉션이면 요소의 객수를 문자열이면 문자의 객수를 반환
fn:replace(string, before, after) string내에 있는 before 문자열을 after 문자열로 모두 변경해서 반환
fn:split(string, separator) string내의 문자열 separetor에 따라 나누어서 배열로 구성해서 반환
fn:startsWith(string, prefix) string이 prefix로 시작하면 return True
fn:substring(string, begin, end) string에서 begin인덱스에서 시작해서 end인덱스에 끝나는 부분의 문자열 반환
fn:substringAfter(string, sbustring) string에서 substring이 나타나는 이후의 문자열 반환
fn:substringBefore(string, sbustring) string에서 substring이 나타나는 이전의 문자열 반환
fn:toLowerCase(string) string을 모두 소문자로 바꿔 리턴
fn:toUpperCase(string) string을 모두 대문자로 바꿔 리턴
fn:trim(string) string앞뒤의 공백을 모두 제거하여 반환

함수테스트 JSP 소스

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>

    <h1>EL Function(JSTL1.1)</h1>

    <c:set var="name" value="Oracle dbms 오라클클럽"/>
    <c:set var="name" value="${fn:trim(name)}"/><br/>
    <c:out value="name: ${name}"/><br/><br/>

    <c:out value="length(name): ${fn:length(name)}"/><br/>
    <c:out value="toUpperCase(name): ${fn:toUpperCase(name)}"/><br/>
    <c:out value="toLowerCase(name): ${fn:toLowerCase(name)}"/><br/>
    <c:out value="substring(name,3,6): ${fn:substring(name,3,6)}"/><br/>
    <c:out value="substringBefore(name,'dbms'): ${fn:substringBefore(name, 'dbms')}"/><br/>
    <c:out value="substringAfter(name,'dbms'): ${fn:substringAfter(name, 'dbms')}"/><br/>
    <c:out value="replace(name, '오라클클럽', 'Korea'): ${fn:replace(name, '오라클클럽', 'Korea')}"/><br/>
    <c:out value="indexOf(name, 'dbms'): ${fn:indexOf(name,'dbms')}"/><br/>
    <c:out value="contains(name, 'Oracle'): ${fn:contains(name, 'Oracle')}"/><br/>
    <c:out value="containsIgnoreCase(name, 'opracle'): ${fn:containsIgnoreCase(name, 'oracle')}"/><br/>
    <c:out value="startsWith(name, 'Oracle'): ${fn:startsWith(name, 'Oracle')}"/><br/>
    <c:out value="startsWith(name, 'dbms'): ${fn:startsWith(name, 'dbms')}"/><br/>
    <c:out value="endsWith(name, '오라클클럽'): ${fn:endsWith(name, '오라클클럽')}"/><br/><br/>
    <c:remove var="name"/>

    <c:out value="=================================================================="/><br/><br/>

    <c:set var="db" value="ORACLE, DB2, MSSQL, MYSQL, SYSBASE"/>
    <c:set var="db_arr" value="${fn:split(db,',')}"/>
    <c:forEach var="x" items="${db_arr}">
        <c:out value="${x}"/><br/>
    </c:forEach>
    <c:out value="${fn:join(db_arr, ',')}"/><br/>

   </body>
</html>

문서에 대하여

Posted by 1010
05.JSP2009. 1. 22. 15:21
반응형

1. 개요

  • JSP에서는 사용자가 태그를 정의해서 사용하는 것이 가능(Custom Tag)
  • Custom Tag중 자주 사용하는 것을 표준화 시켜 놓은 것을 JSTL
  • 작업을 수행하는 코드들을 태그로 간략화

2. JSTL을 사용하기위한 환경 설정

  1) http://jakarta.apache.org → downloads → Taglibs → standard 1.1 Taglib → 1.1.2.zip을 클릭하여 다운로드
  2) 압축을 풀어 jstl.jar, standard.jar 두 개의 파일을 톰캣홈\webapps\study\WEB-INF\lib폴더에 복사


3. JSTL 1.1 라이브러리


라이브러리

URI

Prefix

(접두어)

예시

Core

http://java.sun.com/jsp/jstl/core

c

<c:tagname...

XML processing

http://java.sun.com/jsp/jstl/xml

x

<x:tagname..>

I18N capable formatting

http://java.sun.com/jsp/jstl/fmt

fmt

<fmt:tagname..>

Database access(SQL)

http://java.sun.com/jsp/jstl/sql

sql

<sql:tagname..>

Functions(함수)

http://java.sun.com/jsp/jstl/functions

fn

fn:functionName(....)

4. JSTL 1.1 라이브러리

1) JSTL Core

  • 변수 선언, 삭제 등 변수와 관련된 작업
  • if문, for문 등과 같은 제어문, 그리고 URL 처리등에 사용
  1. <%@ taglib %> 디렉티브

  1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

p649


    *** 태그

(1) <c:set>
  • JSP의 setAttribute와 같은 역할
  • 변수 설정

  1. <c:set var="varName" value="value" target="targetObjectName" property="propertyName" scope="{page|request|session|application}"/>
  2.   var : 변수명
      value : 변수 값
      target : 자바빈 객체명,Map 객체명
      property : property 명
      scope : 공유범위

      예1) <c:set var="abc" value=${20}>  변수 abc에 값 20을 설정

      예2) <c:set value="20" target="kkk" property="age"}

             객체 kkk의 property  age의 값에 20을 설정


(2) <c:out>
  • JSP의 표현식을 대체
  • 화면에 해당 변수값을 출력

  1. <c:out var="varName" default="defaultValue" escapeXml="{true|false}"/>
            var : 변수명
            default : 기본값
            escapeXml : true로 설정시(기본값) < > & ‘ “ 문자들을 각각 &lt;&gt;&amp;&#039;&#034;로 출력

    예1) <c:out value="${abc}"/> 변수 abc 값을 출력


(3) <c:remove>태그
  • JSP의 removeAttribute()와 같은 역할을 한다.
  1. <c:remove var="varName" scope="{page|request|session|application}"/>
          var: 변수명
          scope : 변수의 공유 범위

예1) <c:remove var="abc"/> 변수abc의 값을 제거

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
     <title>JSTL core 예제 - set, out, remove</title>
    </head>
    <body>
  2.  browser변수값 설정
      <c:set var="browser" value="${header['User-Agent']}"/><br>
      <c:out value="${browser}"/><p>
     browser변수값 제거 후
      <c:remove var="browser"/>
      <c:out value="${browser}"/>
    </body>
    </html>

(실습1) 수량과 단가 기억장소에 data를 기억한 후 금액을 출력하는 프로그램 작성
    금액 = 수량 * 단가



(실습2) 이름과 국어,영어, 수학 점수를 폼에서 입력 받아서
EL과 JSTL을 이용하여 다음과 같이 출력


xxx님의 총점은 xxx이고 평균은 xxx입니다.


(4) <c:catch>
  • body위치에서 실행되는 코드의 예외를 잡아내는 역할
  1. <c:catch var="errMag"/>

        var : 에러가 발생하면 변수에 에러메세지가 들어간다


(5) <c:if>
  • 조건문
  1. <c:if test="condition" var="varName" scope="{page|request|session|application}"/>

       test : 조건 판별식
       var : 변수명
       scope : 변수의 공유범위


     예)

  1. <c:if test="${country=='korea'}">
        This customer is based in korea.
    </c:if>

country 변수값이 'korea'이면 밑의 문장 출력


(6) <c:choose>(<c:when>,<c:otherwise>)태그
  • switch문과 비슷, 조건에서 문자열 비교가 가능
  1. <c:choose>
      <c:when test="조건>body 내용</c:when>
      <c:otherwise>body의 내용</c:otherwise>
    </c:choose>

 예)

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
    <title>JSTL core 예제 - if, choose, when, otherwise</title>
    </head>
    <body>
    <c:set var="country" value="${'Korea'}"/>
    <c:if test="${country != null}">
      국가명: <c:out value="${country}"/>
    </c:if>
    <p>
    <c:choose>
      <c:when test="${country == 'Korea'}">
         <c:out value="${country}"/>의 겨울은 춥다.
      </c:when>
      <c:when test="${country == 'Canada'}">
         <c:out value="${country}"/>의 겨울은 너무 춥다.
      </c:when>
      <c:otherwise>
         그외의 나라들의 겨울은 알 수 없다.
      </c:otherwise>
    </c:choose>
    </body>
    </html>

(실습1) <c:if> 사용
변수에 수를 기억시키고
 기억된값이 0보다 크면 ‘양수입니다’
                 0이면 ‘0입니다’
                 0보다 작으면 ‘음수입니다’ 출력


(실습2) <c:choose>이용
변수에 이름과 점수를 기억시킨 후 점수에 따라 수우미양가 출력
  (예: 90점 이상 100점 이하이면 수)


(7) <c:forEach>
  • 객체 전체에 걸쳐 반복 실행할 때 사용
  1. <c:forEach items="items" begin="begin" end="end" step="step" var="varName" varStatus="varStatus"/>

      items : 반복할 객체명
      begin : 시작값
      end : 마지막 값
      step : 증가값
      var : 변수명
      varStatus : 변수 상태(index값이나 count값 출력)


예1) 0,2,4,6,8 출력

  1. <%@ page contentType="text/html;charset=euc-kr"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <c:forEach var="i" begin="0" end="9" step="2">
    ${i}<br>
    </c:forEach>

예2) 1에서 100까지 숫자 중에서 짝수 만 출력

  1. <%@ page contentType="text/html;charset=euc-kr"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <c:forEach var="k" begin="1" end="100">
       <c:if test="${k % 3 == 0}">
         ${k }<br>
       </c:if>
    </c:forEach>

 ** 객체에서 반복하여 값을 출력

  1. <c:forEach var="customer" items = "${customers}">
      Customer : <c:out value="${customer}"/>
    </c:forEach>

*** 예

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
      <title>JSTL core 예제 - forEach</title>
    </head>
    <body>
    <h3>Header 정보:</h3>
    <c:forEach var="head" items="${headerValues}" varStatus="status">
      param: <c:out value="${head.key}"/>
      <c:out value="${status.index}"/>  // index 값 출력
      <c:out value="${status.count}"/>  // 요소의 수를 출력
      <br>
      values:
       <c:forEach var="val" items="${head.value}">
         <c:out value="${val}"/>
       </c:forEach>
       <p>
    </c:forEach>
    </body>
    </html>

(8) <c:forTokens>
  • 자바의 StringTokenizer클래스를 사용하는 것
  1. <c:forTokens items="condition" delims="delimiter" begin="begin" end="end" step="step" var="varName" varStatus="varStatus"/>

    items : 객체명
    delims : 구분자
    begin : 시작값
    end : 마지막 값
    step : 증가값
    var : 변수명
    varStatus : 변수 상태


 *** 예

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
      <title>JSTL core 예제 - forTokens</title>
    </head>
    <body>
      <c:forTokens var="car" items="Sprinter Trueno AE86,
  2. RX-7 Savanna FC3S,
  3. Lancer Evolution III,
  4. RX-7 Efini FD3S" delims=",">
  5.    자동차 이름: <c:out value="${car}"/><br>
      </c:forTokens>
    </body>
    </html>

(9) <c:import>
  • 자원 import

  1. <c:import url="url" var="varName" scope="{page|request|session|application}" varReader="varReader" charEncoding="charEncoding"/>

       url : 읽어올 url
       var : 변수명
       scope : 변수의 공유 범위
       varReader : 리소스의 내용을 Reader 객체로 읽어올 때 사용
       charEncoding : 읽어온 데이터의 캐릭터 셋지정


    예)

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <c:import url="/ch07/date.jsp" var="url" />
    <html>
    <head><title>JSTL core 예제 - import</title></head>
    <body>
      ${url}
    </body>
    </html>

**date.jsp

  1. <%@ page contentType="text/html; charset=euc-kr" %>
    <%@ page import="java.util.*, java.text.*" %>
    <%@ page errorPage="err.jsp"%>
    <html>
      <body>
       <%
          Date date = new Date();
          SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd");
          String strdate = simpleDate.format(date);
       %>
       보통의 JSP 페이지의 형태입니다.<br>
       오늘 날짜는 <%= strdate%> 입니다.
      </body>
    </html>

(10) <c:redirect>
  • response.Redirect()를 대체하는 태그
  1. <c:redirect url="url"/>

     url : 이동할 URL


(11) <c:url>
  • 쿼리 파라미터로부터 URL 생성
  1. <c:url var="varName" value="value" scope="{page|request|session|application}"/>

   예1)

  1. <c:url value="/customers/register" var="registrationURL">
      <c:param name="name" value="${param.name}"/>
      <c:param name="country" value="${param.country}"/>
    </c:url>

 /customers/register?name=xxxx&country=xxxx의 값이 변수 registrationURL에 기억


2) JSTL XML

  • XML을 처리해 주기 위한 것
  • XML 출력, 흐름 제어, XML 변환등의 작업
  •  디렉티브 작성
  1. <%@ taglib prefix="x" uri="http://java.sun.com/jsp/js시/xml" %>
  • 태그 : p665

3) JSTL fmt

  • JSTL 국제화, 지역화 태그로 다국어 문서를 처리할 때 유용
  • 날짜와 숫자 형식을 다룰 때 사용
  • 디렉티브 작성
  1. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  • 태그 p667

(1) <fmt:setLocale>태그
  • 다국어 지원페이지를 만들 때 사용
  • ResourceBundle로 불러오는 *.properties 파일들과 연계하여 사용

  1. <fmt:setLocale value="locale" variant="variant" [scope="{page|request|session|application}"]/>

       value : 두 글자로 된 언어 코드를 반드시 지정
                 한글의 경우 ko_kr
       variant : 브라우저 스펙 기술
       scope : 변수의 공유 범우;


   예)

  1. <fmt:setLocale value="ko" />

(2)<fmt:requestEncoding>
  • request.setCharcterEncoding()

  1. <fmt:requestEncoding value="charsetName"/>

        value : 인코딩 값

     예)

  1. <fmt:requestEncoding value="euc-kr"/>
    <%@ page contentType="text/html; charset=EUC-KR"
        pageEncoding="EUC-KR"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>  
    <fmt:requestEncoding value="euc-kr"/>
    <html>
    <head>
    <title>Insert title here</title>
    </head>
    <body>
    파라미터 :<c:out value="${param.id}"/>
    <form method="post" action="jstlEx6.jsp">
       <input type="text" name=id>
       <input type="submit" value="확인">
    </form>  
    </body>
    </html>

(3) <fmt:bundle>
  •   properties 확장자를 이용하여 자원 파일을 읽어오는 역할
  1. <fmt:bundle basename="basename" prefix="prefix">
    body의 내용
    </fmt>

          basename : properties 파일명
             WEB-INF/classes에 보통위치(패키지 형식의 이름 가질 수 있음)
             bundle 폴더안에 testBundle.properties의 경우 : bundle.testBundle
             로케일이 ko일 경우 : testBundle_ko.properties 파일을 읽어온다
             prefix 속성 : key이름


        ☞ properties의 내용을 한글로 입력할 수 없으므로 유니코드로 변환하여 입력

            (변환 프로그램 : native2ascii.exe) - 자바홈\bin


(4)<fmt:message>
  • 번들 태그에서 정한 값을 가져온다

  1. <fmt:message key="messageKey" bundle="resourceBundle" var="varName"
    scope="{page|request|session|application}" />

         key : 읽어올 메시지의 key 값 기술
         bundle : setBundle 태그를 이용하여 로딩한 번들을 읽어올 때 사용
         var : 메시지를 저장할 변수명
         scope : 변수 공유범위 지정


      예)

  1. <fmt:message key="message" var="msg"/>

         message에 해당하는 값을 .properties 파일로부터 읽어와 msg 변수에 저장

     (예제)

① classes 폴더에 bundle 폴더 생성

         testBundle_ko.properties 파일 생성
         name=\uc0ad\ub791\ud574\uc694
         message=JSTL \ub108\ubb34 \uc88b\uc544


         testBundle.properties 파일 생성

         name=I love you.
         message=JSTL very good


② jstlEx7.jsp
  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"  %>
    <fmt:bundle basename="bundle.testBundle">
    <html>
    <head><title>JSTL fmt 예제 - bundle , message</title></head>
    <body>
    <fmt:message key="name"/>
    <p>
    <fmt:message key="message" var="msg"/>
    <c:out value="${msg}"/>
    </fmt:bundle>
    </body>
    </html>

(5) <fmt:setBundle>
  • 페이지 전체에서 사용할 수 있는 번들을 지정
  1. <fmt:setBundle basename="basename" var="varName" scope="{page|request|session|application}" />

         basename : properties 파일명
         var : 변수명
         scope : 변수 공유 범위


(6) <fmt:formatNumber>
  • 숫자 형식을 지정

  1. <fmt:formatNumber value="numericValue" type="{number|currency|percent}"
    pattern="customPattern" currencyCode="currencyCode" currencySymbol="currencySymbol" groupingUsed="{true|false}" maxIntegerDigits="maxIntegerDigits" minIntegerDigits="minIntegerDigits" maxFractionDigits="maxFractionDigits" minFrationDigits="minFractionDigits" var="varName" scope="{page|request|session|application}" />

        value : Number로 형식화될 수치
        type : 숫자, 통화,퍼센트
        pattern : 사용자가 지정한 패턴 형식 지정
        currencyCode : ISO 4217 통화 코드 지정
        currencySymbol : 통화기호 지정
        groupingUsed : 출력에 그룹 분리 기호를 포함할지 여부 지정
        maxIntegerDigits : 출력에서 integer 최대 자릿수 지정
        minIntegerDigits : 출력에서 integer 최소 자릿수 지정
        maxFractionDigits : 출력에서 소숫점 이하 최대 자릿수 지정
        minFractionDigits : 출력에서 소숫점 이하 최소 자릿수 지정
        var : 출력 결과 문자열을 담는 scope에 해당하는 변수명 지정
        scope : 변수의 공유범위 지정


(7) <fmt:parseNumber>
  • 문자열에서 수치로 파싱한다.
  1. <fmt:parseNumber value="numericValue" type="{number|currency|percent}" pattern="customPattern" parseLocale="parseLocale" integerOnly="{true|false}" var="varName" scope="{page|request|session|application}" />

      value : 수치지정
      type : 숫자, 통화,퍼센트
      pattern : 사용자가 지정한 패턴 형식 지정
      parseLocale : Locale 지정
      integerOnly : 주어진 값에서 integer 부분만 파싱할 지 여부 지정
      var : 변수명 지정
      scope : 변수 공유범위 지정


(8) <fmt:formatDate>

       + 날짜 형식을 표현할 때 사용


  1. <fmt:formatDate vaue="date" type="{time|date|both}" dateStyle="{default|short|medium|long|full}" timeStyle="{default|short|medium|long|full}" pattern="customPattern" timeZone="timeZone" var="varName" scope="{page|request|session|application}"/>

        value : Data와 time 지정
        type : 형식 지정
        dateStyle : 날짜 style 지정
        timeStyle : 시간 style 지정
        pattern : 사용자가 지정한 패턴 형식 지정
        timeZone : java.util.TimeZone 형식으로 된 시간에 나타날 타임 존 지정
        var : 변수명
        scope : 변수 공유범위


(9) <fmt:parseDate>
  • 문자열에서 날짜로 파싱할 때 사용
  1. <fmt:parseDate value="dateString" type="{time|date|both}" dateStyle="{default|short|medium|long|full}" timeStyle="{default|short|medium|long|full}" pattern="customPattern" timeZone="timeZone" parseLocale="parseLocale" var="varName" scope="{page|request|session|application}"/>

        value : Data와 time 지정
        type : 형식 지정
        dateStyle : 날짜 style 지정
        timeStyle : 시간 style 지정
        pattern : 사용자가 지정한 패턴 형식 지정
        timeZone : java.util.TimeZone 형식으로 된 시간에 나타날 타임 존 지정
        var : 변수명
        scope : 변수 공유범위


   예)

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <html>
    <head><title>JSTL fmt 예제 - formatNumber, formatDate</title></head>
    <body>
    number  : <fmt:formatNumber value="12345.678" type="number"/><br>
    currency: <fmt:formatNumber value="12345.678" type="currency" currencySymbol="₩"/><br>
    percent : <fmt:formatNumber value="12345.678" type="percent"/><br>
    pattern=".0" :<fmt:formatNumber value="12345.678" pattern=".0"/> <p>
    <c:set var="now" value="<%= new java.util.Date() %>" />
    <c:out value="${now}"/><br>
    date : <fmt:formatDate value="${now}" type="date" /> <br>
    time : <fmt:formatDate value="${now}" type="time" /> <br>
    both : <fmt:formatDate value="${now}" type="both" />
    </body>
    </html>

  1. number : 12,345.678
    currency: ₩12,345.68
    percent : 1,234,568%
    pattern=".0" :12345.7
    Mon Dec 29 10:03:27 KST 2008
    date : Dec 29, 2008
    time : 10:03:27 AM
    both : Dec 29, 2008 10:03:27 AM
(10) <fmt:setTimeZone>,<fmt:timezone>

    + 시간대 설정


  1. <fmt:setTimeZone value="timeZone" var="varName"
    scope="{page|request|session|application}"/>

      - value : 설정한 시간대 지정
      - var : 변수
      - scope : 변수 공유범위


   예)

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <html>
    <head><title>JSTL fmt 예제 - timeZone</title></head>
    <body>
    <c:set var="now" value="<%= new java.util.Date() %>" />
    Korea   KST  : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/><br>
    UK   GMT  : <fmt:timeZone value="GMT">
                      <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
                   </fmt:timeZone>
    </body>
    </html>

4) JSTL sql

  • DataSource를 이용해서 SQL를 처리하는 작업 등에 사용
  1. <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

태그

     transaction  : 트랜젝션 구현
     query : executeQuery()와 같은 기능
     update " executeUpdate()와 같은 기능
     param : java.sql.PreparedStatement.setString()의 역할
     dateParam : java.sql.PreparedStatement.setTimestamp() 역할
     setDataSource : DataSource 지정


(1)<sql:setDataSource>
  • DataSource 지정
  1. <sql:setDataSource {dataSource="dataSource"  |url="jdbcUrl" driver="driverClassName" user="userName" password="password" } var="varName" scope="{page|request|session|application}"/>

     url : JDBC url
     dataSource : 컨텍스트에 JNDI설정 시 리소스 네임
     driver : JDBC driver
     user : 사용자
     password : 패스워드
     var : 변수
     scope : 변수의 공용범위


 예) 표준 드라이버 사용

  1. <sql:setDataSource url="jdbc:oracle:thin:@localhost:1521:orcl" driver="oracle.jdbc.driver.OracleDriver" user="kkk" password="1234" var="ds" scope="application" />

 예) 기존의 dataSource를 불러와 사용하는 경우

  1. <sql:setDataSource dataSource="jdbc/myoracle" var="ds" scope="application" />

  dataSource : server.xml에서 정의한 <Resource> 태그의 name 속성의 값이 들어간다.


  예) 컨텍스트에 JNDI가 설정되어 있는 겨우

  1. <sql:query var="rs" dataSource="jdbc/myoracle">

(2)  <sql:query>
  • sql 태그의 속성 또는 body에 정의된 SQL  쿼리 문장을 실

① 속성에 sql 쿼리 문장을 기술한 경우
  1. <sql:query sql="sqlQuery" var="varName" scope="{page|request|session|application}" dataSource="dataSource" maxRows="maxRows" startRow="startRow" />

② 속성에 sql 쿼리문장을 기술하고 쿼리의 파라미터가 body에 있는 경우
  1. <sql:query sql="sqlQuery" var="varName" scope="{page|request|session|application}" dataSource="dataSource" maxRows="maxRows" startRow="startRow" />
    <sql:param>태그들
    </sql:query>

③ body에 sql 쿼리 문장과 파라미터를 기술한 경우
  1. <sql:query  var="varName" scope="{page|request|session|application}" dataSource="dataSource" maxRows="maxRows" startRow="startRow" />
    SQL 쿼리 문장
    <sql:param>태그들
    </sql:query>

   sql : sql 쿼리 문장
   var : 쿼리의 결과 저장
   scope : 변수 공용범위
   dataSource : JNDI의 리소스 네임 또는 DriverManger를 위한 파라미터
   maxRows : 쿼리 결과에 포함될 최대 행의 수
   startRow : 쿼리 결과에 포함될 시작 행 번호


  예제)

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    <html>
    <head><title>JSTL sql 예제 - query</title></head>
    <body>
    <sql:query var="rs"  dataSource="jdbc/myoracle">
        select * from member
    </sql:query>
    <table border="1">
      <tr><%--필드명  출력--%>
        <c:forEach var="columnName" items="${rs.columnNames}">
          <th><c:out value="${columnName}"/></th>
        </c:forEach>
      </tr>
      <c:forEach var="row" items="${rs.rowsByIndex}"><%-- 레코드의 수 만큼 반복한다.[][] --%>
      <tr>
        <c:forEach var="column" items="${row}" varStatus="i"><%-- 레코드의 필드수 만큼 반복한다.[] --%>
       <td>
           <c:if test="${column!=null}"> <%--해당 필드값이 null이 아니면--%>
                <c:out value="${column}"/>
           </c:if> <%--해당 필드값이 null이면--%>
           <c:if test="${column==null}">
                &nbsp;
           </c:if>
        </td>
        </c:forEach>
      </tr>
       </c:forEach>
    </table>
    </body>
    </html>

(3)<sql:dateParam>
  • 날짜 형식
  • java.sql.PreparedStatement.setTimestamp() 역할
  1. <sql:dateParam value="value" type="{timestamp|time|date}"}/>

         value : 파라미터 값
         type : 형식 설정


(4) <sql:param>
  • 문자열 형식
  • java.sql.PreparedStatement.setString()의 역할
  1.  <sql:param value="value"/>

(5) <sql:update>
  • sql 태그의 속성 또는 body에 정의된 sql 쿼리 문장을 실행
  •  executeUpdate()와 같은 기능
① 속성에 sql 쿼리 문장을 넣는 경우
  1. <sql:update sql="sqlUpdate" dataSource="dataSource" var="varName" scope="{page|request|session|application}"/>

② 속성에 쿼리 문장을 기술하고 쿼리의 파라미터가 body에 있는겨우
  1. <sql:update sql="sqlUpdate" dataSource="dataSource" var="varName" scope="{page|request|session|application}">
    <sql:param>태그들
    </sql:update>

③body에 sql 쿼리 문장과 파라미터들을 기술하는 경우
  1. <sql:update  dataSource="dataSource" var="varName" scope="{page|request|session|application}">
    sql 쿼리 문장
    <sql:param>태그들
    </sql:update>

    sql : sql 문장
    var : 쿼리 결과를 저장
    scope : 변수의 공유 범위
    dataSource : JNDI의 리소스 네임 또는 DriverManager를 위한 파라미터 네임


  예제)update

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    <html>
    <head><title>JSTL sql 예제 - update, param</title></head>
    <body>
    <sql:update dataSource="jdbc/myoracle">
        update member set passwd=? where id= ?
        <sql:param value="${3456}"/>
        <sql:param value="${'abc'}"/>    
    </sql:update>
    <sql:query var="rs"  dataSource="jdbc/myoracle">
        select * from member
    </sql:query>
    <table border="1">
      <tr><%--필드명  출력--%>
        <c:forEach var="columnName" items="${rs.columnNames}">
          <th><c:out value="${columnName}"/></th>
        </c:forEach>
      </tr>
      <c:forEach var="row" items="${rs.rowsByIndex}"><%-- 레코드의 수 만큼 반복한다. --%>
      <tr>
        <c:forEach var="column" items="${row}" varStatus="i"><%-- 레코드의 필드수 만큼 반복한다. --%>
       <td>
           <c:if test="${column!=null}"> <%--해당 필드값이 null이 아니면--%>
                <c:out value="${column}"/>
           </c:if> <%--해당 필드값이 null이면--%>
           <c:if test="${column==null}">
                &nbsp;
           </c:if>
        </td>
        </c:forEach>
      </tr>
       </c:forEach>
    </table>
    </body>
    </html>

(6) <sql:transaction>
  • 트랜잭션을 구할 때 사용
  1. <sql:transaction dataSource="dataSource" isolation="isolationLevel">
    <sql:query> 태그
    <sql:update>태그
    .....
    </sql:transaction>

dataSource : JNDI의 리소스 네임 또는 DriverManager를 위한 파라미터 네임
   isolation : java.sql.Connection의 setTransactionIsolation()메소드 사용
                 "read_committed","read_uncommitted","repeatable_read","serializable" 중 하나를 사용


 (실습)

id,비밀번호,이름,등록일
폼에서 데이터 입력 후
jstl을 이용하여 DB에 데이터 입력 ,비밀번호 ‘3456’으로 변경하여 출력하는 프로그램 작성





5) JSTL functions

  • JSTL에서 제공하는 각종 함수를 사용해서 문자열이나 콜렉션들을 처리
  1. <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/js시/functions" %>
  • 태그(p692)

 (1)예

  1. <%@ page contentType = "text/html; charset=euc-kr" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    <html>
    <body>
      <c:set var="name" value="  Jsp 세계  "/>
      <c:set var="name" value="${fn:trim(name)}"/>
      <br/><c:out value="name: ${name}"/><br/><br/>
      <c:out value="length(name): ${fn:length(name)}"/><br/>
    </body>
    </html>

Posted by 1010
05.JSP2009. 1. 20. 19:02
반응형


<form action=\"http://phpschool.com\" onSubmit=\"this.submit.disabled=true\">
<input type=\"text\" name=\"test\">
<input name=\"submit\" type=\"submit\" value=\"전송\">
</form>
이렇게 해야겠네요 : )
Jun// type=image일때는 조금 다르게 동작하는거같습니다
그래도 disabled 속성은 있으니
<input type=\"image\" onClick=\"this.form.submit();this.disabled=true\" value=\"전송\">

====================================================================
IE6에선 확인할수 없지만.

일단 IE7에선 아래 처럼 적용.
<input type="submit" value=" 저장 " onClick="this.form.submit();this.disabled=true"/>
Posted by 1010
05.JSP2009. 1. 20. 17:39
반응형
response.setHeader( "Pragma", "no-cache;" );
response.setHeader( "Expires", "-1;" );
no-cache부분을 한번 지워보삼
Posted by 1010
05.JSP2009. 1. 20. 15:06
반응형
String imsi = request.getParameter("imsi")==null ? "" : request.getParameter("imsi");
Posted by 1010
61.Linux2009. 1. 20. 10:37
반응형
Open Antivirus Project
http://www.openantivirus.org/
(자유소프트웨어 진영의 대표적 안티바이러스)

Clam Antivirus
http://www.clamav.net/
(GPL 라이센스를 따르며 C로 쓰여진 OpenAntivirus database 기반의 빠른 스캐너)

QtFprot
http://www.kde-apps.org/content/show.php?content=10381
(QtFprot is a frontend for FPROT 4.x, a free (for personal use) Linux virus-scanner. It's similar to XFprot, but written in Qt. It allows you to set all FPROT paramters with a comfortable GUI.)

Firewall Builder
http://www.fwbuilder.org/
(GPL 라이센스를 따르는 멋진 멀티플래폼 방화벽 설정도구)
참고: http://firewall-jay.sourceforge.net/ (TUI 모드의 방화벽 설정 도구)
http://www.simonzone.com/software/guarddog/#introduction

Kmyfirewall
http://kmyfirewall.sourceforge.net/
(GPL 라이센스의 KDE용 IPtables 설정 도구)


File::Scan
http://freshmeat.net/projects/filescan/
(File::Scan allows users to make multiplataform virus scanners which can detect Windows/DOS/Mac viruses. It include a virus scanner and signatures database
텍스트 기반의 펠로 쓰여진 바이러스 스캔너)

Aegis Virus Scanner
http://jodrell.net/projects/aegis
(그래픽 인터페이스의 단순하고 직관적인 바이러스 스캔너)

BitDefender Linux Edition
http://www.bitdefender.com/
(텍스트 모드의 강력한 바이러스 스캐너로 개인사용자는 무료다운로드 가능-자유소프트웨어 아님)

Panda Antivirus for Linux
http://www.pandasoftware.com/com/linux/
(무료소프트웨어-자유소프트웨어 아님. 텍스트 기반으로 사용자 프로필 작성후 다운로드 가능)

F-Prot
http://www.f-prot.com/
(서버 사용자 유료 개인사용자는 프로필 작성 후 무료사용)

McAfee
http://www.mcafee.com/us/default.asp
(사용자 프로필 작성후 평가판을 다운로드 받을 수 있음)

Kapersky Anti-Virus
http://www.kaspersky.com
(상용 http://www.kaspersky.com/trials 에서 개인 프로필 작성후 30 평가판 다운로드 가능)

NOD32
http://www.nod32.com/home/home.htm
(상용 윈도우 버젼만 평가판 제공 리눅스용으로는 서버용 판매)

Sophos Antivirus
http://www.sophos.com/
(상용 워크스테이션용 $40 서버용 $400 -1사용자 기준)

ServerProtect
http://www.trendmicro.com/kr/products/fileserver/spl/evaluate/overview.htm
(상용 서버용)

RAV Antivirus
http://www.ravantivirus.com
(현재 평가판 버젼 다운로드 중단 구매 가능)

InterScan
http://www.trendmicro.com/en/products/linux/overview.htm
(상용)

Vexira Antivirus for Linux
http://www.centralcommand.com/downloads.html
(텍스트 기반 상용 평가판 다운로드 가능)
Posted by 1010
61.Linux2009. 1. 19. 15:21
반응형
"Server unexpectedly closed network connection"

라는 에러 메시지와 함께 접속 안 되는 경우가 생깁니다

그럴 경우에는 /etc/ssh/sshd_config 에서 UseDNS no 라고 추가 시켜 준 다음에

ssh 데몬(sshd)를 재시작(하거나 kill 로 죽인 다음에 다시 실행)하면 됩니다

추가
이전 키는 삭제 해야 합니다

리눅스에서는 ~계졍명/.ssh/known_hosts 에 해당하는 주소에 키를 삭제 하면 되고

윈도우에서 putty를 쓸 경우에는 레지스트리에서
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
에 해당하는 키를 삭제하면 됩니다--moon.ft.co.kr

2008-05-19 | training
Posted by 1010
61.Linux2009. 1. 19. 14:59
반응형
  1. GUI
    1. DESKTOP X Window선택
    2. X Window에서 해상도 조절
    3. X window 해상도를 설정하려면
    4. ami실행 후 메뉴가 깨져 있을 때
    5. ami실행 후 한영키를 사용하고 싶은 경우
    6. 휠마우스에서 휠이 작동을 안할 때
    7. 원격에서 리모트서버의 X application실행시
    8. 폰트서버 설정
    9. KDE 3.x 버전에서 윈도우용 트루타입 폰트를 못 찾는 경우
    10. 한텀(hanterm) 타이틀바에 디렉토리 경로 보이게 하기
  2. Pacakge 관리
    1. RPM 관련 커맨드
    2. rpm package설치시 상호의존성이 얽혀있을 땐 한 command로 설치
    3. 필요없는 rpm지우기
    4. 레드헷 8.0에서 up2date 사용하기
  3. Network
    1. Network 설정 파일들
    2. 급하게 Network설정을 해야할 경우
    3. 하나의 랜카드에 여러개의 ip추가하기
    4. 열린 포트를 사용하는 프로세서를 확인하려면
    5. ping 무시하기
    6. TCP/IP속도 증가시키기
  4. VI
    1. vi 에디터 내에서 ^M을 입력하려면
    2. vi 에데터 내에서 ^M을 없애려면
    3. vi에서 라인끝 빈칸 지우기
    4. vi에서 벨소리 제거
    5. vi에디터에서 삭제/복사 간편하게
    6. vi에디터에서 어떤 문자열을 찾고자 할 때 대소문자 안가리게 하려면
    7. vi에디터에서 '숫자'만큼의 컬럼으로 이동
    8. vi에서 화면 나누기
    9. 파일 네비게이션
    10. vi내에서 파일 네비게이션 바 만들기
    11. 여러개의 파일 편집하기
    12. vi로 파일비교
    13. 잠시 쉘로 나가기
    14. vi에서 자동들여쓰기를 안하려면
    15. vim 의 syntax 기능에서 underline 없애기
    16. 윈도우에서 작성한 한글이 페도라2(Fedora Core2) 에서 깨져보일 때
  5. System 관리
    1. Swap공간을 알려주는 명령어 (process check)
    2. 현재 디렉토리가 차지하는 용량 보기
    3. run-level을 변경하려면
    4. CPU정보를 알고 싶다면
    5. MEM정보
    6. 특정 데몬이 띄워져 있는지 확인하려면
    7. 현재 구동중인 데몬을 트리형식으로 보려면
    8. 시스템 부하상태 보기
    9. shell을 vi 스타일로
    10. 최신 커널버전 알기
    11. prompt에 full path 표시를 하고싶다면
    12. log파일에서 내용만 지우기
    13. 현재 연결되어 있는 TCP port보기
    14. LILO에서 싱글부팅
    15. grub에서 싱글부팅
    16. 하위 디렉토리까지 문자열 검색하려면
    17. world writable file 찾기
    18. ext2에서 ext3로 업그레이드 하기
    19. logon기록을 보려면
    20. remote환경에 있는 윈도우 폴더 마운트하기
    21. 터미널에서 디렉토리, 파일 색상 변경
    22. 서브 디렉토리까지 한번에 생성
    23. alias 적용안하기
    24. 이동한 바로 직전의 디렉토리로
    25. 일정기간 동안 접근하지 않는 파일 삭제하기
    26. setuid가 설정된 루트쉘 검색
    27. MySQL Connection Failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111) 에러가 나는 경우
    28. 특정 유저만 su 허락하기
    29. 작업중 로그인 막기
    30. 크기가 가장 큰 파일, 디렉토리 찾기
    31. 현재 디렉토리의 크기만을 파악할때
    32. 시스템 정보 감추기
    33. 메모리를 가장 많이 잡아먹는 프로세스 알아내기
    34. FTP로 들어온 사용자 확인하기
    35. 원하지 않는 사용자 죽이기
    36. 몇일 이상된 파일만 mv또는 cp
    37. 터미널에서 백스페이스를 누르면 ^H 와 같은 이상한 문자가 출력되는 현상
    38. 텔넷이나 ftp 외부 사용시 root로 접속 가능하게 하는 방법
    39. 여러 파일 안에 있는 내용중 특정단어를 바꾸고 싶을 때
    40. 윈도우 디렉토리 마운트후 한글 디렉토리가 깨져보일 때
    41. tail 명령어 활용
    42. shell prompt 변경하기
    43. kernel 파라미터 조정하기
    44. 사용자별 du -h 값 보기
    45. 하룻동안 만들어진 파일 검색하기
    46. apache 설정 파일 문법 오류 검색
    47. 레드햇 패키지 버전을 알고 싶을 때
    48. 새로운 배포본 설치를 위한 Multi LILO
    49. Rebooting 키 제한을 위한 설정
    50. 하드디스크 I/O 튜닝
    51. Core 파일 디버깅
    52. CPU부하와 메모리 사용 정보
    53. Fedora Core2에서 한글 인코딩 바꾸기
    54. Fedora2에서 한글man page 깨지는 현상에 대한 해결책


 


1 GUI


1.1 DESKTOP X Window선택

#vi /etc/sysconfig/desktop

DESKTOP = "GNOME" or "KDE"

1.2 X Window에서 해상도 조절

    CTRL + ALT + "+"(Num Lock key)
    CTRL + ALT + "-"


1.3 X window 해상도를 설정하려면

/etc/X11/XF86Config-4 (symbolic link되어 있음)
Screen section의 MODE
"800*600" "1024*768" "1152*864"

1.4 ami실행 후 메뉴가 깨져 있을 때

#export 해서 LANG 와 XMODIFIERS 변수를 확인하라.


1.5 ami실행 후 한영키를 사용하고 싶은 경우

/etc/X11/Xmodmap 파일에 다음을 추가시킨다.

! i386 and alpha
keycode 22 = BackSpace
keycode 107 = Delete
keycode 121 = Hangul_Hanja
keycode 122 = Hangul

X를 재실행하거나 재실행시키고 싶지 않다면
#xmodmap /etc/X11/Xmodmap 을 실행


1.6 휠마우스에서 휠이 작동을 안할 때

휠기능을 작동시키려면  /etc/X11/XF86Config-4 를 수정한다.

Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "PS/2"
Option "Device" "/dev/psaux"
Option "ZAxisMapping" "4 5"
Option "Emulate3Buttons" "yes"
EndSection

바로 이 부분
 Option   "Protocol" "PS/2" 이렇게
 Option   "Protocol" "IMPS/2" 고치면 휠을 사용할 수 있다.
만약 다음 부분
 Option      "ZAxisMapping" "4 5" 이 없다면 추가시킨다.


1.7 원격에서 리모트서버의 X application실행시

서버측: xhost +클라이언트ip (xhost + 는 모든 주소에 대해 원격접속 허용)
클라이언트측: export DISPLAY=서버ip:0.0


1.8 폰트서버 설정

클라이언트측에서 Xmanager를 이용해 리눅스 서버에 접근하려면 서버에 폰트서버가 실행되고 있어야 한다. 폰트서버는 xfs데몬을 말하는 것으로 그냥 띄우면 되고 단지 /etc/X11/XF86Config에서

FontPath "/usr/X11R6/lib/X11/fonts/TrueType"
# FontPath "unix/:-1"

FontPath "unix/:7100" 로 주석부분을 고쳐주면 된다. 그럼 7100포트가 열린다. 그리고 그서버와 포트를 지정하면 폰트서버가 타 x서버에서 사용가능하다.


1.9 KDE 3.x 버전에서 윈도우용 트루타입 폰트를 못 찾는 경우

from KLTP
최근에 나온 레드햇8을 쓰고 있는데요 윈도우용 폰트를 가져다 쓰고 있습니다. 그런데 KDE에서 새로 추가한 윈도우용 트루타입폰트를 찾지 못하는 문제가 있더군요. xfontsel에서도 인식하고 셋팅역시 제대로 되어서 GTK나 Motif로 만들어진 다른 어플리케이션에서는 모두 인식하나 KDE에서는 백묵 글꼴만 나오고 윈도 폰트는 아예글꼴 리스트에 나오지도 않더군요. 해결책이 딴데 있더군요.

KDE가 QT 라이브러리로 만들어진 것이라 "혹시 QT셋팅에 문제가 있는것은 아닐까" 라는 생각을 하고 Qt config를 살펴봤습니다. QT Config에 Anti aliase font지원을 꺼 봤더니 제대로 동작하더군요. 아마도 QT내지는 XFS 자체의 버그인 것 같습니다. 간단히 말씀드리자면 qtconfig3를 실행시켜 Font탭에서 Enable Anti-Aliased Font Support를 꺼 주시고 X를 재시작 하시면 윈도우용 굴림 폰트를 KDE에서 이용하실 수 있습니다. --Kid A

1.10 한텀(hanterm) 타이틀바에 디렉토리 경로 보이게 하기

자신의 .bash_profile에 다음을 추가하면 한텀의 타이틀바에 <사용자ID>@<호스트명>:<디렉토리명>의 형식으로 나타나게 된다.

function proml
{
case $TERM in
xterm*)
local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
;;
*)
local TITLEBAR=''
;;
esac
PS1="${TITLEBAR}\n] \u@\h ]"
}
proml

2 Pacakge 관리


2.1 RPM 관련 커맨드

    #rpm -qa : 현재 설치된 package출력
    #rpm -qil mtools | less : mtools에 관한 package정보
    #rpm -qif /etc/bashrc : /etc/bashrc파일이 속한 package


2.2 rpm package설치시 상호의존성이 얽혀있을 땐 한 command로 설치

#rpm -Uvh [package1] [package2] [packag3] .......

    의존성을 무시하고자 할 땐 --nodeps option사용


2.3 필요없는 rpm지우기

    만약 MySQL을 설치 하였다고 하자.

MySQL-3.23.33-1.i386.rpm* MySQL-devel-3.23.33-1.i386.rpm*
MySQL-client-3.23.33-1.i386.rpm* MySQL-shared-3.23.33-1.i386.rpm*

그리고 이것을 지우려면 ?

rpm -e `rpm -qa | grep MySQL`

또한 대소문자를 구분하지 못한다면?

rpm -e `rpm -qa | grep -i mysql`

이라고 써도 된다.

이때 ` 기호는 숫자 1번 왼쪽에 있는 백쿼터이다.

패키지명과 버젼이 동일한 패키지가 여러개 존재할때 삭제하는 방법

rpm -e 패키지명 --allmatches

2.4 레드헷 8.0에서 up2date 사용하기

from KLTP
레드헷 8.0 설치하고 up2date을 사용하려 하니 황당한 에러가 나와서 해결하고 나서 올립니다.
레드헷 8.0 에서는 설치후에 [일반관리자용] setup 에서 서비스 보시면, rhnsd 가 있는데 이거 활성화 시켜 주시고요..(그냥 참조용임) 바로 up2date --register 하시면 접속해서 등록해서 바로 사용할 수 있습니다.

/etc/rc.d/init.d/rhnsd restart 하시면 됩니다.

이후 up2date * 하시면 됩니다. 그런데, 이런 에러가 나오시는분....

There was an SSL error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]

이게 SSL 에러냐.. 절대 아닙니당.. 저도 처음에 그런줄알고 패키지 문제 인줄 알고 의존성 찾아보고, 삽질했습니당.결국에 알아낸것은 시간이 일치 하지 않는 다는 결론을... 이건 구글에서 검색했는데, 누군가 시간차를 적어 놓았더군요... 혹시 해서...

rdate -s time.kriss.re.kr

해서 다시, up2date --register 해보니... 헐 아주 잘 되네염... --박성훈

    time.kriss.re.kr은 사용하지 마세요. 제가 예전에 서버들 간의 시간동기화를 하기위해서 time.kriss.re.kr 사용했다가 아주 크게 쓴맛을 보았습니다. 표준연의 타임서버가 갑자기 죽고나서 정확한 시간으로 셋팅되는 것이 아니고 OS상에서 존재하는 가장 처음의 시간, 기억은 1960년대의 시간으로 셋팅 되는 바람에 중요한 데이터들간의 시간동기화에 문제가 생겨서 데이터를 몽땅 버린 적이 있습니다. 제가 추천하는 time 서버는 ntp를 사용하는 것입니다. time.datum.com, kr.public.ntp.get-time.net unix 계열의 OS에서는 ntp 관련 S/W를 설치하시면 됩니다. 그러면 이만... --익명

      이번에 레드헷 9.0을 설치하고 업데이트 하려고 하니 위으 에러메세지가 나오더군요! 그래서 시간을 동기화 했는데도 마찬가지 입니다. 그래서 레드헷 사이트에 가니 관련 RPM패키지를 받아 재설치 하라고 하네요 레드헷 사이트에 가서 새로운 up2date 관련 RPM을 받아 새로 설치 하시기 바랍니다. --호종기


3 Network


3.1 Network 설정 파일들

/etc/hosts : localhost 및 server name
/etc/resolv.conf : name server
/etc/sysconfig/network : HOSTNAME
/etc/sysconfig/network-scripts/ifcfg-eth0 : IP, Netmask, Gateway등등

설정이 끝났다면
 #/etc/rc.d/init.d/network restart 또는
 #service network retart

3.2 급하게 Network설정을 해야할 경우

#ifconfig eth0 <ip_addr> netmask <netmask> up
#route add default gw <gw>
#cat > /etc/resolv.conf
nameserver <DNS_addr>
CTRL-D

#ping dongwoo.org

3.3 하나의 랜카드에 여러개의 ip추가하기

from KLTP
◎아이피추가는
1) ifconfig eth0:0 아이피 netmask 아이피 broadcast 아이피 up
2) cd /etc/sysconfig/network-scripts
3) /etc/sysconfig/network-scripts/에 있는 ifcfg-eth0을 복사, 파일명을 ifcfg-eth0:0
4) vi로 열어 Device=eth0:0, ipaddr=원하는 아이피 주소
5) ./ifup eth0:0
6) /etc/rc.d/init.d/network restart

계속 추가시에는 eth0:1, eth0:2....등등으로 한다. 재부팅해보고 ifconfig를 해봐서 추가되었는지 확인한다.

◎아이피 삭제는
1) ifconfig eth0:0 아이피 netmask 아이피 broadcast 아이피 down
2) cd /etc/sysconfig/network-scripts
3) rm ifcfg-eth0:0
4) /etc/rc.d/init.d/network restart

재부팅해보고 ifconfig해봐서 삭제되었는지 확인한다. 참고로 레드햇 8.0에서 셋팅함

3.4 열린 포트를 사용하는 프로세서를 확인하려면

    if #3306 port is opened

#fuser -n tcp 3306 -> show PID
#ps -ef | grep [PID]

3.5 ping 무시하기

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all


3.6 TCP/IP속도 증가시키기

TCP/IP의 속도를 실제로 증가 시키는 것은 아니구요. 디폴트 값을 낮게 해서, 좀 더 많은 연결이 동시에 제어될 수 있도록 하는 방법이랍니다. 리눅스 박스가 연결을 닫는데 드는 시간을 줄여주고, 불안정한 열결을 끊기전에 시간을 줄여 줍니다. 또한 필요없는 IP 확장을 꺼 놓음으로서 체감 속도를 훨씬 빠르게 해 줄 것입니다.

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1800 >/proc/sys/net/ipv4/tcp_keepalive_time
echo 0 > tcp_window_scaling
echo 0 > tcp_sack
echo 0 > tcp_timestamps

4 VI


4.1 vi 에디터 내에서 ^M을 입력하려면

CTRL + V --> CTRL + M
^T ^] 은 각각 CTRL + T CTRL + ]

4.2 vi 에데터 내에서 ^M을 없애려면

:0,%s/^M//g (^M : CTRL-v, CTRL-m)

4.3 vi에서 라인끝 빈칸 지우기

:g/^$/d

4.4 vi에서 벨소리 제거

    :set vb


4.5 vi에디터에서 삭제/복사 간편하게

:10, 20d
10번째줄에 가서 ma 누르고 20번째줄에 가서 d'a (삭제) y'a (복사)

:'a,.co.
'a부터 .까지 .밑에 copy

4.6 vi에디터에서 어떤 문자열을 찾고자 할 때 대소문자 안가리게 하려면

    :set ic


4.7 vi에디터에서 '숫자'만큼의 컬럼으로 이동

    숫자|


4.8 vi에서 화면 나누기

:split [file] <-- 수평
:vs [file] <-- 수직

화면간 이동을 하려면 CTRL + w , ijkl

4.9 파일 네비게이션

    #vi ./ <--- 현재 디렉토리 내용을 네비게이션


4.10 vi내에서 파일 네비게이션 바 만들기

    :20vs ./

    열기를 원하는 파일에 가서 shitf + o


4.11 여러개의 파일 편집하기

#vi file1 file2 file3 .....

:n <---- 뒤의 파일 편집으로
:e# <---- 앞의 파일 편집으로

4.12 vi로 파일비교

 #vi -d file1 file2

4.13 잠시 쉘로 나가기

    CTRL + z

    다시 vi로
    #fg


4.14 vi에서 자동들여쓰기를 안하려면

    :se(t) nocindent
    :se(t) nosmartindent (nosi)
    "se(t) noautoindent (noai)


4.15 vim 의 syntax 기능에서 underline 없애기

리눅스에서 터미널을 열어서 vi 작업을 한다면 syntax 기능을 사용하는데 별다른 어려움이 없을것이다. 하지만 telnet 으로 접속해서 사용하는 경우에 color 를 표시할 수가 없는 경우엔 해당 syntax 가 보통 underline 으로 표시된다. 그런데 이 underline 때문에 소스코드를 보기가 힘들경우가 있다.

이 글에서 다룰 내용은 다음과 같다. highlight 기능 과 colorscheme 사용.

vi 를 연 상태에서

:sy[tax] on

을 켠다. 여기서 [] 안의 내용은 옵션이다. 안써도 된다. 그리고 다음과 같이 하면 현재 사용하는 highlight 목록을 살펴 볼수 있다.

:hi[ghlight]

이 색깔에 대한 정의는 다음에 정의 되어 있다.

:!echo $VIMRUNTIME/colors

위 디렉토리 아래에 가보면 morning.vim, evening.vim 등의 파일들이 보이는데 각각 color scheme 를 정의해 놓은 파일들이다. 다른 color scheme 로 바꾸고 싶다면 다음과 같이 한다.

:colorscheme evening

여기서 evening 는 scheme 이름이다.
그럼 이제 underline 을 없애도록 하겠다. 현재 telnet 접속하여 vim 을 사용하고 있다는 가정하에 하는 것이다. 콘솔에서 사용하는 사람은 대개 underline 이 나오지 않을것이다.

:hi

위와 같이 하면 다음과 같이 출력이 된다.

Type term=underline ctermfg=2
Constant term=underline ctermfg=4 guifg=Magenta

여기서 Type 이라고 쓰여진 첫 필드는 group-name 이다. 만약 당신이 C 코드를 열고 있다면 Type 은 말그대로 char, int, float... 등과 같은 Type 이다. term 은 color 를 표시할 수 없는 터미널이다. term 에선 underline 으로 표시하겠다는 뜻이다. ctermfg 는 color terminal 이다. fg 는 foreground 이다. 번호는 색깔을 나타낸다. 즉, color 를 표시할 수 있는 터미널에선 2번 컬러로 Type 을 표시한다. 색깔은 숫자가 아니라 직접 명시를 할 수도 있다. ctermfg=blue 이런식이다. 그럼 상수를 표시할때 term 에선 bold 로 표시하도록 해보자.

:hi Constant term=bold ctermfg=4

아무런 설정도 하고 싶지 않다면 bold 대신에 NONE 라고 사용하면 된다.

위와 같은 설정들은 ~/.vimrc 에 저장하여 사용할 수도 있다.

shell> cat -n ~/.vimrc

1 set ic
2 set nu
3 set softtabstop=4
4 set shiftwidth=4
5 set formatoptions=croql
6 set ruler
7 set showmode
8 set smartindent
9 syntax on
10 filetype indent on
11 map <F2> :w<cr>:!gcc -Wall % -o %< && ./%<<cr>
12 map <F3> :<CR>:!./%<<CR>
13 map <F4> :so $VIMRUNTIME/syntax/2html.vim<CR>
14
15 colorscheme pablo
16 hi Type term=NONE ctermfg=2
17 hi PreProc term=NONE ctermfg=10
18 hi LineNr term=NONE ctermfg=6
19 hi Constant term=NONE ctermfg=14

15번째 라인부터가 highlight 설정이다. 1번째 라인부터 10번째 라인은 기본적인 설정들에 대한 내용이다. 11번째에서 13번째 라인은 mapping 기능으로 <F2> 를 누르면 C 코드를 컴파일 한후 실행하고 <F3> 를 누르면 컴파일된 바이너리를 실행만 한다. <F4> 를 누르면 현재 파일을 HTML 파일로 변환하여 준다. --linox


4.16 윈도우에서 작성한 한글이 페도라2(Fedora Core2) 에서 깨져보일 때

윈도우에서 작성한 문서를 페도라2에서 열어보면 한글이 다 깨져보이는 수가 있다. 이는 encoding 차이때문인데 윈도우에서 저장한 파일은 기본적으로 euckr로 인코딩된다. Fedora Core2는 utf-8방식을 사용하기 때문에 파일을 컨버전해야 한다. 방법은 2가지다

1. 파일을 utf-8로 인코딩함

$iconv -f euckr -t utf-8 a.euckr.txt > a.utf-8.txt

2. 에디터 프로그램의 보기에서 encoding을 euckr로 바꿔준다. (vi는 지원함)


5 System 관리


5.1 Swap공간을 알려주는 명령어 (process check)

    #top


5.2 현재 디렉토리가 차지하는 용량 보기

    # du -s -h


5.3 run-level을 변경하려면

    #telinit 5


5.4 CPU정보를 알고 싶다면

    #arch


5.5 MEM정보

    #free


5.6 특정 데몬이 띄워져 있는지 확인하려면

    #ps aux | grep httpd


5.7 현재 구동중인 데몬을 트리형식으로 보려면

    #pstree


5.8 시스템 부하상태 보기

    #uptime


5.9 shell을 vi 스타일로

    #set -o vi


5.10 최신 커널버전 알기

    #finger @finger.kernel.org
    #finger @kernel.org


5.11 prompt에 full path 표시를 하고싶다면

#vi /etc/bashrc

PS1 = [ ..... ]
\U : User
\h : Host
\W : 사용자가 위치하는 경로의 최 하위디렉토리
여기서 \W -> \w

5.12 log파일에서 내용만 지우기

    #>log_file


5.13 현재 연결되어 있는 TCP port보기

    #netstat -t (-nlt : 열려있는 포트확인)


5.14 LILO에서 싱글부팅

    #vmlinuz root=/dev/hda9 single : /dev/hda9에 리눅스로 single booting


5.15 grub에서 싱글부팅

- grub메뉴에서 e를 누릅니다. (edit)
- edit 화면에서 화살표키로 "kernel /boot/vmlinuz-xxxx" 로 옴깁니다.
- 다시 e키를 누르면 명령어 줄이 나옵니다. 끝에 한칸띄우고 single이라 고 적고
enter를 누릅니다.
kernel /boot/vmlinuz-2.2.17-5mz /dev/hdax single [enter]
- 하시고, b를 눌러서 booting을 합니다.

5.16 하위 디렉토리까지 문자열 검색하려면

grep -rl [문자열] *

    r 옵션이 없다면

find . * -exec grep -n [문자열] {}\; -print

    더 짧고도 효과적인 방법

    grep "string"'find . -type '
    그런데 이는 조건에 맞는 파일의 개수가 많아지면 쉘의 명령행 버퍼의 범위를 벗어나므로 문제가될 소지가 있다. 명령행 버퍼의 오버플로우를 방지하기 위해선 다음과 같이 하면 된다.
    find . -type f | xargs grep "string"
    그런데 이 방법은 파일 이름에 공백이 들어갈 경우 문제가 생길 수 있다. 그럼 다음과 같이 해보자.
    find . -type f -print0 | xargs -0 grep "string"
    find는 심볼릭 링크된 디렉토리에 대해서는 기본적으로 검색을 실시하지 않으니 -follow옵션을 사용해야할 경우도 있다는 것을 알아둔다.

      명령행 버퍼오버플로우를 방지하는 방법은 다음과 같은 방법도 있다.

      find . -type f -exec grep -l"string" {}\;
      grep에서 '-l'옵션은 string을 포함하는 파일명을 나타내준다. 이런 검색을 특정 파일들에 대해서 행하기 위해서는 -type와 -name옵션을 쓸 수 있다.
      find . \(-type f -name "*\.html"\) -exec grep -l "string" {}\;
      이것은 html의 확장자를 가지는 모든 파일에 대해서 "string"을 포함하는지 알아보고 포함하고 있는 파일명을 출력해준다.

위의 방법들은 "어떻게 서브디렉토리에 있는 파일들에 대해서 grep을 실행해줄 수 있는가?"하는 문제에 관한 여러 가지 방법들은 매우 유용하긴 하지만 검색을 실시하는 디렉토리에 바이너리 파일이 있을 경우에는 터미널을 제어하지 못하는 문제가 생길 수 있다. 왜냐하면 바이너리 파일의 몇몇 제어 문자들(Control Characters)이 터미널을 그래픽 모드로 바꿔놓을 수 있기 때문이다. 물론 이렇게 되었을 경우 터미널을 다시 바로잡는 방법이 있긴 하지만 아무래도 가장 좋은 방법은 그러한 일이 없도록 처음부터 방지하는 것이 가장 좋을 것이다.
이제 화면에 찍혀나올 수 없는 문자들을 모두 없애보자. 어쨌든 읽을 수는 없지만 다음과 같은 명령을 내려보라.

sed -e 's/[^-~][^-~]*//g'

이 명령은 화면에 출력될 수 없는 (제어) 문자들을 그냥 스페이스들로 바꿔 버린다. 이 명령은 파이프를 이용하여 쉽게 다른 명령어들과 결합해서 사용할 수 있다. 여기 간단한 쉘 스크립트가 있다. 이것을 grepfind라고 이름붙여서 사용할 수 있다.

#!/bin/sh
#save this in a file called grepfind and do a "chmod 755 grepfind"
#
if test $@ = 0 -o "$1" = "-h" -o "$1" = "-help" ; then
echo 'grepfind ─ recursively descends directories and egrep all files '
echo
echo 'Usage: grepfind [-help][-h](start_directory] egrep_search_pattern'
echo
echo 'The surrent directory is used as start_directory if parameter'
echo 'start_directory is omitted. The search is case insensitive.'
echo 'Multiple occurrences of control characters are replaced by a single'
echo 'space. This makes it possible to grep around in files that contain'
echo 'binary data and strings without setting the terminal accidently'
echo 'to graphics mode.'
echo
echo 'Example : grepfind/home "hello world"
else
if ["$2" = "" ];then
find . -type f -exec egrep -i "$1" /dev/null {} \;|sed -e 's/[^-~][^-~]*//g'
else
if [-d "$1" ] ;then
find $1 -type f -exec egrep -i "$2" /dev/null {} \;|sed -e 's/[^-~][^-~]*//g'
else
echo "ERROR: $1 is not a directory"
fi
fi
fi
#_END_OF_grepfind

5.17 world writable file 찾기

#find / -type f -perm -2 -exec ls -lg {} \;

    world writable directory 찾기

#find / -type d -perm -2 -exec ls -ldg {} \;

5.18 ext2에서 ext3로 업그레이드 하기

#mke2fs -j /dev/hda[X] (X: disk number)
#tune2fs "

ext3에서 ext2로 다운그레이드 하기
#debugfs
#open -f -w /dev/hda[X]
features
features -has_journal -needs_recovery
quit

5.19 logon기록을 보려면

    #last


5.20 remote환경에 있는 윈도우 폴더 마운트하기

    /etc/fstab 에 물론 마운트 정보 입력

//win_pc/win_folder /linux/mount/point smbfs user,noauto,username=Winuser_name 0 0

5.21 터미널에서 디렉토리, 파일 색상 변경

    /etc/DIR_COLORS


5.22 서브 디렉토리까지 한번에 생성

    mkdir -p sub/sub1/sub2/ ....


5.23 alias 적용안하기

#\rm file1
쉘을 빠져나가기까지 alias를 적용 안하려면
#unalias rm

5.24 이동한 바로 직전의 디렉토리로

    #cd -


5.25 일정기간 동안 접근하지 않는 파일 삭제하기

$find /var/spool/mail -atime +5 -exec rm {} \;
<--- /var/spool/mail 아래 있는 디렉토리에서 5일동안 접근하지 않는 파일(-atime +5)은
삭제하라는 명령어

혹은 3일 이전의 파일을 지우고자 한다면

$find /tmp/log/ -mtime +7 -exec rm -rf {} \;

5.26 setuid가 설정된 루트쉘 검색

#find . -user root -perm 4755 -print
그렇게 되면 4755 퍼미션이 아니면 문제가 생길 것이다. 이런 경우에는 다음과 같이 명령을 내린다.

#ls -alR / |grep rws
#ls -alR / | grep r-s
#ls -alR / |grep -- --s
이렇게 하면 루트 쉘을 찾아낼 수 있다.

5.27 MySQL Connection Failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111) 에러가 나는 경우

MySQL 데몬 프로세스가 돌아가지 않는 것이며 최신 버전은 ./safe_mysqld -u & 해서 실행해야한다.

    그럼에도 불구하고 sql 데몬이 실행이 안되고 /var/log/mysql.log에 다음과 같은 메시지가 표출될 경우가 있다.

    040720 15:57:28 /usr/libexec/mysqld: Table 'mysql.host' doesn't exist
    040720 15:57:28 mysqld ended
    이것은 DB를 설치하고 data base를 생성하지 않았기 때문이다. 다음의 커맨드로 DB를 생성시키도록 한다.
    $mysql_install_db
    mysql이라는 DB를 생성하고 그 안에 user와 host 정보를 가지게 된다. 그럼에도 에러가 나타난다면 퍼미션 문제일 가능성이 크다. /var/lib/mysql안의 내용을 mysql 소유자로 권한을 변경시켜서 데몬을 구동시켜 본다.
    $chown -R mysql.mysql /var/lib/mysql

5.28 특정 유저만 su 허락하기

. 휠 그룹에 등록

 vi /etc/group ------------  wheel:x:10:root,wantedid

2. su 권한 제한

chgrp wheel /bin/su
chmoe 4770 /bin/su

5.29 작업중 로그인 막기

시스템을 공사중일 때, root 이외의 다른 사용자를 로그인 못하게 해야 할 때가 있죠?
그럴 때는, /etc/nologin 이라는 파일을 만들어,
공사중 또는 Under Construction이라는 공지를 넣으면 됩니다.


5.30 크기가 가장 큰 파일, 디렉토리 찾기

가장 큰 디렉토리를 찾으려면,

du -S | sort -n

가장 큰 파일을 찾으려면,

ls -lR | sort +4n

5.31 현재 디렉토리의 크기만을 파악할때

[root@dev2 local]# du -c -h --max-depth=0 *
6.4M apache
35M bin
43M dns
1.7M doc
42k etc
1.0k games
42k geektalkd
1.1M gnuws
1.1M include
41k info
19M jakarta-tomcat-3.2.3
0 jre
15M jre118_v3
25M lib
62k libexec
1011k man
1.3M mm.mysql.jdbc-1.2c
937k sbin
3.8M share
1.8M shoutcast-1-8-3-linux-glibc6
5.2M ssl
159M total

5.32 시스템 정보 감추기

/etc/inetd.conf 파일을 열어서,

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd -h

5.33 메모리를 가장 많이 잡아먹는 프로세스 알아내기

ps -aux | sort +4n

또는

ps -aux | sort +5n

5.34 FTP로 들어온 사용자 확인하기

ftpwho
ftpcount


5.35 원하지 않는 사용자 죽이기

[root@dream /root]# skill -KILL sunny

위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다.
그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠?
그럴때는

[root@dream /root]# skill -KILL -v pts/14

이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.


5.36 몇일 이상된 파일만 mv또는 cp

#find ./ -mtime +10 | awk ' { print "mv "$1" ./babo" } ' | sh

find의 -mtime +10은 수정된지 10일 이상인 것만 찾는다. 이것을 이용해 나온 파일들을 ./babo 디렉토리 아래로 move


5.37 터미널에서 백스페이스를 누르면 ^H 와 같은 이상한 문자가 출력되는 현상

이 문제는 터미널에서 백스페이스를 어떠한 방식으로 인식하느냐의 문제에서 발생한다. 일반적으로 백스페이스는 ^?^H로 나타내어지는데 터미널에서 ^H만을 백스페이스로 간주한다면, 이와 같은 문제가 발생하게 됩니다. 보통 그 자리에서 CTRL + h를 백스페이스 대용으로 써도 되고 export TERM="vt100" 로 터미널을 설정해도 되고 stty erase ^H 로 키보드 입력값을 조정해도 된다.


5.38 텔넷이나 ftp 외부 사용시 root로 접속 가능하게 하는 방법

레드헷계열은 공통이다.

telnet
/etc/securetty
이파일은 root가 로그인가능한 터미널(tty)장치들을 나열해 둔 것이다.
tty1
tty2
tty3
tty4
tty5
tty6
tty7
tty8

이 장치명은 가상터미널을 의미하는 것으로 root로 이런 가상터미널을 통한 접속이 허용된다는 것을뜻한다. 그리고
ttyp0
ttyp1
ttyp2
ttyp3

등은 pseudo 터미널을 통해서 root의 접속이 가능함을 뜻하므로 원격지에서 root로 접속을 막으려면 다음설정과 같이 이 pseudo터미널을 모두 주석처리하면 된다. 그리고, 이 /etc/securetty파일에 다음과 같은 것을 볼 수도 있을 것입니다.
ttyS0
ttyS1
ttyS2
ttyS3

등은 시리얼라인 또는 모뎀을 통한 root의 접속을 허용한다는 것을 뜻한다.

FTP
나의 경우 ProFtp 를 사용하고 있는데 proftp 의 경우 루트접속을 가능케 하려면 /etc/proftpd/ftpusers 파일을 여어서 root 를 주석처리해주면 된다.

SSH
나는 텔넷은 사용하지 않고 ssh 을 열어두고있다. 텔넷보다는 보안상 좀더 안정적이라고할수있겠다. ssh 의 경우 7.1 버전까지는 기본적으로 root 접속이 가능하다. 하지만 7.3버전에서는 접속이 안되니 ssh 에서 루트 접속이 가능하게하려면 ssh 설정파일인 /etc/ssh/sshd_config 파일을 열어서 PermitRootLogin 부분을 yes 로 해주시면 된다.

PermitRootLogin yes

5.39 여러 파일 안에 있는 내용중 특정단어를 바꾸고 싶을 때

1. $ sed -e 's/aaaa/bbbb/g' < a.php > b.php
하면 b.php 로 바뀐 파일이 나온다네요

2. find 와 perl 의 조합으로 가능합니다.
find / -name 'aaa.php' -type f -exec perl -pi -e 's/aaa/bbb/g' {} \;

3. 하위 디렉토리까지 찾아서 파일 내의 특정한 내용을 바꾸는 명령입니다.
find . -name *.html | awk '{ print "cat "$1" | sed "s/바꾸고싶은말/바뀔말/g" >"$1 }' | sh

저는 이런식으로 하고 있습니다..
find . -name *.html -exec perl -pi -e 's/바뀌고/바뀔/g' {}\; 위에서 찾을때 '*.html' 식으로 해야할 수도 있다.

5.40 윈도우 디렉토리 마운트후 한글 디렉토리가 깨져보일 때

윈도우 디렉토리를 그냥 마운트하면 한글로 된 파일이나 디렉토리가 ??로 나타나게 된다. 이때 다음과 같이 마운트를 하면 한글 디렉토리가 제대로 보인다.

#mount -t vfat -o iocharset=cp949 /dev/hd* /mnt/win

5.41 tail 명령어 활용

# tail

man tail 로 자세한 사용법을 알 수 있다. 가장 많이 사용하는 옵션으로는 -f 가 있는데 기본적으로 끝에서 10 줄까지를 보여준다. tail 은 계속 크기가 변하는 파일을 모니터링 할때 유용한 명령어인데 보안적으로나 기타 여러가지에 있어서 아주 유용한 명령어이다. 실제 본인이 보안 프로젝트를 하면서 tail 은 상당히 강조를 했다.

tail -f /var/log/messages

messages 파일은 누가 뭐라고 해도 가장 중요한 log 파일이다. 실제 항상 실행시켜놓고 있는 명령어이다. 또한 몇몇 중요한 log 파일들이 있는데 secure, xferlog 등등이 있는데 /etc/syslog.conf 파일에서 모든 log 를 한 파일로 남기게 해서 하나의 파일만 모니터링을 하고 있으면 좋을 것이다.
일단 sendmail 이 시작되지 않을 경우를 예를 들어 보자. 창을 두개을 열고 하나의 창에서 tail -f /var/log/maillog를 실행한다. 그리고 다른 창에서 sendmail 을 재시작 시켜보자. 그러면 tail -f 를 실행한 곳에서 maillog 에 기록되는 상황이 계속 출력이 될것이다. 이것을 이용하면 에러 대처에 많은 도움이 될수 있을 것이다.

tail 명령어에서 두번째로 많이 쓰는 옵션은 -n 일 것이다.
-n 옵션은 원하는 수 라인 만큼 값을 출력하는 것이다. -c 는 bytes 만큼.

tail 의 반대 명령어는 head 이다. head 명령어는 앞에서 부터 보여주는 명령어이다.

5.42 shell prompt 변경하기

일단 prompt 는 PS1 이라는 환경 변수를 이용한다. 즉 root 권한이 있다면 /etc/bashrc나 /etc/profile 에서 PS1 변수가 지정이 되어 있는것을 수정하여 전체 유저의 prompt 를 수정할수 있다. 만약 개인 유저가 prompt 를 수정하고 싶다면 계정 홈의 .bashrc 의 제일 마지막 라인에 PS1="" 을 설정해 주면 된다. PS1 에 사용되는 예약어에 대해서는 아래를 참고 하도록 하면 된다.

\t 현재 시간을 HH:MM:SS 형식으로 표시
\d 날자를 "요일 월 일" 형식으로 표시 (예, "Tue May 26")
\n 개행문자
\s 쉘의 이름, $0 의 베이스 이름 (마지막 슬래쉬 뒷 부분)
\w 현재 작업 디렉토리
\W 현재 작업 디렉토리의 베이스 이름
\u 현재 사용자의 사용자명
\h 호스트 이름
\# 이 명령의 명령 번호
\! 이 명령의 히스토리 번호
\$ 유효 UID가 0 이면 if the effective UID is 0, a #, 그렇지 않으면 $
\nnn 팔진수 nnn에 해당하는 문자
\\ 백슬래쉬
\[ 비출력 문자의 시퀀스를 시작한다. 프롬프트에 터미널 제어 시퀀스를 넣을 때 사용한다.
\] 비출력 문자의 시퀀스를 마친다.

5.43 kernel 파라미터 조정하기

보통 커널의 파라미터를 조정할때 proc 에서 echo 를 이용하여 redirect로 직접 쓰는 경우가 많았다. 이렇게 조정을 할 경우에는 또 rc.local 같은 파일에 따로 기입을 해 줘야 하는 불편함이 있었다. RedHat 6.2 이후 배포판에는 sysctl 이라는 package가 추가되어 이것들을 관리를 할수 있게 되었다. 일단 조정할수 있는 모든 parameter 들은

$ sysctl -a

명령으로 확인을 할수가 있다. 그리고 특정값을 수정하기 위해서는 /etc/sysctl.conf 에 해당 키(이건 sysctl -a 명령에서 리스트를 확인할수 있다)와 키값을 지정한 다음

$ sysctl -p

명령으로 바로 적용을 시킬수 있다. 물론 sysctl.conf 에 기입이 되면 부팅시 마다 자동으로 적용이 된다.
만약 잠시만 바꾸어 보고 싶다면

$ sysctl -w net.ipv4.icmp_echo_ignore_all=0

과 같이 직접 값을 넣어 줄수도 있다. 이럴 경우에는 부팅이 되어 있는 순간만 적용이 된다. -p 옵션은 sysctl.conf 가 아닌 다른 파일을 설정 파일로 지정을 할수 있게 한다. 옵션값이 없으면 default 로 /etc/sysctl.conf 를 읽어 들이며 따로 path 를 지정하면 해당 path 에있는 파일을 읽어 들인다.


5.44 사용자별 du -h 값 보기

du 4.0p 이상

du -h --max-depth=1 /home/ | less

5.45 하룻동안 만들어진 파일 검색하기

find / -ctime -1

5.46 apache 설정 파일 문법 오류 검색

httpd.conf를 설정한 후에 쉘에서

bash# httpd -t

명령을 실행해 보도록 한다. 그러면 apache가 자체적으로 httpd.conf에서 에러가 있는지 없는지를 살펴 보게 된다.


5.47 레드햇 패키지 버전을 알고 싶을 때

#cat /etc/redhat-release


5.48 새로운 배포본 설치를 위한 Multi LILO

리눅스를 오래 사용하다 보면 나름대로 입맛에 맞게 튜닝이 되어 있을 것이다. 이때 새로운 배포본이나 호기심을 자극하는 작업때문에 리눅스를 새로이 설치할 경우가 많다. 이럴 경우 중요 세팅 파일이나 작업 데이타 파일등을 백업을 해놓고 새롭게 리눅스를 설치할 텐데 간혹 다시 이전 상태로 복귀해야할 상황에 부딪히곤 한다. 이때 원래 이전 셋팅으로 되돌리기 위해선 상당히 번거로운 작업을 해야하는데 이때 Multi LILO를 이용하면 편리하다.

먼저 최초 리눅스 설치시 하드디스크가 하나라면 5GB 정도 나누어 비워 둔다. 혹은 여분의 하드 디스크가 있으면

Posted by 1010
반응형

<html>
<head>
<title> 미디어 플레이어 제어 </title>

</head>

<body>
<OBJECT ID="Player"
  CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
  <PARAM name="autoStart" value="True">
  <PARAM name="URL" value="mms://mmc.daumcast.net/mmc/1/500/0902600000101h.wmv ">
</OBJECT>

<SCRIPT FOR="Player" EVENT="buffering(Start)">
var idTimer;
if(Start == true)
{
 idTimer = setInterval("setStatus()", 1000);
}
else
{
 clearInterval(idTimer);
}
</SCRIPT>
<SCRIPT FOR="Player" EVENT="StatusChange()">
window.status = Player.status;

</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
<!--
function setStatus()
{
 var bf = parseInt(Player.network.bufferingProgress);
 if(bf < 100)
 {
  window.status = "버퍼링 중 : " + bf + " %";
 }
 else
 {
  window.status = "버퍼링 완료";
 }
}

//-->
</SCRIPT>
</body>
</html>







<html>
<head>
<title> 미디어 플레이어 제어 </title>
</head>

<body>
<OBJECT ID="Player"
CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
<PARAM name="autoStart" value="True">
<PARAM name="URL" value="mms://mmc.daumcast.net/mmc/1/500/0902600000101h.wmv">
</OBJECT>
uiMode<select onchange="setUI(this.options[this.selectedIndex].value)">
<option value="invisible">invisible
<option value="none">none
<option value="mini">mini
<option value="full">full
</select>
<input type="button" value="volume +10" onclick="setVol('+')">
<input type="button" value="volume -10" onclick="setVol('-')">
mute <input type="checkbox" onclick="mute(this.checked)">
<input type="button" onclick="setPos(-10)" value="10초 전">
<input type="button" onclick="setPos(10)" value="10초 뒤">
<input type="button" onclick="Player.controls.play();" value="재생">
<input type="button" onclick="Player.controls.stop();" value="정지">
<input type="button" onclick="Player.controls.pause();" value="일시정지">

<SCRIPT LANGUAGE="JavaScript">
<!--
function setUI(str)
{
Player.uiMode = str;
}
function setPos(v)
{
Player.controls.currentPosition += v;
}
function setVol(flag)
{
if(flag == '+')
Player.settings.volume += 10;
else
Player.settings.volume -= 10;
}

function mute(stat)
{
if(stat)
Player.settings.mute = true;
else
Player.settings.mute = false;
}
//-->
</SCRIPT>
</body>
</html>
<script language=javascript>
<!--
document.write("<iframe src='http://lcs.naver.com/u{"+document.URL+"}' width=0 height=0 frameborder=0></iframe>");
//-->
</script>
Posted by 1010
반응형

1. 옵션을 HEAD안에...
<script language="JavaScript">
function openNewWindow(window) {
open (window,"NewWindow","left=0, top=0, toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, width=200, height=200");
}
</script>
<a href=javascript:openNewWindow("주소입력")>새창열기</a>

2. 링크에 옵션을 지정...
<a href="javascript:;" onclick="window.open('주소입력','name','resizable=no width=200 height=200');return false">새창열기</a>

* 옵션 *
새창 뛰울때 용도에 맞게 옵션 설정을 해줍니다. "YES" 또는 "NO" 로 지정 해주면 됩니다.
menubar - 파일, 편집, 보기....부분
toolbar - 뒤로, 앞으로, 새로고침 아이콘등이 있는 부분
directories - 연결 디렉토리가 표시되는 부분
location - 주소 입력창
status - 아래 브라우저 상태 바
scrollbars - 스크롤
resizable - 리사이즈 옵션



1.자동 띄우기

팝업창에 삽입
<html>
<head>
<title></title>
<script language="javascript">
<!--
function pop(){
window.open("팝업창파일", "pop", "width=400,height=500,history=no,resizable=no,status=no,scrollbars=yes,menubar=no")
}
//-->
</script>
</head>
<body onload="javascript:pop()">
이벤트 팝업창을 띄우기
</body>
</html>  


2.프레임이 있는 팝업창 닫기

팝업창에 삽입
<html>
<head>
<title></title>
<script language="Javascript">
<!--
function frameclose() {
parent.close()
window.close()
self.close()
}
//-->
</script>
</head>
<body>
<a href="javascript:frameclose()">프레임셋 한방에 닫기</a>
</body>
</html>


3.팝업창 닫고 프레임이 없는 부모창에서 원하는 페이지로 이동하기

팝업창에 삽입
<html>
<head>
<title></title>
<script language="javascript">
<!--
function MovePage() {
window.opener.top.location.href="연결할파일"
window.close()
}
//-->
</script>
</head>
<body>
<a href="javascript:MovePage();">자세한내용보기</a>
</body>
</html>


4.팝업창 닫고 프레임이 있는 부모창에서 원하는 페이지로 이동하기

팝업창에 삽입하고 팝업창의 설정은 프레임셋 페이지에 해야함
오픈창이 아닐경우에는 window.top.프레임이름.location.href="연결할파일" 적용한다
<html>
<head>
<title></title>
<script language="javascript">
<!--
function MovePage() {
window.opener.top.프레임이름.location.href="연결할파일"
//팝업창이 아닌것우..
window.close()
}
//-->
</script>
</head>
<body>
<a href="javascript:MovePage();">자세한내용보기</a>
</body>
</html>


5.팝업창 자동으로 닫기

팝업창에 삽입
<html>
<head>
<title>Close Window Timer</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
<!--
function closeWin(thetime) {
setTimeout("window.close()", thetime); //1000 은 1초를 의미합니다.
}
//-->
</script>
</head>
<body onLoad="closeWin('5000')">
이창은 5초후 자동으로 창이 닫힘니다.<br>
</body>
</html>


6.프레임 나눈 팝업창 한번에 닫기

팝업창에 삽입
<html>
<head>
<title>Close Window Timer</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
<!--
function closeWin(thetime) {
setTimeout("window.close()", thetime); //1000 은 1초를 의미합니다.
}
//-->
</script>
</head>
<body onLoad="closeWin('5000')">
이창은 5초후 자동으로 창이 닫힘니다.<br>
</body>
</html>


7.하루동안 팝업창 띄우지 않기 소스 예제1

부모창인 index.htm에 삽입
<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="javascript">
<!--
function getCookie(name)
{
var Found = false
var start, end
var i = 0
// cookie 문자열 전체를 검색
while(i <= document.cookie.length)
{
start = i
end = start + name.length
// name과 동일한 문자가 있다면
if(document.cookie.substring(start, end) == name)
{
Found = true
break
}
i++
}
// name 문자열을 cookie에서 찾았다면
if(Found == true) {
start = end + 1
end = document.cookie.indexOf(";", start)
// 마지막 부분이라 는 것을 의미(마지막에는 ";"가 없다)
if(end < start)
end = document.cookie.length
// name에 해당하는 value값을 추출하여 리턴한다.
return document.cookie.substring(start, end)
}
// 찾지 못했다면
return ""
}
function openMsgBox()
{
var eventCookie=getCookie("memo");
if (eventCookie != "no")
window.open('팝업창파일','_blank','width=300,height=300,top=50,left=150');
//팝업창의 주소, 같은 도메인에 있어야 한다.
}
openMsgBox();
//-->
</script>
</head>
<body>
</body>
</html>


팝업창인 pop.htm에 삽입
<html>
<head>
<title></title>
<head>
<script language="JavaScript">
<!--
function setCookie( name, value, expiredays )
{
var todayDate = new Date();
todayDate.setDate( todayDate.getDate() + expiredays );
document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + todayDate.toGMTString() + ";"
}
function closeWin()
{
if ( document.myform.event.checked )
setCookie("memo", "no" , 1); // 1일 간 쿠키적용

}
//-->
</script>
</head>
<body onunload="closeWin()">
<form name="myform">
<input type="checkbox" name="event">다음부터 이 창을 열지않음
<input type=button value="닫기" onclick="self.close()">
</form>
</body>
</html>


8.하루동안 팝업창 띄우지 않기 소스 예제2

부모창인 index.htm에 삽입
<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<head>
<SCRIPT LANGUAGE="JavaScript">
<!--
function change(form)
{
if (form.url.selectedIndex !=0)
parent.location = form.url.options[form.url.selectedIndex].value
}
function setCookie( name, value, expiredays )
{
var todayDate = new Date();
todayDate.setDate( todayDate.getDate() + expiredays );
document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + todayDate.toGMTString() + ";"
}
function getCookie( name )
{
var nameOfCookie = name + "=";
var x = 0;
while ( x <= document.cookie.length )
{
var y = (x+nameOfCookie.length);
if ( document.cookie.substring( x, y ) == nameOfCookie ) {
if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 )
endOfCookie = document.cookie.length;
return unescape( document.cookie.substring( y, endOfCookie ) );
}
x = document.cookie.indexOf( " ", x ) + 1;
if ( x == 0 )
break;
}
return "";
}
if ( getCookie( "Notice" ) != "done" )
{
noticeWindow = window.open('pop.htm','notice','toolbar=no,location=no,directories=no,status=no,
menubar=no,scrollbars=no, resizable=no,width=400,height=400');
//winddow.open의 ()의 것은 한줄에 계속 붙여써야 오류가 안남, 줄바뀌면 오류남
noticeWindow.opener = self;
}
//-->
</script>
</head>
<body>
</body>
</html>


팝업창인 pop.htm에 삽입
<html>
<head>
<title></title>
<head>
<SCRIPT language="JavaScript">
<!--
function setCookie( name, value, expiredays )
{
var todayDate = new Date();
todayDate.setDate( todayDate.getDate() + expiredays );
document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + todayDate.toGMTString() + ";"
}


function closeWin()
{
if ( document.forms[0].Notice.checked )
setCookie( "Notice", "done" , 1);
self.close();
}
//-->
</script>
</head>
<body onunload="closeWin()">
<form>
<input type=CHECKBOX name="Notice" value="">다시 팝업 안뜸
<a href="javascript:window.close()">닫기</a>
</form>
</body>
</html>


9.같은 브라우져에서 팝업 띄우기 않기

부모창인 index.htm에 삽입
<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="javascript">
<!--
function getCookie(name)
{
var Found = false
var start, end
var i = 0
// cookie 문자열 전체를 검색
while(i <= document.cookie.length)
{
start = i
end = start + name.length
// name과 동일한 문자가 있다면
if(document.cookie.substring(start, end) == name)
{
Found = true
break
}
i++
}
// name 문자열을 cookie에서 찾았다면
if(Found == true) {
start = end + 1
end = document.cookie.indexOf(";", start)
// 마지막 부분이라 는 것을 의미(마지막에는 ";"가 없다)
if(end < start)
end = document.cookie.length
// name에 해당하는 value값을 추출하여 리턴한다.
return document.cookie.substring(start, end)
}
// 찾지 못했다면
return ""
}
function openMsgBox()
{
var eventCookie=getCookie("memo");
if (eventCookie != "no")
window.open('팝업창파일','_blank','width=300,height=300,top=50,left=150');
//팝업창의 주소, 같은 도메인에 있어야 한다.
}
openMsgBox();
//-->
</script>
</head>
<body>
</body>
</html>


팝업창인 pop.htm에 삽입
<html>
<head>
<title></title>
<head>
<script language="JavaScript">
<!--
function setCookie( name, value, expiredays )
{
//같은 창에서만 안띄움.
//expiredays 값은 상관없음.
document.cookie = name + "=" + escape( value ) + "; path=/;";
function closeWin()
{
if ( document.myform.event.checked )
setCookie("memo", "no" , 1); // 1일 간 쿠키적용

}
//-->
</script>
</head>
<body onunload="closeWin()">
<form name="myform">
<input type="checkbox" name="event">다음부터 이 창을 열지않음
<input type=button value="닫기" onclick="self.close()">
</form>
</body>
</html>


10.팝업창 가운데에 자동띄우기

팝업창에 삽입
<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
<!--
function winCentre() {
if (document.layers) {
var sinist = screen.width / 2 - outerWidth / 2;
var toppo = screen.height / 2 - outerHeight / 2;
} else {
var sinist = screen.width / 2 - document.body.offsetWidth / 2;
var toppo = -75 + screen.height / 2 - document.body.offsetHeight / 2;
}
self.moveTo(sinist, toppo);
}
//-->
</script>
</head>
<body onLoad="winCentre()">
</body>
</html> 


11.부모창에서 클릭하면 팝업창 가운데에 띄우기

부모창에 삽입
<html>
<head>
<title></title>
<head>
<script language="JavaScript">
<!--
var win = null;
function NewWindow(mypage,myname,w,h,scroll){
LeftPosition = (screen.width) ? (screen.width-w)/2 : 0;
TopPosition = (screen.height) ? (screen.height-h)/2 : 0;
settings =
'height='+h+',width='+w+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scroll+',
resizable'
win = window.open(mypage,myname,settings)
}
//-->
</script>
<body>
<a href="팝업창파일" onclick="NewWindow(this,'name','100','100','yes');return false">
링크</a>
</body>
</html>


12.같은 브라우져에서만 팝업 띄우기 않기

부모창인 index.htm에 삽입 _새로 브라우져를 열면 팝업창이 뜸
<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="javascript">
<!--
function getCookie(name)
{
var Found = false
var start, end
var i = 0
// cookie 문자열 전체를 검색
while(i <= document.cookie.length)
{
start = i
end = start + name.length
// name과 동일한 문자가 있다면
if(document.cookie.substring(start, end) == name)
{
Found = true
break
}
i++
}
// name 문자열을 cookie에서 찾았다면
if(Found == true) {
start = end + 1
end = document.cookie.indexOf(";", start)
// 마지막 부분이라 는 것을 의미(마지막에는 ";"가 없다)
if(end < start)
end = document.cookie.length
// name에 해당하는 value값을 추출하여 리턴한다.
return document.cookie.substring(start, end)
}
// 찾지 못했다면
return ""
}
function openMsgBox()
{
var eventCookie=getCookie("memo");
if (eventCookie != "no")
window.open('팝업창파일','_blank','width=300,height=300,top=50,left=150');
//팝업창의 주소, 같은 도메인에 있어야 한다.
}
openMsgBox();
//-->
</script>
</head>
<body>
</body>
</html> 


팝업창인 pop.htm에 삽입
<html>
<head>
<title></title>
<head>
<script language="JavaScript">
<!--
function setCookie( name, value, expiredays )
{
//같은 창에서만 안띄움.
//expiredays 값은 상관없음.
document.cookie = name + "=" + escape( value ) + "; path=/;";
}
function closeWin()
{
if ( document.myform.event.checked )
setCookie("memo", "no" , 1); // 1일 간 쿠키적용
}
//-->
</script>
</head>
<body onunload="closeWin()">
<form name="myform">
<input type="checkbox" name="event">다음부터 이 창을 열지않음
<input type=button value="닫기" onclick="self.close()">
</form>
</body>
</html>


13.링크걸어서 지정된 사이즈로 열기

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language='JavaScript'>
<!--
function winopen(url)
{
window.open(url,"url","width=517,height=450,history=no,resizable=no,status=no,
scrollbars=yes,menubar=no");
}
//-->
</script>
</head>
<body>
<a HREF="javascript:winopen('주소')">링크걸기</a>
</body>
</html>


14.자동으로 지정된 크기로 브라우저 열기

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language='JavaScript'>
<!--
window.resizeTo(300,300);
window.moveTo(0,0);
//-->
</script>
</head>
<body>
<!--원하는 가로,세로의 크기를 입력해준다.-->
</body>
</html>


15.해상도에 맞추어 전체장으로 늘어남

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
function winMaximizer() {
if (document.layers) {
larg = screen.availWidth - 10;
altez = screen.availHeight - 20;
} else {
var larg = screen.availWidth;
var altez = screen.availHeight;
}
self.resizeTo(larg, altez);
self.moveTo(0, 0);
}
</script>
</head>
<body onload="winMaximizer()">
해상도에 맞추어 전체장으로 늘어남
</body>
</html>


16.이미지 클릭시 html문서없이 큰이미지로 새창띄우기

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
var win1Open = null
function displayImage(picName, windowName,
windowWidth, windowHeight){
return window.open(picName,windowName,"toolbar=no,

scrollbars=no,resizable=no,width=" + (parseInt(windowWidth)+20) + ",height=" + (parseInt(windowHeight)+15))
} function winClose(){
if(win1Open != null) win1Open.close()
} function doNothing(){}
</script> <script language="JavaScript1.1">
function displayImage(picName, windowName,

windowWidth, windowHeight){
var winHandle = window.open("" ,windowName,"toolbar=no,scrollbars=no,

resizable=no,width=" + windowWidth + ",height=" + windowHeight)
if(winHandle != null){
var htmlString = "<html><head><title>Picture</title></head>"
htmlString += "<body leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>"
htmlString += "<a href=javascript:window.close()><img src=" + picName + " border=0
alt=닫기></a>"
htmlString += "</body></html>"
winHandle.document.open()
winHandle.document.write(htmlString)
winHandle.document.close()
}
if(winHandle != null) winHandle.focus()
return winHandle
}
</script>
</head>
<body>
<a href="javascript:doNothing()"
onClick="win1Open=displayImage('큰 이미지파일', 'popWin1', '300', '400')" onMouseOver="window.status='Click to display picture'; return true;" onMouseOut="window.status=''">
<img src=이미지파일" border="0"></a>
</body>
</html>


17.몇초후 웹페이지이동하기 소스예제1

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
function nextWin()
{location = "이동할 URL"}
</script>
</head>
<body onLoad="setTimeout('nextWin()', 1000)"> <!--1000 이 1초 입니다.-->
바로 이동한 원하는 사이트로 이동함
</body>
</html>


18.몇초후 웹페이지이동하기 소스예제2

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
self.location.replace('이동할 URL');
</script>
</head>
<body>
바로 이동한 원하는 사이트로 이동함
</body>
</html>


19.자동새로고침하기

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
<!--
setTimeout("history.go(0);", 3000); // 1초는 1000 입니다.
-->
</script>
</head>
<body>
자동새로고침하기
</body>
</html>


20.해상도에 따라 다른 웹페이지 열기

<html>
<head>
<title>..</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="JavaScript">
<!--
function redirectPage() {
var url800x600 = "main1.html"; //800*600 에서 열릴문서
var url1024x768 = "main2.html"; //1024*768 에서 열릴문서
var url1152x864 = "main3.html"; //1152*864 에서 열릴문서

if ((screen.width == 800) && (screen.height == 600))
window.location.href= url800x600;
else if ((screen.width == 1024) && (screen.height == 768))
window.location.href= url1024x768;
else if ((screen.width == 1152) && (screen.height == 864))
window.location.href= url1152x864;
else window.location.href= url800x600;
}
//-->
</script>
</head>
<body Onload="redirectPage()"> 
</body>
</html>


30.HTML파일 없이 이미지 사이즈에 맞게 팝업창 띄우기.
<script Language="Javascript">
<!-- //////////////////////////////////////////////////////////////
//*****************************************************************
// Web Site: http://www.CginJs.Com
// CGI 와 JavaScript가 만났을 때 = C.n.J ☞ http://www.CginJs.Com
// CGI 와 JavaScript가 만났을 때 = C.n.J ☞ webmaster@CginJs.Com
// C.n.J 자바스크립트 자동 생성 마법사 ☞ http://www.CginJs.Com
// C.n.J 자바스크립트(JavaScript) 가이드 ☞ http://www.CginJs.Com
// C.n.J CSS(Cascading Style Sheet) 가이드 ☞ http://www.CginJs.Com
// Editer : Web Site: http://www.CginJs.Com
//*****************************************************************
/////////////////////////////////////////////////////////////// -->
var cnj_img_view = null;
function cnj_win_view(img){
img_conf1= new Image();
img_conf1.src=(img);
cnj_view_conf(img);
}

function cnj_view_conf(img){
if((img_conf1.width!=0)&&(img_conf1.height!=0)){
cnj_view_img(img);
} else {
funzione="cnj_view_conf('"+img+"')";
intervallo=setTimeout(funzione,20);
}
}

function cnj_view_img(img){
if(cnj_img_view != null) {
if(!cnj_img_view.closed) { cnj_img_view.close(); }
}
cnj_width=img_conf1.width+20;
cnj_height=img_conf1.height+20;
str_img="width="+cnj_width+",height="+cnj_height;
cnj_img_view=window.open(img,"cnj_img_open",str_img);
cnj_img_view.focus();
return;
}
</script>


<a href="javascript:cnj_win_view('../img/cnjlogo.gif')"><img src="../img/cnjlogo.gif" border="0" width="247" height="55"></a>

32.이미지사이즈에 맞게 새창이 열리며 휠마우스 효과를 내줌
그리고 메인(imgmove-main.html)에서 새창 띄워주는 부분

<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function cnjOpen() {
window.open('img-move.html','cnjOpenWin','width=350,height=250,toolbar=0,scrollbars=0,location=0,status=0,menubar=0,resizable=0');
}
// End -->
</script>
<a href="javascript:cnjOpen()"><img src="test.jpg" width="200" height="150" border="0"></a>
</center>

이 부분은 이미지를 보여줄 새창(img-move.html)입니다.
<style>
body {cursor:move;}
</style>
<body leftmargin=0 topmargin=0 marginwidth=0 marginheight=0 onLoad="fitWindowSize();">

<SCRIPT LANGUAGE="JavaScript">
// 이미지는 별도로 제공하지 않습니다.
<!-- CGI 와 JavaScript가 만났을 때=CnJ ☞ http://www.cginjs.com -->
<!-- CGI 와 JavaScript가 만났을 때=CnJ ☞ webmaster@cginjs.com -->
var ie = 1;
var windowX, windowY;
var bLargeImage = 0;
var x,y;

var InitX = 500;

// 이미지가 새창에 맞게 조절되는 부분

function fitWindowSize()
{
if( ie )
{
window.resizeTo( InitX, InitX );
width = InitX - (document.body.clientWidth - document.images[0].width);
height = InitX - (document.body.clientHeight - document.images[0].height);
windowX = (window.screen.width-width)/2;
windowY = (window.screen.height-height)/2;
if( width > screen.width-50 )
{
width = screen.width-50;
windowX = 20;
bLargeImage = 1;
}
if( height > screen.height-80 )
{
height = screen.height-80;
windowY = 20;
bLargeImage = 1;
}
window.moveTo( windowX, windowY );
window.resizeTo( width, height+4 );
}
else
{
window.innerWidth = document.layers[0].document.images[0].width;
window.innerHeight = document.layers[0].document.images[0].height;
}
}

// 휠마우스 효과

function move() {
if(bLargeImage){ window.scroll(window.event.clientX - 50,window.event.clientY -50);
}
}

// 오른쪽 왼쪽 마우스 클릭시 창닫는 부분

function click() {
if ((event.button==1) || (event.button==2) || (event.button==3)) {
top.self.close();
}
}
document.onmousedown=click

</script>
<img src="http://www.cginjs.com/cgi/js/test.jpg" border="0" ONMOUSEMOVE="move();">

Posted by 1010
02.Oracle/DataBase2009. 1. 19. 13:43
반응형

import java.sql.Clob;
import weblogic.jdbc.common.OracleClob;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.CLOB;
import org.apache.commons.dbcp.DelegatingResultSet;


String query1 = "select content from "+table+" where no="+ no + " for update";

con = getConnection();
con.setAutoCommit(false);//꼭 setAutoCommit을 false로 지정

pstmt = con.prepareStatement(query1);
rs = pstmt.executeQuery();

while (rs.next()){

 /**********************************************
 * Tomcat
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer writer = ((CLOB)clob).getCharacterOutputStream();
 Reader src = new CharArrayReader(contentData.toCharArray());
 char[] buffer = new char[1024];
 int read = 0;
 while ( (read = src.read(buffer,0,1024)) != -1)
 {
   writer.write(buffer, 0, read); // write clob.
 }
 src.close();               
 writer.close();   


 /**********************************************
 * weblogic
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer writer = ((OracleClob)clob).getCharacterOutputStream();
 Reader src = new CharArrayReader(contentData.toCharArray());
 char[] buffer = new char[1024];
 int read = 0;
 while ( (read = src.read(buffer,0,1024)) != -1)
 {
   writer.write(buffer, 0, read); // write clob.
 }
 src.close();               
 writer.close();


 /**********************************************
 * sunone
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer characterStream = clob.setCharacterStream(0);
 characterStream.write(contentData);
 characterStream.close();


 /**********************************************
 * interstage

 * ********************************************/

 CLOB clob = ((OracleResultSet)((DelegatingResultSet)rs).getDelegate()).getCLOB(1);
 BufferedWriter writer = new BufferedWriter(clob.getCharacterOutputStream());
 writer.write(form.getContent());
 writer.close();

}

con.commit();
con.setAutoCommit(true);


출처 : http://www.okjsp.pe.kr/seq/98774

Posted by 1010
02.Oracle/DataBase2009. 1. 19. 13:43
반응형

1. 문자 함수
 1-1) CHR
 1-2) CONCAT 함수
 1-3) INITCAP 함수
 1-4) LOWER 함수
 1-5) LPAD 함수
 1-6) LTRIM 함수
 1-7) NLS_INITCAP 함수
 1-8) NLS_LOWER 함수
 1-9) NLSSORT 함수
 1-10) NLS_UPPER 함수
 1-11) REPLACE 함수
 1-12) RPAD 함수
 1-13) RTRIM 함수
 1-14) SOUNDEX 함수
 1-15) SUBSTR 함수
 1-16) TRANSLATE 함수
 1-17) TREAT 함수
 1-18) TRIM 함수
 1-19) UPPER 함수
 1-20) ASCII 함수
 1-21) INSTR 함수
 1-22) LENGTH 함수


2. 날짜 처리함수(datetime function)
 2-1) ADD_MONTHS 함수
 2-2) CURRENT_DATE 함수
 2-3) URRENT_TIMESTAMP 함수
 2-4) DBTIMEZONE 함수
 2-5) EXTRACT(datetime) 함수
 2-6) FROM_TZ 함수
 2-7) LAST_DAY 함수
 2-8) LOCALTIMESTAMP 함수 
 2-9) MONTHS_BETWEEN 함수
 2-10) NEW_TIME 함수
 2-11) NEXT_DAY 함수
 2-12) NUMTODSINTERVAL 함수
 2-13) NUMTOYMINTERVAL 함수
 2-14) ROUND(date) 함수
 2-15) SESSIONTIMEZONE 함수
 2-16) SYS_EXTRACT_UTC 함수
 2-17) SYSDATE 함수
 2-18) SYSTIMESTAMP 함수
 2-19) TO_DSINTERVAL 함수
 2-20) TO_TIMESTAMP 함수
 2-21) TO_TIMESTAMP_TZ 함수
 2-22) TO_YMINTERVAL 함수
 2-23) TRUNC(date) 함수
 2-24) TZ_OFFSET 함수


3.데이터 형 변환 함수(conversion function)
 3-1) ASCIISTR 함수
 3-2) BIN_TO_NUM 함수
 3-3) CAST 함수
 3-4) CHARTOROWID 함수
 3-5) COMPOSE 함수 
 3-6) CONVERT 함수
 3-7) HEXTORAW 함수
 3-8) NUMTODSINTERVAL 함수
 3-9) NUMTOYMINTERVAL 함수
 3-10) RAWTOHEX 함수
 3-11) RAWTONHEX 함수
 3-12) ROWIDTOCHAR 함수
 3-13) ROWIDTONCHAR 함수
 3-14) TO_CHAR(character) 함수
 3-15) TO_CLOB 함수
 3-16) TO_DSINTERVAL 함수
 3-17) TO_LOB 함수
 3-18) TO_MULTI_BYTE 함수
 3-19) TO_NCHAR(character) 함수
 3-20) TO_NCHAR(datetime) 함수
 3-21) TO_NCHAR(number) 함수
 3-22) TO_NCLOB 함수
 3-23) TO_NUMBER 함수
 3-24) TO_SINGLE_BYTE 함수
 3-25) TO_YMINTERVAL 함수
 3-26) TRANSLATE ... USING 함수
 3-27) UNISTR 함수


4. 기타함수(miscellaneous single row function)
 4-1) BFILENAME 함수
 4-2) COALESCE 함수
 4-3) DECODE 함수
 4-4) DEPTH 함수
 4-5) DUMP 함수
 4-6) EMPTY_BLOB 함수
 4-7) EMPTY_CLOB 함수
 4-8) EXISTSNODE 함수
 4-9) EXTRACT(XML) 함수
 4-10) EXTRACTVALUE 함수
 4-11) GREATEST 함수
 4-12) LEAST 함수
 4-13) NLS_CHARSET_DECL_LEN 함수
 4-14) NLS_CHARSET_ID 함수
 4-15) NLS_CHARSET_NAME 함수
 4-16) NULLIF 함수
 4-17) NVL2 함수
 4-18) PATH 함수
 4-19) SYS_CONNECT_BY_PATH 함수
 4-20) SYS_CONTEXT 함수
 4-21) SYS_DBURIGEN 함수
 4-22) SYS_EXTRACT_UTC 함수
 4-23) SYS_GUID 함수
 4-24) SYS_XMLAGG 함수
 4-25) SYS_XMLGEN 함수
 4-26) UID 함수
 4-27) USER 함수
 4-28) USERENV 함수
 4-29) VSIZE 함수
 4-30) XMLAGG 함수
 4-31) XMLCOLATTVAL 함수
 4-32) XMLCONCAT 함수
 4-33) XMLFOREST 함수
 4-34) XMLELEMENT 함수


5.그룹함수  Aggregate 함수
 5-1) AVG* 함수
 5-2) CORR* CORR* 함수
 5-3) COUNT* 함수
 5-4) COVAR_POP 함수
 5-5) COVAR_SAMP 함수
 5-6) CUME_DIST 함수
 5-7) DENSE_RANK 함수
 5-8) FIRST 함수
 5-9) GROUP_ID 함수
 5-10) Grouping 함수
 5-11) GROUPING_ID 함수
 5-12) LAST 함수
 5-13) MAX 함수
 5-14) MIN 함수
 5-15) PERCENTILE_CONT 함수
 5-16) PERCENTILE_DISC 함수
 5-17) PERCENT_RANK 함수
 5-18) RANK 함수
 5-19) REGR_(linear regression) function* 함수
 5-20) STDDEV 함수
 5-21) STDDEV_POP 함수
 5-22) STDDEV_SAMP 함수
 5-23) SUM 함수
 5-24) VAR_POP 함수
 5-25) VAR_SAMP 함수
 5-26) VARIANCE 함수
 5-27) Grouping sets 함수


6. Analytic 함수
 6-1) AVG* 함수
 6-2) CORR* CORR* 함수
 6-3) COUNT* 함수
 6-4) COVAR_SAMP 함수
 6-5) CUME_DIST 함수
 6-6) DENSE_RANK 함수
 6-7) FIRST 함수
 6-8) FIRST_VALUE 함수
 6-9) LAG 함수
 6-10) LAST_VALUE 함수
 6-11) LEAD 함수
 6-12) NTILE 함수
 6-13) RATIO_TO_REPORT 함수
 6-14) ROW_NUMBER 함수


7. 객체 참조 함수
 7-1) REF 타입


8. PseudoColumn을 의미하는 것
 8-1) ROWID 컬럼
 8-2) ROWNUM 컬럼


1-1) CHR 함수
--------------------------------------------------------------------------------

입력된 수의 바이너리 코드에 해당하는 문자를 반환한다.

【예제】
SQL> select chr(75)||chr(79)||chr(82)||chr(69)||chr(65)
   2    from dual;

CHR(7
-----
KOREA

SQL>

1-2) CONCAT 함수
--------------------------------------------------------------------------------

 입력되는 두 문자열을 연결하여 반환한다.
 입력되는 두 문자열의 타입이 다를 경우 다음과 같이 반환된다.

첫 번째 문자열 타입  두 번째 문자열 타입  반환되는 문자열 타입 CLOB  NCLOB  NCLOB NCLOB  NCHAR  NCLOB NCLOB  CHAR  NCLOB NCHAR  CLOB  NCLOB


【예제】
SQL> select concat('Republic of',' KOREA') from dual;

CONCAT('REPUBLICO
-----------------
Republic of KOREA

SQL>  


1-3) INITCAP 함수
--------------------------------------------------------------------------------

initcap('string‘) 함수는 입력 문자열 중에서
각 단어의 첫 글자를 대문자로 나머지는 소문자로 변환한 스트링을 반환한다

【예제】
SQL> select initcap('beautiful corea') from dual;

INITCAP('BEAUTI
---------------
Beautiful Corea

SQL>


1-4) LOWER 함수
--------------------------------------------------------------------------------

lower(string) 함수는 입력된 문자열을 소문자로 반환한다.

【예제】
SQL> select lower('Beautiful COREA') from dual;

LOWER('BEAUTIFU
---------------
beautiful corea

SQL>  


1-5) LPAD 함수
--------------------------------------------------------------------------------

lpad(char1,n,char2) 함수는
지정된 길이 n에서 문자 char1으로 채우고
남은 공간은 왼쪽부터 char2로 채워서 출력한다.

【형식】
lpad (char1, n [, char2] )

【예제】
SQL> select lpad ('Corea', 12, '*') from dual;

LPAD('COREA'
------------
*******Corea

SQL>


1-6) LTRIM 함수
--------------------------------------------------------------------------------

 LTRIM(문자열, 문자)함수는 문자열중
좌측으로부터 특정문자와 일치하는 문자를 제거하고 출력한다.

【형식】
ltrim(char [,set] )

【예제】
SQL> select LTRIM('xyxXxyLAST WORD','xy') from dual;

LTRIM('XYXXX
------------
XxyLAST WORD

SQL>


1-7) NLS_INITCAP 함수
--------------------------------------------------------------------------------

nls_initcap(‘string’) 함수는 입력 문자열 중에서
 각 단어의 첫 글자를 대문자로
           나머지는 소문자로 변환한 스트링을 반환한다.
 단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.

【형식】
nls_initcap ( char [,'nlsparam'] )

【예제】
SQL> select nls_initcap('beautiful corea', 'nls_sort=binary')
  2  from dual;

NLS_INITCAP('BE
---------------
Beautiful Corea

SQL> select nls_initcap('beautiful corea','nls_sort=XDutch')
  2  from dual;

NLS_INITCAP('BE
---------------
Beautiful Corea

SQL>


1-8) NLS_LOWER 함수
--------------------------------------------------------------------------------

nls_lower(‘string’) 함수는 입력 문자열을 모두 소문자로 변환한 스트링을 반환한다. 
 단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.

【형식】
nls_lower ( char [,'nlsparam'] )

【예제】
SQL> select nls_lower('CITTA''','nls_sort=XGerman') from dual;

NLS_LO
------
citta'

SQL>


1-9) NLSSORT 함수
--------------------------------------------------------------------------------

nlssort(‘string’) 함수는 입력 문자열을 소팅하여 스트링을 반환한다.
  단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.

【형식】
nlssort ( char [,'nlsparam'] )

【예제】
SQL> select * from emp
  2    order by nlssort(name, 'nls_sort=XDanish');

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1104 jijoe             220        100
      1103 kim               250        100

SQL>


1-10) NLS_UPPER 함수
--------------------------------------------------------------------------------

nls_upper(‘string’) 함수는 입력 문자열을 모두 소문자로 변환한 스트링을 반환한다.
  단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.

【형식】
nls_upper ( char [,'nlsparam'] )

【예제】
SQL> select nls_upper('gro?e') from dual;

NLS_U
-----
gro?e

SQL> select nls_upper('gro?e','nls_sort=XGerman')
  2  from dual;

NLS_UP
------
grosse

SQL>


1-11) REPLACE 함수
--------------------------------------------------------------------------------

이 함수는 문자열에서 지정한 문자를 다른 문자로 치환한다.
  치환될 문자를 지정하지 않으면 해당 문자를 삭제한다.

【형식】
replace (char, search_string [, replacement_string] )

【예제】
SQL> select replace('aaabb','a','b') from dual;

REPLA
-----
bbbbb

SQL> select replace('aaabb','a') from dual;

RE
--
bb

SQL>


1-12) RPAD 함수
--------------------------------------------------------------------------------

rpad(char1,n,char2) 함수는 지정된 길이 n에서 문자 char1으로 채우고
남은 공간은 오른쪽부터 char2로 채워서 출력한다.

【형식】
rpad (char1, n [, char2] )

【예제】
SQL> select rpad('Corea',12,'*') from dual;

RPAD('COREA'
------------
Corea*******

SQL>


1-13) RTRIM 함수
--------------------------------------------------------------------------------

 RTRIM(문자열, 문자)함수는 문자열중
 우측으로부터 특정문자와 일치하는 문자를 제거하고 출력한다.

【형식】
rtrim(char [,set] )

【예제】
SQL> select RTRIM('BROWINGyxXxy','xy') "RTRIM example" from dual;

RTRIM exam
----------
BROWINGyxX

SQL>


1-14) SOUNDEX 함수
--------------------------------------------------------------------------------

soundex(‘char’) 함수는 char과 같은 발음의 이름을 표현한다.

【예제】
SQL> select name from emp;

NAME
----------
Cho
Joe
kim
jijoe

SQL> select name from emp
  2  where soundex(name) = soundex('jo');

NAME
----------
Joe

SQL>


1-15) SUBSTR 함수
--------------------------------------------------------------------------------

substr(str,m,n) 함수는 문자열 str 중에서 특정 위치 m으로부터 특정 길이n 만큼의 문자를 출력한다.
  m이 0이나 1이면 문자열의 첫글자를 의미하고,
  n이 생략되면 문자열의 끝까지를 의미한다.
  m이 음수이면 뒤쪽으로부터의 위치를 의미한다.

 SUBSTRB는 character 대신 byte를 사용하고,
 SUBSTDC는 unicode를 사용하며,
 SUBSTR2는 UCS2 codepoint를 사용하고,
 SUBSTR4는 UCS4 codepoint를 사용한다.

【형식】
{SUBSTR|SUBSTRB|SUBSTRC|SUNBSTD2|SUBSTR4}
  ( string, position [,substring_length] )

【예제】
SQL> select substr('abcdesfg', 3,2) from dual;

SU
--
cd

SQL> select substr('abcdefg',3) from dual;

SUBST
-----
cdefg

SQL> select substr('abcdefg', -3,2) from dual; ☜ 뒤에서 3번째부터 2글자를 의미한다.
SU
--
ef

SQL>


1-16) TRANSLATE 함수
--------------------------------------------------------------------------------

TRANSLATE (‘char’,‘from_string’,‘to_string’) 함수는
 char 내에 포함된 문자중 from_string에 지정한 모든 각각의 문자를
                         to_string문자로 각각 변경한다.

【형식】
TRANSLATE ('char','from_string','to_string')

【예제】
SQL> select translate('ababccc','c','d') from dual;

TRANSLA
-------
ababddd

SQL> select translate('2KRW229',
  2  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  3  '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX') from dual;

TRANSLA
-------
9XXX999

SQL> select translate('2KRW229',
  2  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ','0123456789')
  3  from dual;

TRAN
----
2229

SQL>


1-17) TREAT 함수
--------------------------------------------------------------------------------

TREAT 함수는 선언된 타입을 변경함으로써, 수퍼타입을 서브타입인 것처럼 처리할 수 있도록 한다.

【형식】
TREAT ( expr AS [ REF] [schema . ] type )

【예제】
SQL> select x.p.empno from person_table p;
select x.p.empno from person_table p
       *
ERROR at line 1:
ORA-00904: "X"."P"."EMPNO": invalid identifier
 
SQL> select treat(x.p as employee).empno empno,
  2               x.p.last_name last_name
  3   from person_table x;
 
     EMPNO LAST_NAME
---------- --------------------
           Seoul
      1234 Inchon
      5678 Arirang
 
SQL>

【예제】
SQL> select name, TREAT(VALUE(p) AS employee_t).salary salary
  2   FROM person p;

NAME                        SALARY
----------------------   ---------
Bob   
Joe                         100000
Tim                           1000

SQL>


1-18) TRIM 함수
--------------------------------------------------------------------------------

 이 함수는 LTRIM과 RTRIM 함수를 결합한 형태로
  문자값의 왼쪽 또는 오른쪽 부분에 정의한 문자를 절삭하여 출력한다.
LEADING은 LTRIM처럼 문자열 왼쪽의 문자를 지정하여 절삭하고,
 TRAILING은 RTRIM처럼 문자열 오른쪽 문자를 지정하여 절삭한다.
 BOTH는 왼쪽과 오른쪽 문자를 지정하여 절삭한다.

【형식】
TRIM ([{{{LEADING|TRAILING|BOTH} [trim_char] } | trim_char} FROM]
      trim_source )

【예제】
SQL> select trim (0 from 000123400) from dual;

TRIM
----
1234

SQL> select trim(trailing 'a' from 'abca') from dual;

TRI
---
abc

SQL> select trim(leading 'a' from 'abca') from dual;

TRI
---
bca

SQL> select trim(both 'a' from 'abca') from dual;

TR
--
bc

SQL>


1-19) UPPER 함수
--------------------------------------------------------------------------------

upper(string) 함수는 입력된 문자열을 대문자로 반환한다.

【예제】
SQL> select upper('Beautiful COREA') from dual;

UPPER('BEAUTIFU
---------------
BEAUTIFUL COREA

SQL>


1-20) ASCII 함수
--------------------------------------------------------------------------------

ASCII
ascii(‘char’) 함수는 주어진 char의 첫 글자의 아스키 값을 반환한다.
 char의 타입은 char, varchar2, nchar, nvarchar2중의 하나이어야 한다.

【예제】
SQL> select ascii('Korea') from dual;

ASCII('KOREA')
--------------
            75

SQL> select ascii('K') from dual;

ASCII('K')
----------
        75

SQL>


1-21) INSTR 함수
--------------------------------------------------------------------------------

이 함수는 문자 스트링 중에서
지정한 문자가 가장 처음 나타나는 위치를 숫자로 출력한다.

【형식】
{INSTR|INSTRB|INSTRC|INSTR2|INSTR4}
  ( string, substring [, position [,occurrence] ] )

【예제】
SQL> select instr('Corea','e') from dual;

INSTR('COREA','E')
------------------
                 4

SQL> select instr('corporate floor','or',3,2) from dual;

INSTR('CORPORATEFLOOR','OR',3,2)
--------------------------------
                              14

SQL> select instrb('corporate floor','or',5,2) from dual;

INSTRB('CORPORATEFLOOR','OR',5,2)
---------------------------------
                               14

SQL>


1-22) LENGTH 함수
--------------------------------------------------------------------------------

 LENGTH(char) 함수는 char의 길이를 반환한다.
LENGTHB는 character 대신 byte를 사용하고,
LENGTHC는 unicode를 사용하며,
LENGTH2는 UCS2 codepoint를 사용하고,
LENGTH4는 UCS4 codepoint를 사용한다.

【형식】
{LENGTH| LENGTHB| LENGTHC| LENGTH2| LENGTH4} (char)

【예제】
SQL> select length('Corea') from dual;

LENGTH('COREA')
---------------
              5

SQL> select lengthb('Corea') from dual;

LENGTHB('COREA')
----------------
               5

SQL>



2-1) ADD_MONTHS 함수
--------------------------------------------------------------------------------

ADD_MONTHS
 ADD_MONTHS(d, n)는 날짜 d에 n 개월을 더한 일자를 반환한다.

【예제】
SQL> select current_date today, add_months(current_date,1) "next month"
  2  from dual;

TODAY     next mont
--------- ---------
29-JUL-04 29-AUG-04

SQL>


2-2) CURRENT_DATE 함수
--------------------------------------------------------------------------------


 이 함수는 현재 session의 날짜 정보를 반환한다.
【예제】
SQL> select current_date from dual;

CURRENT_D
---------
31-JUL-04

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
--------------------------------------------------------------------------
+09:00

SQL> alter session set NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';

Session altered.

SQL> select current_date from dual;

CURRENT_DATE
--------------------
31-JUL-2004 09:31:57

SQL> alter session set time_zone='-5:0';

Session altered.

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
--------------------------------------------------------------------------
-05:00

SQL>


2-3) URRENT_TIMESTAMP 함수
--------------------------------------------------------------------------------

 이 함수는 현재 session의 날짜와 시간 정보를 반환한다.
 current_timestamp는 time zone까지 출력되지만,
 localtimestamp는 time zone은 출력되지 않는다.
【예제】
SQL> select current_timestamp, localtimestamp,
  2  current_date from dual;

CURRENT_TIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
CURRENT_D
---------
04-AUG-04 11.17.40.768776 AM +09:00
04-AUG-04 11.17.40.768776 AM
04-AUG-04

SQL>


2-4) DBTIMEZONE 함수
--------------------------------------------------------------------------------


데이터베이스 timezone을 반환한다.
【예제】
SQL> select dbtimezone from dual;

DBTIME
------
-07:00

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
--------------------------------------------------------------------------
+09:00

SQL>


2-5) EXTRACT(datetime) 함수
--------------------------------------------------------------------------------

특정 날짜/시간 값이나 날짜 값을 가진 표현식으로부터
  원하는 날짜 영역을 추출하여 출력한다.

【형식】
EXTRACT ({year|month|day|hour|minute|second|
         timezone_hour|timezone_minute|
         timezone_region|timezone_abbr}
 FROM {datetime_value_expr|interval_value_rxpr})

【예제】
SQL> select extract(year from date '2004-8-2') from dual;

EXTRACT(YEARFROMDATE'2004-8-2')
-------------------------------
                           2004

SQL>


2-6) FROM_TZ 함수
--------------------------------------------------------------------------------

이 함수는 timestamp 값을 timestamp with time zone 값으로 변환한다.

【형식】
FROM_TZ ( timestamp_value, time_zone_value)

【예제】
SQL> select from_tz(timestamp '2004-8-11 08:00:00','3:00') from dual;

FROM_TZ(TIMESTAMP'2004-8-1108:00:00','3:00')
--------------------------------------------------------------------------
11-AUG-04 08.00.00.000000000 AM +03:00

SQL>


2-7) LAST_DAY 함수
--------------------------------------------------------------------------------

 이 함수는 지정한 달의 마지막 날을 출력한다.

【형식】
LAST_DAY ( date )

【예제】
SQL> select sysdate, last_day(sysdate) "last day",
  2  last_day(sysdate)- sysdate "Days Left"
  3  from dual;

SYSDATE   last day   Days Left
--------- --------- ----------
04-AUG-04 31-AUG-04         27

SQL>


2-8) LOCALTIMESTAMP 함수
--------------------------------------------------------------------------------

이 함수는 timestamp의 현재 날짜와 시각을 출력한다.
 current_timestamp는 time zone까지 출력되지만,
 localtimestamp는 time zone은 출력되지 않는다.

【형식】
localtimestamp [(timestamp_precision)]

【예제】
SQL> select current_timestamp, localtimestamp,
  2  current_date from dual;

CURRENT_TIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
CURRENT_D
---------
04-AUG-04 11.17.40.768776 AM +09:00
04-AUG-04 11.17.40.768776 AM
04-AUG-04

SQL>
 
【예제】오류가 발생하는 이유를 잘 이해하자.
SQL> CREATE TABLE local_test(col1 TIMESTAMP WITH LOCAL TIME ZONE);

Table created.

SQL> INSERT INTO local_test VALUES
  2  (TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF'));
(TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF'))
              *
ERROR at line 2:
ORA-01830: date format picture ends before converting entire input string

SQL> INSERT INTO local_test VALUES
  2  (TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF PM'));

1 row created.

SQL> select * from local_test;

COL1
--------------------------------------------------------------------------
04-AUG-04 11.33.58.183398 AM

SQL>



2-9) MONTHS_BETWEEN 함수
--------------------------------------------------------------------------------

 MONTHS_BETWEEN(date1,date2) 함수는 date1과 date로 나타내는
 날짜와 날짜 사이의 개월 수를 출력한다.

【예제】
SQL> select months_between
  2  (to_date('02-02-2004','MM-DD-YYYY'),
  3   to_date('01-01-2003','MM-DD-YYYY') ) "Months"
  4  FROM dual;

    Months
----------
13.0322581

SQL>


2-10) NEW_TIME 함수
--------------------------------------------------------------------------------

NEW_TIME(date,zone1,zone2) 함수는 date, zone1 시간대를 zone2 시간대로 출력한다.
여기서 사용되는 zone은 다음 중의 하나이다.

 AST,ADT : Atlantic Standard or Daylight Time
 BST,BDT : Bering Standard or Daylight Time
 CST,CDT : Central Standard or Daylight Time
 EST,EDT : Eastern Standard or Daylight Time
 GMT : Greenwich Mean Time
 HST,HDT : Alaska-Hawaii Standard or Daylight Time
 MST,MDT : Mountain Standard or Daylight Time
 NST : Newfoundland Standard Time
 PST,PDT : Pacific Standard or Daylight Time
 YST,YDT : Yukon Standard or Daylight Time

【예제】
SQL> alter session set nls_date_format =
  2  'DD-MON-YYYY HH24:MI:SS';

Session altered.

SQL> select NEW_TIME(TO_DATE(
  2  '11-10-04 01:23:33', 'MM-DD-YY HH24:MI:SS'),
  3  'AST', 'PST') FROM DUAL;

NEW_TIME(TO_DATE('11
--------------------
09-NOV-2004 21:23:33

SQL>



2-11) NEXT_DAY 함수
--------------------------------------------------------------------------------

NEXT_DAY(date,char) 함수는 date로부터 char로 명시한 가장 최근의 날짜를 출력한다.

【예제】
SQL> select next_day('02-AUG-2004','MONDAY') from dual;

NEXT_DAY('02-AUG-200
--------------------
09-AUG-2004 00:00:00

SQL>



2-12) NUMTODSINTERVAL 함수
--------------------------------------------------------------------------------

 NUMTODSINTERVAL(n,'char_expr') 함수는 n을 interval day to second로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘DAY’
  ‘HOUR’
  ‘MINUTE’
  ‘SECOND’

【예제】
SQL> select numtodsinterval(100,'MINUTE') from dual;

NUMTODSINTERVAL(100,'MINUTE')
--------------------------------------------------------------------------
+000000000 01:40:00.000000000

SQL>

【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename, hiredate,
  2  numtodsinterval(100,'day')+hiredate from emp;

ENAME      HIREDATE  NUMTODSIN
---------- --------- ---------
SMITH      17-DEC-80 27-MAR-81
ALLEN      20-FEB-81 31-MAY-81
WARD       22-FEB-81 02-JUN-81
JONES      02-APR-81 11-JUL-81
MARTIN     28-SEP-81 06-JAN-82
BLAKE      01-MAY-81 09-AUG-81
CLARK      09-JUN-81 17-SEP-81
SCOTT      19-APR-87 28-JUL-87
KING       17-NOV-81 25-FEB-82
TURNER     08-SEP-81 17-DEC-81
ADAMS      23-MAY-87 31-AUG-87
JAMES      03-DEC-81 13-MAR-82
FORD       03-DEC-81 13-MAR-82
MILLER     23-JAN-82 03-MAY-82

14 rows selected.

SQL>


2-13) NUMTOYMINTERVAL 함수
--------------------------------------------------------------------------------

NUMTOYMINTERVAL(n,'char_expr') 함수는 n을 interval year to month로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘YEAR’
  ‘MONTH’

【예제】
SQL> select numtoyminterval(30,'month') from dual;

NUMTOYMINTERVAL(30,'MONTH')
---------------------------------------------------------------------------
+000000002-06

SQL>

【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename,hiredate,
  2  numtoyminterval(30,'month')+hiredate from emp;

ENAME      HIREDATE  NUMTOYMIN
---------- --------- ---------
SMITH      17-DEC-80 17-JUN-83
ALLEN      20-FEB-81 20-AUG-83
WARD       22-FEB-81 22-AUG-83
JONES      02-APR-81 02-OCT-83
MARTIN     28-SEP-81 28-MAR-84
BLAKE      01-MAY-81 01-NOV-83
CLARK      09-JUN-81 09-DEC-83
SCOTT      19-APR-87 19-OCT-89
KING       17-NOV-81 17-MAY-84
TURNER     08-SEP-81 08-MAR-84
ADAMS      23-MAY-87 23-NOV-89
JAMES      03-DEC-81 03-JUN-84
FORD       03-DEC-81 03-JUN-84
MILLER     23-JAN-82 23-JUL-84

14 rows selected.

SQL>



2-14) ROUND(date) 함수
--------------------------------------------------------------------------------

이 함수는 날짜를 주어진 형식으로 반올림하는 함수이다.
 날짜 형식이 없으면 가장 가까운 날을 출력한다.

【형식】
ROUND( date [,fmt] )

【예제】
SQL> select localtimestamp, round(sysdate,'year') from dual;

LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.26.24.197977 PM
01-JAN-05

SQL> select localtimestamp,round(sysdate,'day') from dual;

LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.29.57.839269 PM
08-AUG-04

SQL> select localtimestamp,round(sysdate) from dual;

LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.30.11.552050 PM
05-AUG-04

SQL>


2-15) SESSIONTIMEZONE 함수
--------------------------------------------------------------------------------

이 함수는 현재 세션의 시간대역을 출력한다.

【예제】
SQL> select sessiontimezone, current_timestamp from dual;

SESSIONTIMEZONE
--------------------------------------------------------------------------
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
+09:00
04-AUG-04 01.37.13.355873 PM +09:00

SQL> select sessiontimezone, tz_offset(sessiontimezone) from dual;

SESSIONTIMEZONE
--------------------------------------------------------------------------
TZ_OFFS
-------
+09:00
+09:00

SQL>


2-16) SYS_EXTRACT_UTC 함수
--------------------------------------------------------------------------------

sys_extract_utc(datetime_with_timezone) 함수는
UTC(coordinated universal time: Greenwich mean time) 시각을 반환한다.

【예제】
SQL> select systimestamp, sys_extract_utc(systimestamp) from dual;

SYSTIMESTAMP
--------------------------------------------------------------------------
SYS_EXTRACT_UTC(SYSTIMESTAMP)
--------------------------------------------------------------------------
06-AUG-04 02.41.39.258976 PM +09:00
06-AUG-04 05.41.39.258976 AM


SQL>


2-17) SYSDATE 함수
--------------------------------------------------------------------------------

이 함수는 오늘 현재 날짜와 시각을 출력한다.

【예제】
SQL> select sysdate, current_timestamp from dual;

SYSDATE
---------
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
04-AUG-04
04-AUG-04 01.51.39.767156 PM +09:00

SQL> select to_char
  2  (sysdate, 'MM-DD-YYYY HH24:MI:SS') from dual;

TO_CHAR(SYSDATE,'MM
-------------------
08-04-2004 13:53:18

SQL>


2-18) SYSTIMESTAMP 함수
--------------------------------------------------------------------------------

이 함수는 시스템의 날짜를 출력한다.

【예제】
SQL> select sysdate,systimestamp,localtimestamp from dual;

SYSDATE
---------
SYSTIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
04-AUG-04
04-AUG-04 01.58.06.346528 PM +09:00
04-AUG-04 01.58.06.346552 PM

SQL>


2-19) TO_DSINTERVAL 함수
--------------------------------------------------------------------------------

이 함수는 문자열을 interval day to second 형식으로 변환하는 함수이다.

【형식】
to_dsinterval ( char [ ‘nlsparam’] )

【예제】
SQL> select sysdate,
  2  sysdate+to_dsinterval('003 17:00:00') as "3days 17hours later"
  3  from dual;

SYSDATE   3days 17h
--------- ---------
04-AUG-04 08-AUG-04

SQL>


2-20) TO_TIMESTAMP 함수
--------------------------------------------------------------------------------

이 함수는 문자열을 timestamp 형식으로 변환하여 출력한다

【형식】
to_timestamp ( char [,fmt ['nlsparam'] ] )

【예제】
SQL> select to_timestamp('2004-8-20 1:30:00', 'YYYY-MM-DD HH:MI:SS')
  2  from dual;

TO_TIMESTAMP('2004-8-201:30:00','YYYY-MM-DDHH:MI:SS')
--------------------------------------------------------------------------
20-AUG-04 01.30.00.000000000 AM

SQL>



2-21) TO_TIMESTAMP_TZ 함수
--------------------------------------------------------------------------------

이 함수는 문자열을 timestamp with time zone 형식으로 변환하여 출력한다.

【형식】
to_timestamp_tz ( char [,fmt ['nlsparam'] ] )

【예제】
SQL> select to_timestamp_tz('2004-8-20 1:30:00 -3:00',
  2  'YYYY-MM-DD HH:MI:SS TZH:TZM') from dual;

TO_TIMESTAMP_TZ('2004-8-201:30:00-3:00','YYYY-MM-DDHH:MI:SSTZH:TZM')
--------------------------------------------------------------------------
20-AUG-04 01.30.00.000000000 AM -03:00

SQL>


2-22) TO_YMINTERVAL 함수
--------------------------------------------------------------------------------

TO_YMINTERVAL ( char ) 함수는 문자열을 interval year to month 형식으로 변환하는 함수이다.

【예제】
SQL> select sysdate,
  2  sysdate+to_yminterval('01-03') "15Months later"
  3  from dual;

SYSDATE   15Months
--------- ---------
04-AUG-04 04-NOV-05

SQL>


2-23) TRUNC(date) 함수
--------------------------------------------------------------------------------

이 함수는 날짜를 절삭하여 출력한다.

【형식】
TRUNC ( date [.fmt] )

【예제】
SQL> select trunc(to_date('27-AUG-04','DD-MON-YY'), 'YEAR')
  2  from dual;

TRUNC(TO_
---------
01-JAN-04

SQL>


2-24) TZ_OFFSET 함수
--------------------------------------------------------------------------------

이 함수는 time zone의 offset 값을 출력한다.

【형식】
TZ_OFFSET ( {‘time_zone_name’ | SESSIONTIMEZONE | DBTIMEZONE |
             ‘{+|-} hh:mi’ } )

【예제】
SQL> select sessiontimezone, tz_offset('ROK') from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
TZ_OFFS
-------
+09:00
+09:00

SQL>



3-1) ASCIISTR 함수
--------------------------------------------------------------------------------

 asciistr('string')의 string의 아스키 문자로 반환한다.
Ä
【예제】
SQL> select ascii('ABÄCDE') from dual;
☜ ABÄCDE의 두번째 Ä는 A에 움라우트(Umlaut)가 붙은 글씨이다.

ASCIIS
------
ABDCDE
           
SQL>



3-2) BIN_TO_NUM 함수
--------------------------------------------------------------------------------

 이 함수는 2진수 벡터를 10진수로 변환한다.

SQL> select bin_to_num(1,0,1,0) from dual;

BIN_TO_NUM(1,0,1,0)
-------------------
                 10

SQL>


3-3) CAST 함수
--------------------------------------------------------------------------------

 데이터형식이나 collection 형식을 다른 데이터형식이나 다른 collection 형식으로 변환한다.

【예제】데이터형식인 경우
SQL> select current_date from dual;

CURRENT_D
---------
30-JUL-04

SQL> select cast(current_date as timestamp) from dual;

CAST(CURRENT_DATEASTIMESTAMP)
---------------------------------------------------------------------------
30-JUL-04 12.29.15.000000 PM

SQL>


3-4) CHARTOROWID 함수
--------------------------------------------------------------------------------

 이 함수는 char, varchar2, nchar, ncharvar2형 데이터 타입을 rowid 형 데이터 타입으로 변경한다.
【예제】
SQL> select name from emp
  2  where rowid = chartorowid('AAAHZ+AABAAAMWiAAF');

NAME
----------
jijoe

SQL> select rowid,name from emp;

ROWID              NAME
------------------ ----------
AAAHZ+AABAAAMWiAAA Cho
AAAHZ+AABAAAMWiAAB Joe
AAAHZ+AABAAAMWiAAC kim
AAAHZ+AABAAAMWiAAF jijoe

SQL>


여기서 rowid의 의미는 다음과 같다.
AAAHZ+  AAB  AAAMWi  AAA 객체번호  테이블스페이스번호  블록번호  행번호



3-5) COMPOSE 함수
--------------------------------------------------------------------------------

 입력된 스트링을 unicode로 나타낸다.

【예제】
SQL> select compose('aa' || unistr('\0308') ) from dual;

CO
--
aa

SQL>


3-6) CONVERT 함수
--------------------------------------------------------------------------------

입력된 문자열을 지정한 코드로 변환한다.
공용 문자셋은 살펴보자.
US7ASCII  US 7-bit ASCII 문자 WE8DEC  서유럽 8비트 문자 WE8HP  HP 서유럽 레이져젯 8비트 문자 F7DEC  DEC 프랑스 7비트 문자 WE8EBCDIC500  IBM 서유럽 EBCDIC 코드 페이지 500 WE8PC850  IBM PC 코드 페이지 850 WE8ISO8859P1  ISO 8859 서유럽 8비트 문자

【예제】
SQL> select convert('arirang','we8pc850') from dual;

CONVERT
-------
arirang

SQL>


3-7) HEXTORAW 함수
--------------------------------------------------------------------------------

HEXTORAW(char) 함수는 char, varchar2, nchar, nvarchar2 따위의 문자로 주어지는
 hexadecimal digit을 raw 값으로 변환한다.

【예제】
SQL> create table test(raw_col RAW(10));

Table created.

SQL> insert into test VALUES (HEXTORAW('7D'));

1 row created.

SQL> select * from test;

RAW_COL
--------------------
7D

SQL>



3-8) NUMTODSINTERVAL 함수
--------------------------------------------------------------------------------

 NUMTODSINTERVAL(n,'char_expr') 함수는 n을 interval day to second로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘DAY’
  ‘HOUR’
  ‘MINUTE’
  ‘SECOND’

【예제】
SQL> select numtodsinterval(100,'MINUTE') from dual;

NUMTODSINTERVAL(100,'MINUTE')
--------------------------------------------------------------------------
+000000000 01:40:00.000000000

SQL>

【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename, hiredate,
  2  numtodsinterval(100,'day')+hiredate from emp;

ENAME      HIREDATE  NUMTODSIN
---------- --------- ---------
SMITH      17-DEC-80 27-MAR-81
ALLEN      20-FEB-81 31-MAY-81
WARD       22-FEB-81 02-JUN-81
JONES      02-APR-81 11-JUL-81
MARTIN     28-SEP-81 06-JAN-82
BLAKE      01-MAY-81 09-AUG-81
CLARK      09-JUN-81 17-SEP-81
SCOTT      19-APR-87 28-JUL-87
KING       17-NOV-81 25-FEB-82
TURNER     08-SEP-81 17-DEC-81
ADAMS      23-MAY-87 31-AUG-87
JAMES      03-DEC-81 13-MAR-82
FORD       03-DEC-81 13-MAR-82
MILLER     23-JAN-82 03-MAY-82

14 rows selected.

SQL>



3-9) NUMTOYMINTERVAL 함수
--------------------------------------------------------------------------------

NUMTOYMINTERVAL(n,'char_expr') 함수는 n을 interval year to month로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘YEAR’
  ‘MONTH’

【예제】
SQL> select numtoyminterval(30,'month') from dual;

NUMTOYMINTERVAL(30,'MONTH')
---------------------------------------------------------------------------
+000000002-06

SQL>

【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename,hiredate,
  2  numtoyminterval(30,'month')+hiredate from emp;

ENAME      HIREDATE  NUMTOYMIN
---------- --------- ---------
SMITH      17-DEC-80 17-JUN-83
ALLEN      20-FEB-81 20-AUG-83
WARD       22-FEB-81 22-AUG-83
JONES      02-APR-81 02-OCT-83
MARTIN     28-SEP-81 28-MAR-84
BLAKE      01-MAY-81 01-NOV-83
CLARK      09-JUN-81 09-DEC-83
SCOTT      19-APR-87 19-OCT-89
KING       17-NOV-81 17-MAY-84
TURNER     08-SEP-81 08-MAR-84
ADAMS      23-MAY-87 23-NOV-89
JAMES      03-DEC-81 03-JUN-84
FORD       03-DEC-81 03-JUN-84
MILLER     23-JAN-82 23-JUL-84

14 rows selected.

SQL>




3-10) RAWTOHEX 함수
--------------------------------------------------------------------------------

RAWTOHEX(raw) 함수는 raw 값을 hexadecimal 값으로 변환한다.

【예제】
SQL> create table test(raw_col RAW(10));

Table created.

SQL> insert into test VALUES (HEXTORAW('7D'));

1 row created.

SQL> select * from test;

RAW_COL
--------------------
7D

SQL> select rawtohex(raw_col) from test;

RAWTOHEX(RAW_COL)
--------------------
7D

SQL>


3-11) RAWTONHEX 함수
--------------------------------------------------------------------------------

RAWTONHEX(raw) 함수는 raw 값을 nvarchar2형 hexadecimal 값으로 변환한다.

【예제】
SQL> create table test(raw_col RAW(10));

Table created.

SQL> insert into test VALUES (HEXTORAW('7D'));

1 row created.

SQL> select * from test;

RAW_COL
--------------------
7D

SQL> select rawtonhex(raw_col) from test;

RAWTONHEX(RAW_COL)
--------------------
7D

SQL>


3-12) ROWIDTOCHAR 함수
--------------------------------------------------------------------------------

RAWIDTOCHAR(rowid) 함수는 rowid 값을 varchar2 형식의 데이터로 변환한다.

【예제】
SQL> select rowid from test;

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL>

여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호



3-13) ROWIDTONCHAR 함수
--------------------------------------------------------------------------------

RAWIDTONCHAR(rowid) 함수는 rowid 값을 nvarchar2 형식의 데이터로 변환한다.

【예제】
SQL> select rowid from test;

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL> select lengthb(rowidtonchar(rowid)), rowidtonchar(rowid)
  2  from test;

LENGTHB(ROWIDTONCHAR(ROWID)) ROWIDTONCHAR(ROWID
---------------------------- ------------------
                          36 AAAHbHAABAAAMXCAAA

SQL>


여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호



3-14) TO_CHAR(character) 함수
--------------------------------------------------------------------------------

 이 함수는 nchar, nvarchar2, clob, nclob 형식의 데이터를
데이터베이스 character set으로 변환한다. 즉, 문자로 변환한다.

【형식】
 TO_CHAR( nchar| clob | nclob)

【예제】
SQL> select to_char('01110') from dual;

TO_CH
-----
01110

SQL>



3-15) TO_CLOB 함수
--------------------------------------------------------------------------------

이 함수는 LOB 컬럼에 있는 NCLOB나 또는 다른 문자 스트링을 CLOB로 변환한다.

【형식】
 TO_CLOBR({ lob_column | char})

【예제】
SQL> select to_clob('corea') from dual;

TO_CLOB('COREA')
--------------------------------------------------------------------------
corea

SQL>



3-16) TO_DSINTERVAL 함수
--------------------------------------------------------------------------------

이 함수는 문자열을 interval day to second 형식으로 변환하는 함수이다.

【형식】
to_dsinterval ( char [ ‘nlsparam’] )

【예제】
SQL> select sysdate,
  2  sysdate+to_dsinterval('003 17:00:00') as "3days 17hours later"
  3  from dual;

SYSDATE   3days 17h
--------- ---------
04-AUG-04 08-AUG-04

SQL>


3-17) TO_LOB 함수
--------------------------------------------------------------------------------

 TO_LOB(long_column) 함수는 LONG, LONG RAW 컬럼의 데이터를 LOB 값으로 변환한다.

【예제】
SQL> create table test2(zz clob);

Table created.

SQL> insert into test2
  2  (select to_lob(p.raw_col) from test p);

SQL>


3-18) TO_MULTI_BYTE 함수
--------------------------------------------------------------------------------

TO_MULTI_BYTE(char) 함수는 싱글 바이트 문자를 포함한 모든 문자열을 다중바이트 문자열로 변환한다.

【예제】
SQL> select dump(to_multi_byte('Corea')) from dual;

DUMP(TO_MULTI_BYTE('COREA'))
-----------------------------------------------------
Typ=1 Len=10: 163,195,163,239,163,242,163,229,163,225

SQL>



3-19) TO_NCHAR(character) 함수
--------------------------------------------------------------------------------

 이 함수는 문자스트링, clob, nclob 형식의 데이터를 national character set,
 즉 nchar으로 변환한다. 이는 translate ... using 문의 경우와 같다.

【형식】
TO_NCHAR({char|clob|nclob} [,fmt [,'nlsparam']])

【예제】
SQL> select to_nchar('Corea') from dual;

TO_NC
-----
Corea

SQL>


3-20) TO_NCHAR(datetime) 함수
--------------------------------------------------------------------------------

 이 함수는 date, timestamp, timestamp with time zone, timestamp with local time zone,
 interval month to year, interval day to second 형식의 데이터를
 nchar 형식의 데이터로 변환한다.

【형식】
TO_NCHAR({datetime|interval} [,fmt [,'nlsparam']])

【예제】
SQL> select to_nchar(sysdate) from dual;

TO_NCHAR(SYSDATE)
------------------------------
05-AUG-04

SQL>



3-21) TO_NCHAR(number) 함수
--------------------------------------------------------------------------------

 이 함수는 숫자를 nvarchar2 형식의 데이터로 변환한다.

【형식】
TO_NCHAR(n [,fmt [,'nlsparam']])

【예제】
SQL> select to_nchar(1234) from dual;

TO_N
----
1234

SQL> select to_nchar(rownum) from test;

TO_NCHAR(ROWNUM)
----------------------------------------
1

SQL>



3-22) TO_NCLOB 함수
--------------------------------------------------------------------------------

이 함수는 clob, 문자열 형식의 데이터를 nclob 형식의 데이터로 변환한다.

【형식】
TO_NCLOB({char|lob_column})

【예제】
SQL> select to_nclob('Corea') from dual;

TO_NCLOB('COREA')
--------------------------------------------------------------------------
Corea

SQL>



3-23) TO_NUMBER 함수
--------------------------------------------------------------------------------

이 함수는 숫자를 포함하는 char, varchar2, nchar, nvarchar2 형식의
 문자 데이터를 number 형식의 숫자 데이터로 변환한다.

【형식】
TO_NUMBER(char [,fmt [,'nlsparam']])

【예제】
SQL> select to_number('1234') from dual;

TO_NUMBER('1234')
-----------------
             1234

SQL>


3-24) TO_SINGLE_BYTE 함수
--------------------------------------------------------------------------------

TO_SINGLE_BYTE(char) 함수는 다중 바이트 문자열을 single byte 문자로 변환한다.

【예제】
SQL> select dump(to_multi_byte('Corea')) from dual;

DUMP(TO_MULTI_BYTE('COREA'))
-----------------------------------------------------
Typ=1 Len=10: 163,195,163,239,163,242,163,229,163,225

SQL> select dump(to_single_byte('Corea')) from dual;

DUMP(TO_SINGLE_BYTE('COREA'))
------------------------------
Typ=1 Len=5: 67,111,114,101,97

SQL> select to_single_byte(chr(65)) from dual;

T
-
A

SQL>



3-25) TO_YMINTERVAL 함수
--------------------------------------------------------------------------------

TO_YMINTERVAL ( char ) 함수는 문자열을 interval year to month 형식으로 변환하는 함수이다.

【예제】
SQL> select sysdate,
  2  sysdate+to_yminterval('01-03') "15Months later"
  3  from dual;

SYSDATE   15Months
--------- ---------
04-AUG-04 04-NOV-05

SQL>


3-26) TRANSLATE ... USING 함수
--------------------------------------------------------------------------------

이 함수는 텍스트 형식의 데이터를 지정한 문자 형식의 데이터로 변환한다.

【형식】
TRANSLATE ( text USING {CHAR_CS|NCHAR_CS} )

【예제】
SQL> select translate('Corea' USING char_cs) from dual;

TRANS
-----
Corea

SQL> select to_nchar('Corea') from dual;

TO_NC
-----
Corea

SQL>


3-27) UNISTR 함수
--------------------------------------------------------------------------------

UNISTR('string') 함수는 스트링 형식의 데이터를 nchar 형식의 데이터로 변환한다.

【예제】
SQL> select unistr('abc\00e5\00f1\00f6') from dual;

UNISTR
------
abc??o

SQL> select unistr('Corea') from dual;

UNIST
-----
Corea

SQL>



4-1) BFILENAME 함수
--------------------------------------------------------------------------------

 서버 파일 시스템 상에 실제로 위치한 LOB 바이너리 파일의 위치한 BFILE locator를 반환한다.
【형식】
bfilename ('디렉토리‘,’파일이름‘)

【예제】BFILE을 insert하는 예
SQL> connect system/manager

SQL> host mkdir /export/home/oracle/bfile

SQL> create directory bfile_dir as '/export/home/oracle/bfile';

Directory created.

SQL> grant read on directory bfile_dir to jijoe;

Grant succeeded.

SQL> connect jijoe/joe_password

SQL> create table bfile_doc (id number, doc bfile);

SQL> insert into bfile_doc

   1    values(1111,bfilename('bfile_dir','unix.hwp'));

1 row created.

SQL>


4-2) COALESCE 함수
--------------------------------------------------------------------------------

이 함수는 나열된 값 중에서 NULL이 아닌 첫 번째 값을 반환한다.  

【예제】
SQL> select coalesce('','','arirang','kunsan') from dual;

COALESC
-------
arirang

SQL>



4-3) DECODE 함수
--------------------------------------------------------------------------------

DECODE는 일반적인 프로그래밍 언어의 IF문을 SQL 문자 또는 PL/SQL 안으로 끌어들여 사용하기 위하여 만들어진 오라클 함수이다.
따라서 일반 프로그래밍 언어의 IF문이 수행 할 수 있는 기능을 포함하고 있다.
  select시의 decode 사용은 from 절만 빼고 어디에서나 사용할 수 있다.
  일반 프로그래밍과 decode 함수를 서로 비교하여 보자.
IF문 Decode 함수 IF A=B THEN RETURN 'T';END IF; DECODE(A,B,'T') IF A=B THENRETURN 'T';ELSIF A=C THENRETURN 'F';ELSERETURN 'X';END IF; DECODE(A,B,'T',C,'F','X')
【형식】
DECODE(검색컬럼,조건1,결과값1,
                  조건2,결과값2,...,기본값);

【예제】
SQL> connect jijoe/jijoe_password
SQL> create table aa(
  2  pid        number(12) primary key,
  3  addr varchar2(20),
  4  name varchar2(10));

SQL> insert into aa values(1234,'kunsan','jijoe')
SQL> insert into aa values(3456,'seoul','sunny')

SQL> select * from aa;

       PID ADDR                 NAME
---------- -------------------- ----------
      1234 kunsan               jijoe
      3456 seoul                sunny

SQL> select decode(pid,1234,name) name from aa;

NAME
----------
jijoe


SQL>
【예제】
SQL> desc ddd
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NO                                                 NUMBER(4)
 NAME                                               VARCHAR2(10)
 HIRDATE                                            DATE
 DEPTNO                                             NUMBER(5)

SQL> select * from ddd;

        NO NAME       HIRDATE       DEPTNO
---------- ---------- --------- ----------
         1 student1   01-JAN-04         10
         2 student2   01-FEB-04         10
         3 student3   01-MAR-04         20
         4 student4   01-MAY-04         30

SQL> select count(decode(to_char(hirdate,'MM'),'01',1)) "JAN",
  2         count(decode(to_char(hirdate,'MM'),'02',1)) "FEB",
  3         count(decode(to_char(hirdate,'MM'),'03',1)) "MAR",
  4         count(*) "Total"
  5  from ddd
  6  where to_char(hirdate,'MM') >= '01' AND
  7        to_char(hirdate,'MM') <= '06';

       JAN        FEB        MAR      Total
---------- ---------- ---------- ----------
         1          1          1          4

SQL>



4-4) DEPTH 함수
--------------------------------------------------------------------------------

DEPTH( correlation_integer) 함수는 UNDER_PATH나 EQUALS_PATH 조건과 함께 사용되는 보조함수이다.
 이 함수는 UNDER_PATH 조건에 상관관계의 수치를 반환한다.

【예제】
SQL> select * from resource_view;
SQL> select path(1), depth(2)
  2  from resource_view
  3  where under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 1)=1
  4    and under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 2)=1;

PATH(1)                                      DEPTH(2)
------------------------------------------ ----------
/xml.xsd                                            1
        

SQL>


4-5) DUMP 함수
--------------------------------------------------------------------------------

지정한 데이터의 위치와 길이 따위를 지정한 형식으로 반환한다.
【형식】
DUMP(expr [,반환형식[,시작위치[,길이]]] )

【예제】
SQL> select dump('Corea', 1016) from dual;

DUMP('COREA',1016)
-----------------------------------------------------
Typ=96 Len=5 CharacterSet=KO16KSC5601: 43,6f,72,65,61

SQL> select dump('Corea', 8,3,2) "Octal" from dual;

Octal
---------------------
Typ=96 Len=5: 162,145

SQL> select dump('Corea',16,3,2) "ASCII" from dual;

ASCII
-------------------
Typ=96 Len=5: 72,65

SQL>


4-6) EMPTY_BLOB 함수
--------------------------------------------------------------------------------

EMPTY_BLOB () 함수는 LOB 변수를 초기화하기 위하여 쓰이거나,
 또는 INSERT 문이나 UPDATE 문에서 empty LOB 위치를 반환한다.

【예시】
UPDATE print_media SET ad_photo = EMPTY_BLOB();


4-7) EMPTY_CLOB 함수
--------------------------------------------------------------------------------

EMPTY_CLOB () 함수는 LOB 변수를 초기화하기 위하여 쓰이거나,
 또는 INSERT 문이나 UPDATE 문에서 empty LOB 위치를 반환한다.

【예시】
UPDATE print_media SET ad_photo = EMPTY_CLOB();


4-8) EXISTSNODE 함수
--------------------------------------------------------------------------------

이 함수는 node의 존재여부를 확인하여 그 결과를 반환한다.
 0은 노드가 남아 있지 않은 경우이고,
 1은 아직 노드가 존재하는 경우이다.

【형식】
EXISTSNODE(XMLType_instance, XPath_string [,namespace_string] )

【예제】
SQL> select * from resource_view;
SQL> select res,any_path
  2  from resource_view
  3  where existsnode(res, 'xdbconfig.xml') =0;

26 rows selected.
SQL>



4-9) EXTRACT(XML) 함수
--------------------------------------------------------------------------------

이 함수는 existsnode와 유사한 함수이다.

【형식】
EXTRACT(XMLType_instance, XPath_string [,namespace_string] )

【예제】
SQL> select * from resource_view;
SQL> select extract(res,'xdbconfig.xml')
  2  from resource_view;
 
26 rows selected.
SQL>



4-10) EXTRACTVALUE 함수
--------------------------------------------------------------------------------

이 함수는 existsnode와 유사한 함수로써 node의 스칼라 값을 반환한다.

【형식】
EXTRACTVALUE(XMLType_instance, XPath_string [,namespace_string] )

【예제】
SQL> select * from resource_view;
SQL> select extractvalue(res,'xdbconfig.xml')
  2  from resource_view;
 
26 rows selected.
SQL>


4-11) GREATEST 함수
--------------------------------------------------------------------------------

GREATEST (expr,...) 함수는 expr 중에서 가장 큰 값을 반환한다.

【예제】
SQL> select greatest(20,10,30) from dual;

GREATEST(20,10,30)
------------------
                30

SQL>


4-12) LEAST 함수
--------------------------------------------------------------------------------

LEAST (expr,...) 함수는 expr 중에서 가장 작은 값을 반환한다.

【예제】
SQL> select least(20,10,30) from dual;

GREATEST(20,10,30)
------------------
                10

SQL> select least('bb','aa','cc') from dual;

GR
--
aa

SQL>


4-13) NLS_CHARSET_DECL_LEN 함수
--------------------------------------------------------------------------------

NLS_CHARSET_DECL_LEN (byte_count , char_set_id) 함수는 nchar로 선언된 폭을 반환한다.

【예제】
SQL> select nls_charset_decl_len
  2  (200, nls_charset_id('ja16eucfixed')) from dual

NLS_CHARSET_DECL_LEN(200,NLS_CHARSET_ID('JA16EUCFIXED'))
--------------------------------------------------------
                                                     100

SQL>



4-14) NLS_CHARSET_ID 함수
--------------------------------------------------------------------------------

nls_charset_id('text') 함수는 문자셋 이름에 대응하는 ID 번호를 반환한다.
 여기서 text는 서버에서 지원되는 CHAR_CS나 NCHAR_CS이다.

【예제】
SQL> select nls_charset_id('ja16euc') from dual;

NLS_CHARSET_ID('JA16EUC')
-------------------------
                      830

SQL>


4-15) NLS_CHARSET_NAME 함수
--------------------------------------------------------------------------------

nls_charset_name('number') 함수는 문자섹 ID 번호에 대응하는 문자의 이름을 반환한다.

【예제】
SQL> select nls_charset_name(830) from dual;

NLS_CHA
-------
JA16EUC

SQL> select nls_charset_name(1) from dual;

NLS_CHAR
--------
US7ASCII

SQL>



4-16) NULLIF 함수
--------------------------------------------------------------------------------

NULLIF(expr1, expr2) 함수는
 expr1과 expr2를 비교하여
       같으면 null을 반환하고,
       같지 않으면 expr1을 반환한다.

이는 CASE 문으로 쓰면 다음과 같다.
  CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END

【예제】
SQL> select nullif('aa','AA') from dual;

NU
--
aa

SQL> select nullif('aa','aa') from dual;

NU
--


SQL>



4-17) NVL2 함수
--------------------------------------------------------------------------------

NVL2(expr1, expr2, expr3) 함수는
   expr1이 null이 아니면 expr2를 반환하고,
   expr1이 null이면 expr3을 반환한다.

【예제】
SQL> select nvl2('','Corea','Korea') from dual;

NVL2(
-----
Korea

SQL> select nvl2('aa','Corea','Korea') from dual;

NVL2(
-----
Corea

SQL>



4-18) PATH 함수
--------------------------------------------------------------------------------

PATH(correlation_path) 함수는 under_path나 equals_path의 보조함수로서,
 자원의 관계경로를 반환한다.

【예제】
SQL> select * from resource_view;
SQL> select path(1), depth(2)
  2  from resource_view
  3  where under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 1)=1?
  4    and under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 2)=1;

PATH(1)                                      DEPTH(2)
------------------------------------------ ----------
/xml.xsd                                            1
        

SQL>



4-19) SYS_CONNECT_BY_PATH 함수
--------------------------------------------------------------------------------

SYS_CONNECT_BY_PATH(column, char) 함수는 계층적 쿼리에서만 유효하며,
 column의 절대 경로를 char로 지정한 문자로 분리하여 반환한다.

【예제】
SQL> select sys_connect_by_path(name, '/') from emp
  2  start with name='jijoe'
  3  connect by prior id=1101;

SYS_CONNECT_BY_PATH(NAME,'/')
-----------------------------
/jijoe

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


4-20) SYS_CONTEXT 함수
--------------------------------------------------------------------------------

 이 함수는 namespace와 관계되는 parameter의 값을 반환한다.

【형식】
SYS_CONTEXT('namespace','parameter' [,length])

【예제】
SQL> select sys_context('userenv','session_user') from dual;

SYS_CONTEXT('USERENV','SESSION_USER')
-------------------------------------
JIJOE

SQL> select sys_context('userenv','lang') from dual;

SYS_CONTEXT('USERENV','LANG')
-----------------------------
US

SQL>

 userenv에서 사용될 parameter는 다음과 같다.
AUDITED_CURSORID AUTHENTICATION_DATA BG_JOB_ID
CLIENT_IDENTIFIER CLIENT_INFO  CURRENT_SCHEMA
CURRENT_SCHEMAID CURRENT_SQL  CURRENT_USER
CURRENT_USERID  DB_DOMAIN  DB_NAME
ENTRY_ID  EXTERNAL_NAME  FG_JOB_ID
GLOBAL_CONTEXT_MEMORY HOST   INSTANCE
IP_ADDRESS  ISDBA   LANG
LANGUAGE  NETWORK_PROTOCOL NLS_CALENDAR
NLS_CURRENCY  NLS_DATE_FORMAT  NLS_DATE_LANGUAGE
NLS_SORT  NLS_TERRITORY  OS_USER
PROXY_USER  PROXY_USERID  SESSION_USER
SESSION_USERID  SESSIONID  TERMINAL



4-21) SYS_DBURIGEN 함수
--------------------------------------------------------------------------------

이 함수는 입력된 argument에 대한 DBURIType의 URL을 반환한다.

【형식】
SYS_DBURIGEN({column|attribute} [rowid],... [,'text()'])

【예제】
SQL> select sys_dburigen(id,name) from emp
  2  where name='jijoe';

SYS_DBURIGEN(ID,NAME)(URL, SPARE)
------------------------------------------------------------------------
DBURITYPE('/PUBLIC/EMP/ROW[ID=''1104'']/NAME', NULL)

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


4-22) SYS_EXTRACT_UTC 함수
--------------------------------------------------------------------------------

sys_extract_utc(datetime_with_timezone) 함수는
UTC(coordinated universal time: Greenwich mean time) 시각을 반환한다.

【예제】
SQL> select systimestamp, sys_extract_utc(systimestamp) from dual;

SYSTIMESTAMP
--------------------------------------------------------------------------
SYS_EXTRACT_UTC(SYSTIMESTAMP)
--------------------------------------------------------------------------
06-AUG-04 02.41.39.258976 PM +09:00
06-AUG-04 05.41.39.258976 AM


SQL>


4-23) SYS_GUID 함수
--------------------------------------------------------------------------------

sys_guid() 함수는 globally unique identifier를 반환한다.

【예제】
SQL> select sys_guid() from dual;

SYS_GUID()
--------------------------------
E0F6C6D5767C01ADE034080020B588F4

SQL>


4-24) SYS_XMLAGG 함수
--------------------------------------------------------------------------------

이 함수는 sys_xmlgen 문에서 만든 XML 문을 기본적으로 ROWSET 태그를 새로 추가 시킨다.

【형식】
SYS_XMLAGG( expr [fmt] )

【예제】
SQL> select sys_xmlagg(sys_xmlgen(name)) from emp
  2  where name like 'j%';

SYS_XMLAGG(SYS_XMLGEN(NAME))
--------------------------------------------------------------------------
<ROWSET>
  <NAME>jijoe</NAME>
</ROWSET>


SQL>


4-25) SYS_XMLGEN 함수
--------------------------------------------------------------------------------

이 함수는 지정한 행이나 열을 XML 문으로 만들어 반환한다.

【형식】
SYS_XMLGEN( expr [fmt] )

【예제】
SQL> select sys_xmlgen(name) from emp
  2  where name like 'j%';

SYS_XMLGEN(NAME)
--------------------------------------------------------------------------
<NAME>jijoe</NAME>

SQL>


4-26) UID 함수
--------------------------------------------------------------------------------

UID 함수는 사용자의 유일한 ID를 정수로 반환한다.

【예제】
SQL> select uid from dual;

       UID
----------
        93

SQL>


4-27) USER 함수
--------------------------------------------------------------------------------

이 함수는 사용자의 이름을 반환한다.

【예제】
SQL> select user,uid from dual;

USER                                  UID
------------------------------ ----------
JIJOE                                  93

SQL>



4-28) USERENV 함수
--------------------------------------------------------------------------------

USERENV('parameter') 함수는 사용자의 환경에 관한 정보를 반환한다.

 parameter는 다음과 같은 것이 있다.
CLIENT_INFO ENTRYID  ISDBA  LANG
LANGUAGE SESSIONID TERMINAL

【예제】
SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.KO16KSC5601

SQL>



4-29) VSIZE 함수
--------------------------------------------------------------------------------

VSIZE('expr') 함수는 expr이 표시되는 바이트 수를 반환한다.

【예제】
SQL> select name, vsize(name) from emp
  2  where name like 'jijoe';

NAME       VSIZE(NAME)
---------- -----------
jijoe                5

SQL>

$ cat .profile
..........
NLS_LANG=AMERICAN_AMERICA.KO16KSC5601  ☜ 한글 문자셋으로 설정
export NLS_LANG
NLS_LANG=AMERICAN_AMERICA.UTF8  ☜ UNICODE로 설정
export NLS_LANG
$


테이블에서 저장된 데이터가 한글 문자셋인지 유니코드인지 식별하려면 다음과 같이 확인해 볼 수 있다.

    select 한글컬럼명, vsize(한글컬럼명) from 테이블명;

여기서 한글 컬럼에 한글이 3글자라면, vsize 결과가
    9이면 unicode이고,
    6이면 한글 문자셋으로 저장된 것임을 알 수 있다.

【예제】
SQL> select * from test;
 
        ID NAME
---------- ----------------------------------------
      1113 아리랑
      1112 쓰리랑
 
SQL> select name, vsize(name) from test;
 
NAME                                     VSIZE(NAME)
---------------------------------------- -----------
아리랑                                             6
쓰리랑                                             6
 
SQL>



4-30) XMLAGG 함수
--------------------------------------------------------------------------------

이 함수는 xmlelement에 의해서 XML 태그를 만든 문장을 모으는 기능이다.

【형식】
XMLAGG( XMLType_instance [order_by_clause])

【예제】
 SQL> select xmlagg(xmlelement("name",e.name)) from emp e;

XMLAGG(XMLELEMENT("NAME",E.NAME))
--------------------------------------------------------------------------
<name>Cho</name>
<name>Joe</name>
<name>kim</name>
<name>jijoe</name>

SQL>



4-31) XMLCOLATTVAL 함수
--------------------------------------------------------------------------------

이 함수는 XML fragment를 만드는 기능이다

【형식】
XMLCOLATTVAL( value_expr [AS c_alias],...)

【예제】
SQL> select xmlcolattval(e.name,e.id,e.salary) from emp e;

XMLCOLATTVAL(E.NAME,E.ID,E.SALARY)
--------------------------------------------------------------------------
<column name="NAME">Cho</column>
<column name="ID">1101</column>
<column name="S

<column name="NAME">Joe</column>
<column name="ID">1102</column>
<column name="S

<column name="NAME">kim</column>
<column name="ID">1103</column>
<column name="S

<column name="NAME">jijoe</column>
<column name="ID">1104</column>
<column name=


SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



4-32) XMLCONCAT 함수
--------------------------------------------------------------------------------

XMLCONCAT( XMLType_instance,...) 함수는 XMLType instance를 series로 넣어 만드는 기능이다.

【예제】
SQL> select xmlconcat(
  2    xmlelement("name",e.name),xmlelement("bonus",e.bonus))
  3  from emp e;

XMLCONCAT(XMLELEMENT("NAME",E.NAME),XMLELEMENT("BONUS",E.BONUS))
--------------------------------------------------------------------------
<name>Cho</name>
<bonus>125</bonus>

<name>Joe</name>
<bonus>100</bonus>

<name>kim</name>
<bonus>100</bonus>

<name>jijoe</name>
<bonus>100</bonus>

SQL>


4-33) XMLFOREST 함수
--------------------------------------------------------------------------------

이 함수는 각각의 argument parameter를  XML로 변환한다.

【형식】
XMLFOREST( value_expr [AS c_alias],...)

【예제】
SQL> select xmlelement("emp",
  2  xmlforest(e.id, e.name, e.bonus)) from emp e;

XMLELEMENT("EMP",XMLFOREST(E.ID,E.NAME,E.BONUS))
--------------------------------------------------------------------------
<emp>
  <ID>1101</ID>
  <NAME>Cho</NAME>
  <BONUS>125</BONUS>
</emp>

<emp>
  <ID>1102</ID>
  <NAME>Joe</NAME>
  <BONUS>100</BONUS>
</emp>

<emp>
  <ID>1103</ID>
  <NAME>kim</NAME>
  <BONUS>100</BONUS>
</emp>

<emp>
  <ID>1104</ID>
  <NAME>jijoe</NAME>
  <BONUS>100</BONUS>

</emp>

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>
 


4-34) XMLELEMENT 함수
--------------------------------------------------------------------------------

이 함수는 XML 태그를 붙이는 기능이다

【예제】
SQL> select xmlelement("name",e.name) from emp e
  2  where name like 'j%';

XMLELEMENT("NAME",E.NAME)
--------------------------------------------------------------------------
<name>jijoe</name>

SQL>



5-1) AVG* 함수
--------------------------------------------------------------------------------

조건을 만족하는 행(row)의 평균을 값을 반환하며,
 aggregate 함수나
 analytic 함수로 사용된다.

【형식】
AVG( [DISTINCT | ALL] 컬럼명)
   [ [OVER] (analytic 절)]

【예제】aggregate 예
SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL> select avg(salary) from emp;

AVG(SALARY)
-----------
        240

SQL>
【예제】analytic 예
SQL> select avg(distinct salary) over(partition by bonus)
  2  from emp;

AVG(DISTINCTSALARY)OVER(PARTITIONBYBONUS)
-----------------------------------------
                               236.666667
                               236.666667
                               236.666667
                                      250


SQL> select avg(salary) over(partition by bonus order by id
    2 rows between 1 preceding and 1 following) as avg  from emp;

       AVG
----------
       245
236.666667
       235
       250

SQL>



5-2) CORR* CORR* 함수
--------------------------------------------------------------------------------

집합 쌍의 상관관계 계수를 반환한다.

【형식】
CORR( expr1, expr2 ) [ [OVER] (analytic 절)]

【예제】
SQL> select corr(avg(bonus),max(bonus))
  2  from employees
  3  group by dept_no;

CORR(AVG(BONUS),MAX(BONUS))
---------------------------
                          1

SQL>


5-3) COUNT* 함수
--------------------------------------------------------------------------------


 쿼리한 행의 수를 반환한다.
【형식】
COUNT([*|DISTINCT|ALL] 컬럼명) [ [OVER] (analytic 절)]

【예제】
SQL> select count(*) from emp;

  COUNT(*)
----------
         4

SQL> select count (distinct dept_no) from employees;

COUNT(DISTINCTDEPT_NO)
----------------------
                     2

SQL> select count (all dept_no) from employees;

COUNT(ALLDEPT_NO)
-----------------
                4

SQL> select salary,count(*)
  2  over (order by salary)
  3  from emp;

    SALARY COUNT(*)OVER(ORDERBYSALARY)
---------- ---------------------------
       220                           1
       240                           2
       250                           4
       250                           4

SQL>



5-4) COVAR_POP 함수
--------------------------------------------------------------------------------

이 함수는 number 쌍의 집합에 대한 population covariance를 반환한다.

【형식】
COVAR_POP(expr1, expr2 [ OVER (analytic 절)] )

【예제】
SQL> select covar_pop(bonus,salary) from emp;

COVAR_POP(BONUS,SALARY)
-----------------------
                   62.5

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


5-5) COVAR_SAMP 함수
--------------------------------------------------------------------------------

이 함수는 number 쌍의 집합에 대한 sample covariance를 반환한다.

【형식】
COVAR_SAMP(expr1, expr2 [ OVER (analytic 절)] )

【예제】
SQL> select covar_samp(bonus,salary) from emp;

COVAR_SAMP(BONUS,SALARY)
------------------------
              83.3333333

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


5-6) CUME_DIST 함수
--------------------------------------------------------------------------------

이 함수는 그룹 값 내에서 어떤 값의 cumulative distribution(누적분포)을 계산한다.

【형식】
CUME_DIST(expr,... WITHIN GROUP (ORDER BY
     expr [DESC | ASC] [NULLS {FIRST|LAST}],...)
또는
CUME_DIST() over ([query_partition_clause] order_by_clause)

【예제】
SQL> select cume_dist(230) within group
  2  (order by salary ) from emp;

CUME_DIST(230)WITHINGROUP(ORDERBYSALARY)
----------------------------------------
                                      .4

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



5-7) DENSE_RANK 함수
--------------------------------------------------------------------------------


그룹 내에서 순위를 반환한다.

【예제】
SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL> select dense_rank(230, .05) within group
  2  (order by salary, bonus) "Dense Rank"
  3  from employees;

Dense Rank
----------
         2

SQL>



5-8) FIRST 함수
--------------------------------------------------------------------------------

first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK FIRST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;

     Worst       Best
---------- ----------
       220        250

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-9) GROUP_ID 함수
--------------------------------------------------------------------------------

GROUP() 함수는 group by로 분리되어 복제된 번호로 복제 횟수를 구분하도록 출력한다.
번호가 0부터 시작되므로 n번 복제되었으면 n-1의 번호가 출력된다.

【예제】
SQL> select dept_no, group_id() from employees
  2  group by dept_no;

   DEPT_NO GROUP_ID()
---------- ----------
        10          0
        20          0

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-10) Grouping 함수
--------------------------------------------------------------------------------

Grouping 함수는 Rollup이나 cube 연산자랑 함께 사용하여
 grouping 함수에서 기술된 컬럼이 그룹핑시 사용되었는지 보여주는 함수이다.
특별히 연산의 기능은 없으며,
  rollup이나 cube 연산 후 출력된 결과에 대한 사용자의 이해를 높이기 위해 사용된다.
  즉, grouping 함수를 이용할 경우 출력되는 결과값 중 null 값이 있다면,
      이 null 값이 rollup이나 cube 연산의 결과로 생성된 값인지,
      원래 테이블상에 null 값으로 저장된 것인지 확인할 수 있다.

. grouping 함수는 인수로 하나의 값만을 가진다.
. grouping 함수에 사용된 인수는 group by 절에 기술된 값 중에 하나와 반드시 일치해야 한다.
. grouping 함수의 결과값으로 0 또는 1을 반환한다.
    0은 해당인수로 쓰인 값이 rollup이나 cube 연산에 사용되었음을 나타나고,
    1은 사용되지 않았음을 의미한다.
【형식】
SELECT   컬럼명,그룹함수(컬럼명), GROUPING(컬럼명)
FROM  테이블명
WHERE  조건
GROUP BY [ROLLUP | CUBE] 그룹핑하고자하는 컬럼명,...
HAVING  그룹조건
ORDER BY 컬럼명 또는 위치번호

【예제】
SQL> select grade,deptno,sum(salary),GROUPING(deptno)
  2  from aaa
  3  group by rollup(grade,deptno);

     GRADE     DEPTNO SUM(SALARY) GROUPING(DEPTNO)
---------- ---------- ----------- ----------------
         1         10         100                0
         1         20         500                0
         1         30         300                0
         1                    900                1
         2         10         400                0
         2         20         200                0
         2         30         600                0
         2                   1200                1
                             2100                1

9 rows selected.

SQL>


5-11) GROUPING_ID 함수
--------------------------------------------------------------------------------

GROUPING_ID(expr,...) 함수는 행과 관련되는 GROUPING 비트 벡터에 대응되는 수치를 반환한다.

【예제】
SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL> select sum(salary), grouping_id(dept_no)
  2  from employees
  3  group by dept_no;

SUM(SALARY) GROUPING_ID(DEPT_NO)
----------- --------------------
        500                    0
        460                    0

SQL>


5-12) LAST 함수
--------------------------------------------------------------------------------

first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK LAST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;

     Worst       Best
---------- ----------
       220        250

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-13) MAX 함수
--------------------------------------------------------------------------------

이 함수는 최대 값을 반환한다.

【형식】
MAX ([{DISTINCT|ALL}] expr) [OVER(analytic_clause)]

【예제】
SQL> select max(salary) over (partition by dept_no)
  2  from employees;

MAX(SALARY)OVER(PARTITIONBYDEPT_NO)
-----------------------------------
                                250
                                250
                                240
                                240

SQL> select max(salary) from employees;

MAX(SALARY)
-----------
        250

SQL>


5-14) MIN 함수
--------------------------------------------------------------------------------

이 함수는 최소 값을 반환한다.

【형식】
MIN ([{DISTINCT|ALL}] expr) [OVER(analytic_clause)]

【예제】
SQL> select min(salary) over (partition by dept_no)
  2  from employees;

MIN(SALARY)OVER(PARTITIONBYDEPT_NO)
-----------------------------------
                                250
                                250
                                220
                                220

SQL> select min(salary) from employees;

MIN(SALARY)
-----------
        220

SQL>



5-15) PERCENTILE_CONT 함수
--------------------------------------------------------------------------------

이 함수는 연속 모델에 대한 inverse distribution function이다.

【형식】
PERCENTILE_CONT(expr) WITHIN GROUP (ORDER BY expr [{DESC|ASC}])
  [OVER (query_partition_cluause)]

【예제】
SQL> select dept_no,percentile_cont(0.5) within group
  2  (order by salary DESC)
  3  from employees GROUP BY dept_no;

   DEPT_NO PERCENTILE_CONT(0.5)WITHINGROUP(ORDERBYSALARYDESC)
---------- --------------------------------------------------
        10                                                250
        20                                                230

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-16) PERCENTILE_DISC 함수
--------------------------------------------------------------------------------

이 함수는 불연속 모델에 대한 inverse distribution function이다.

【형식】
PERCENTILE_DISC(expr) WITHIN GROUP (ORDER BY expr [{DESC|ASC}])
  [OVER (query_partition_cluause)]

【예제】
SQL> select dept_no,percentile_disc(0.5) within group
  2  (order by salary DESC)
  3  from employees GROUP BY  dept_no;

   DEPT_NO PERCENTILE_DISC(0.5)WITHINGROUP(ORDERBYSALARYDESC)
---------- --------------------------------------------------
        10                                                250
        20                                                240

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-17) PERCENT_RANK 함수
--------------------------------------------------------------------------------

이 함수는 CUME_DIST 함수와 유사하게 percent_rank 값을 반환한다.

【형식】
PERCENT_RANK(expr,...) WITHIN GROUP (ORDER BY expr [{DESC|ASC}]
  [NULLS {FIRST|LAST}],...)
또는
PERCENT_RANK() OVER( [query_partition_clause] order_by_clause)

【예제】
SQL> select percent_rank(230,0.05) within group
  2  (order by salary,bonus) from employees;

PERCENT_RANK(230,0.05)WITHINGROUP(ORDERBYSALARY,BONUS)
------------------------------------------------------
                                                   .25

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-18) RANK 함수
--------------------------------------------------------------------------------

이 함수는 그룹 내에서 위치를 반환한다.

【형식】
RANK(expr,...) WITHIN GROUP (ORDER BY expr [{DESC|ASC}]
  [NULLS {FIRST|LAST}],...)
또는
RANK() OVER( [query_partition_clause] order_by_clause)

【예제】
SQL> select rank(230,0.05) within group
  2 (order by salary,bonus) from employees;

RANK(230,0.05)WITHINGROUP(ORDERBYSALARY,BONUS)
----------------------------------------------
                                             2
SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-19) REGR_(linear regression) function* 함수
--------------------------------------------------------------------------------

선형 회귀(linear regression) 함수 ordinary-least squares regression line을 찾도록 한다.
 사용되는 회귀함수는 자음 중 하나이다.
 REGR_SLOPE REGR_INTERCEPT REGR_COUNT
 REGR_R2 REGR_AVGX REGR_AVGY
 REGR_SXX REGR_SYY REGR_SXY

【형식】
REGR { REGR_SLOPE|REGR_INTERCEPT|REGR_COUNT|REGR_R2|REGR_AVGX|
       REGR_AVGY|REGR_SXX|REGR_SYY|REGR_SXY}
    (expr1,expr2) [OVER (analytic_clause)]

【예제】
SQL> select regr_slope(salary,bonus) from employees

REGR_SLOPE(SALARY,BONUS)
------------------------
              .533333333

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



5-20) STDDEV 함수
--------------------------------------------------------------------------------

이 함수는 standard deviation을 반환한다.

【형식】
STDDEV [{DISTINCT|ALL}] (expr) [OVER (analytic_clause)]

【예제】
SQL> select stddev(salary) from emp;

STDDEV(SALARY)
--------------
    14.1421356

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



5-21) STDDEV_POP 함수
--------------------------------------------------------------------------------

이 함수는 population standard deviation을 반환한다.

【형식】
STDDEV_POP (expr) [OVER (analytic_clause)]

【예제】
SQL> select stddev_pop(salary) from emp;

STDDEV_POP(SALARY)
------------------
        12.2474487

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


5-22) STDDEV_SAMP 함수
--------------------------------------------------------------------------------

이 함수는 cumulative sample standard deviation을 반환한다.

【형식】
STDDEV_SAMP (expr) [OVER (analytic_clause)]

【예제】
SQL> select stddev_samp (salary) from emp;

STDDEV_SAMP(SALARY)
-------------------
         14.1421356

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100


SQL>



5-23) SUM 함수
--------------------------------------------------------------------------------

이 함수는 합계를 반환한다.

【형식】
SUM ([{DISTINCT|ALL}] expr) [OVER (analytic_clause)]

【예제】
SQL> select sum(salary) from emp;

SUM(SALARY)
-----------
        960

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



5-24) VAR_POP 함수
--------------------------------------------------------------------------------

이 함수는 population variance를 반환한다.

【형식】
VAR_POP (expr) [OVER (analytic_clause)]

【예제】
SQL> select var_pop(salary) from emp;

VAR_POP(SALARY)
---------------
            150

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100


SQL>



5-25) VAR_SAMP 함수
--------------------------------------------------------------------------------

이 함수는 sample variance를 반환한다.

【형식】
VAR_SAMP (expr) [OVER (analytic_clause)]

【예제】
SQL> select var_samp(salary) from emp;

VAR_SAMP(SALARY)
----------------
             200

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100


SQL>



5-26) VARIANCE 함수
--------------------------------------------------------------------------------

이 함수는 variance를 반환한다.

【형식】
VARIANCE ([{DISTINCT|ALL}] expr) [OVER (analytic_clause)]

【예제】
SQL> select variance(salary) from emp;

VARIANCE(SALARY)
----------------
             200

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



5-27) Grouping sets 함수
--------------------------------------------------------------------------------

Grouping sets 함수는 Group by의 확장된 형태로 하나의 쿼리문에서 원하는 그룹핑 조건을 여러 개 기술할 수 있으며,
 grouping sets 함수 사용이 불가능한 이전 버전에서
 복잡한 union all 연산자를 사용하여 기술하던 것을 간단하게
 한 문장 안에서 해결할 수 있어 검색시 효율성이 증대 된다.
 다시 말해서, grouping sets 함수를 사용하면,
              group by ... union all을 사용한 것보다
              SQL 문이 간단해지고 또한 실행시 성능이 빨라진다.
【형식】
SELECT   컬럼명,그룹함수(컬럼명), GROUPING(컬럼명)
FROM  테이블명
WHERE  조건
GROUP BY [ROLLUP | CUBE] 그룹핑하고자하는 컬럼명, ...
  [GROUPING SETS (컬럼명,컬럼명, ...), ...]
HAVING  그룹조건
ORDER BY 컬럼명 또는 위치번호

【예제】
SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grouping sets(grade,deptno);

     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1                    900
         2                   1200
                   10         500
                   20         700
                   30         900

SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grouping sets((grade,name),(deptno,name));

     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1                    100
         1                    300
         1                    500
         2                    200
         2                    400
         2                    600
                   10         100
                   20         200
                   30         300
                   10         400
                   20         500
                   30         600

12 rows selected.
SQL>
【예제】Union all을 사용한 경우
SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grade,deptno
  4  union all
  5  select grade,deptno,sum(salary)
  6  from aaa
  7  group by grade,deptno;

     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1         10         100
         1         20         500
         1         30         300
         2         10         400
         2         20         200
         2         30         600
         1         10         100
         1         20         500
         1         30         300
         2         10         400
         2         20         200
         2         30         600

12 rows selected.

SQL>

composite columns란 rollup, cube, grouping sets 절과 같은 기능을 사용하면
표현되는 각 컬럼이 하나가 아닌 복수 개의 컬럼으로 정의되는 경우이며
다음 표를 보고 이해하자.
composite column 문의 경우  group by 문의 경우 group by grouping sets(a,b,c)  group by a union allgroup by b union allgroup by c  group by grouping sets(a,b,(b,c))  group by a union allgroup by b union allgroup by b,c  group by grouping sets((a,b,c))  group by a,b,c  group by grouping sets(a,(b),())  group by a union allgroup by b union allgroup by ()  group by grouping sets(a,rollup(b,c))  group by a union allgroup by rollup(b,c)  group by rollup(a,b,c)  group by (a,b,c) union allgroup by (a,b) union allgroup by (a) union allgroup by ()  group by cube(a,b,c)  group by (a,b,c) union allgroup by (a,b) union allgroup by (a,c) union allgroup by (b,c) union allgroup by (a) union allgroup by (b) union allgroup by (c) union allgroup by () 



6-1) AVG* 함수
--------------------------------------------------------------------------------

조건을 만족하는 행(row)의 평균을 값을 반환하며,
 aggregate 함수나
 analytic 함수로 사용된다.

【형식】
AVG( [DISTINCT | ALL] 컬럼명)
   [ [OVER] (analytic 절)]

【예제】aggregate 예
SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL> select avg(salary) from emp;

AVG(SALARY)
-----------
        240

SQL>
【예제】analytic 예
SQL> select avg(distinct salary) over(partition by bonus)
  2  from emp;

AVG(DISTINCTSALARY)OVER(PARTITIONBYBONUS)
-----------------------------------------
                               236.666667
                               236.666667
                               236.666667
                                      250


SQL> select avg(salary) over(partition by bonus order by id
    2 rows between 1 preceding and 1 following) as avg  from emp;

       AVG
----------
       245
236.666667
       235
       250

SQL>



6-2) CORR* CORR* 함수
--------------------------------------------------------------------------------

집합 쌍의 상관관계 계수를 반환한다.

【형식】
CORR( expr1, expr2 ) [ [OVER] (analytic 절)]

【예제】
SQL> select corr(avg(bonus),max(bonus))
  2  from employees
  3  group by dept_no;

CORR(AVG(BONUS),MAX(BONUS))
---------------------------
                          1

SQL>


6-3) COUNT* 함수
--------------------------------------------------------------------------------


 쿼리한 행의 수를 반환한다.
【형식】
COUNT([*|DISTINCT|ALL] 컬럼명) [ [OVER] (analytic 절)]

【예제】
SQL> select count(*) from emp;

  COUNT(*)
----------
         4

SQL> select count (distinct dept_no) from employees;

COUNT(DISTINCTDEPT_NO)
----------------------
                     2

SQL> select count (all dept_no) from employees;

COUNT(ALLDEPT_NO)
-----------------
                4

SQL> select salary,count(*)
  2  over (order by salary)
  3  from emp;

    SALARY COUNT(*)OVER(ORDERBYSALARY)
---------- ---------------------------
       220                           1
       240                           2
       250                           4
       250                           4

SQL>



6-4) COVAR_SAMP 함수
--------------------------------------------------------------------------------

이 함수는 number 쌍의 집합에 대한 sample covariance를 반환한다.

【형식】
COVAR_SAMP(expr1, expr2 [ OVER (analytic 절)] )

【예제】
SQL> select covar_samp(bonus,salary) from emp;

COVAR_SAMP(BONUS,SALARY)
------------------------
              83.3333333

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>



6-5) CUME_DIST 함수
--------------------------------------------------------------------------------

이 함수는 그룹 값 내에서 어떤 값의 cumulative distribution(누적분포)을 계산한다.

【형식】
CUME_DIST(expr,... WITHIN GROUP (ORDER BY
     expr [DESC | ASC] [NULLS {FIRST|LAST}],...)
또는
CUME_DIST() over ([query_partition_clause] order_by_clause)

【예제】
SQL> select cume_dist(230) within group
  2  (order by salary ) from emp;

CUME_DIST(230)WITHINGROUP(ORDERBYSALARY)
----------------------------------------
                                      .4

SQL> select * from emp;

        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>


6-6) DENSE_RANK 함수
--------------------------------------------------------------------------------


그룹 내에서 순위를 반환한다.

【예제】
SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL> select dense_rank(230, .05) within group
  2  (order by salary, bonus) "Dense Rank"
  3  from employees;

Dense Rank
----------
         2

SQL>


6-7) FIRST 함수
--------------------------------------------------------------------------------

first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK FIRST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;

     Worst       Best
---------- ----------
       220        250

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>


6-8) FIRST_VALUE 함수
--------------------------------------------------------------------------------

이 함수는 서열화된 값에서 첫 번째를 출력한다.

【형식】
FIRST_VALUE ( expr ) OVER ( analytic_절)

【예제】
SQL> select salary,first_value(name)
  2  over (order by salary asc)
  3  from (select * from employees
  4        where dept_no = 20
  5        order by salary);

    SALARY FIRST_VALU
---------- ----------
       220 jijoe
       240 jijoe

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>


6-9) LAG 함수
--------------------------------------------------------------------------------

이 함수는 analytic 함수로서,
self join하지 않고 하나의 테이블에서 동시에 한 행(row) 이상을 접근할 수 있도록 한다.

【형식】
LAG ( value_expr [,offset] [,default] )
     OVER ([query_partition_clause] order_by_clause )

【예제】
SQL> select name,salary,LAG(salary,1,0)    
  2   OVER (ORDER BY salary) FROM employees;

NAME           SALARY LAG(SALARY,1,0)OVER(ORDERBYSALARY)
---------- ---------- ----------------------------------
jijoe             220                                  0
Joe               240                                220
Cho               250                                240
kim               250                                250

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



6-10) LAST_VALUE 함수
--------------------------------------------------------------------------------

이 함수는 서열화된 값에서 마지막 번째를 출력한다.

【형식】
LAST_VALUE ( expr ) OVER ( analytic_절)

【예제】
SQL> select salary,last_value(name)
  2  over (order by salary asc)
  3  from (select * from employees
  4        where dept_no = 20
  5        order by salary);

    SALARY LAST_VALUE
---------- ----------
       220 jijoe
       240 Joe

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



6-11) LEAD 함수
--------------------------------------------------------------------------------

이 함수는 analytic 함수로서, self join하지 않고
하나의 테이블에서 동시에 한 행(row) 이상을 접근할 수 있도록 한다.

【형식】
LEAD ( value_expr [,offset] [,default] )
     OVER ([query_partition_clause] order_by_clause )

【예제】
SQL> select name,salary,LEAD(salary,1,0)   
  2   OVER (ORDER BY salary) FROM  employees;

NAME           SALARY LEAD(SALARY,1,0)OVER(ORDERBYSALARY)
---------- ---------- -----------------------------------
jijoe             220                                 240
Joe               240                                 250
Cho               250                                 250
kim               250                                   0

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>


6-12) NTILE 함수
--------------------------------------------------------------------------------

이 함수는 analytic 함수로서, 데이터를 주어진 bucket 수 expr로 분리한다.

【형식】
NTILE ( expr ) OVER ([query_partition_clause] order_by_clause )

【예제】
SQL> select name,salary,NTILE(3) OVER (ORDER BY salary DESC)
  2  FROM  employees;

NAME           SALARY NTILE(3)OVER(ORDERBYSALARYDESC)
---------- ---------- -------------------------------
Cho               250                               1
kim               250                               1
Joe               240                               2
jijoe             220                               3

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



6-13) RATIO_TO_REPORT 함수
--------------------------------------------------------------------------------

이 함수는 analytic 함수로서, 데이터 합에 대한 구성비를 계산한다.

【형식】
RATIO_TO_REPORT ( expr ) OVER ([query_partition_clause])

【예제】
SQL> select name,salary,RATIO_TO_REPORT(salary) OVER ()
  2   FROM  employees;

NAME           SALARY RATIO_TO_REPORT(SALARY)OVER()
---------- ---------- -----------------------------
Cho               250                    .260416667
Joe               240                           .25
kim               250                    .260416667
jijoe             220                    .229166667

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



6-14) ROW_NUMBER 함수
--------------------------------------------------------------------------------

이 함수는 analytic 함수로서, 각 행(row)에 unique 번호를 부여한다.

【형식】
ROW_NUMBER () OVER ([query_partition_clause] order_by_clause )

【예제】
SQL> SELECT ROW_NUMBER() OVER (ORDER BY salary DESC),name
  2    FROM  employees;

ROW_NUMBER()OVER(ORDERBYSALARYDESC) NAME      
----------------------------------- ----------
                                  1 Cho       
                                  2 kim       
                                  3 Joe       
                                  4 jijoe     

SQL> select * from employees;

        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100

SQL>



7-1) REF 타입
--------------------------------------------------------------------------------
테이블의 어떤 컬럼이 독립된 다른 객체 테이블을 참조하는 데이터 타입을 의미한다.
일반적으로 테이블을 만들때 사용하는 외부키(foreign-key)를 이용한 참조관계와 유사하다.
REF 타입의 컬럼 데이터를 읽을 때는 반드시 DEREF 함수를 사용한다.
REF 타입으로 정의된 컬럼에는 실제 데이터가 저장되는 것이 아니고 참조되는 객체가 존재하는 포인트정보만 가지고 있기 때문에 객체가 삭제 된다면, 해당 컬러은 정상적으로 검색되지 못한다.
이러한 현상을 REF의 Dangling 현상이고 한다.
이러한 dangling 현상을 방지하기 위해서는 삭제된 객체 정보를 참조하는 행의 컬럼 정보를 analyze 명령어를 이용하여 null 값으로 변경해 주어야 한다.
【예제】
SQL> connect jijoe/jijoe_password
connected

SQL> create type person_type as object(
  2  first_name         varchar2(10),
  3  last_name          varchar2(10),
  4  phone              varchar(12),
  5  birthday           varchar2(12));
  6  /

Type created.

SQL> create type emp_type as object (
  2  empno      number,
  3  emp        person_type);
  4  /

Type created.

SQL> create table emp2 of emp_type
  2  oidindex emp_oid;

Table created.

SQL> insert into emp2 values(
  2  emp_type(1000,person_type('junik','joe','123-1234','20-jul-04')));

1 row created.

SQL> create table dept(
  2  empno      number(4),
  3  ename      varchar2(15),
  4  mgr        REF emp_type SCOPE IS emp2);

Table created.

SQL> insert into dept
  2  select empno, 'SCOTT', REF(e)
  3  from emp2 e
  4  where empno=1000;

1 row created.


【예제】
SQL> select ename,empno from dept;

ENAME                EMPNO
--------------- ----------
SCOTT                 1000

SQL> select mgr, DEREF(mgr) from dept;

MGR
--------------------------------------------------------------------------------
DEREF(MGR)(EMPNO, EMP(FIRST_NAME, LAST_NAME, PHONE, BIRTHDAY))
--------------------------------------------------------------------------------
0000220208DFA05B27A63701D9E034080020B588F4DFA05B27A63601D9E034080020B588F4
EMP_TYPE(1000, PERSON_TYPE('junik', 'joe', '123-1234', '20-jul-04'))


SQL>

【예제】
SQL> select empno,ename,mgr
  2  from dept
  3  where mgr is dangling;

no rows selected

SQL> analyze table dept validate REF update set dangling to NULL;

Table analyzed.

SQL>


8-1) ROWID 컬럼
--------------------------------------------------------------------------------

오라클에서 내부적으로 사용되는 컬럼을 pseudocolumn이라고 하며,
ROWID, ROWNUM등이 있다.
ROWID는 데이터베이스에서 컬럼이 위치한 장소이다.

【예제】
SQL> select rowid from test;

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';

ROWID
------------------
AAAHbHAABAAAMXCAAA

SQL> select lengthb(rowidtonchar(rowid)), rowidtonchar(rowid)
  2  from test;

LENGTHB(ROWIDTONCHAR(ROWID)) ROWIDTONCHAR(ROWID
---------------------------- ------------------
                          36 AAAHbHAABAAAMXCAAA

SQL>


여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호



8-2) ROWNUM 컬럼
--------------------------------------------------------------------------------

오라클에서 내부적으로 사용되는 컬럼을 pseudocolumn이라고 하며,
ROWID, ROWNUM등이 있다.
ROWNUM은 테이블에서 select 되어진 일련 번호임
【예제】
SQL> select rownum,ename from emp;
 
    ROWNUM ENAME
---------- ----------
         1 CLARK
         2 MILLER
         3 JONES
         4 ALLEN
         5 MARTIN
         6 CHAN
 
6 rows selected.
 
SQL> delete from emp where ename='JONES';
 
1 row deleted.
 
SQL> select rownum,ename from emp;
 
    ROWNUM ENAME
---------- ----------
         1 CLARK
         2 MILLER
         3 ALLEN
         4 MARTIN
         5 CHAN
 
SQL>

Posted by 1010