1. XML Query 사용법

조회 수 3073 추천 수 0 2011.05.10 14:09:31
SMaker *.22.160.117

개요

  1. XpressEngine는 query문을 직접 사용하지 않습니다.
  2. 이는 다양한 DBMS를 지원하기 위해서입니다.
  3. XML Query문의 확장자는 .xml 입니다.

사용법

모듈 또는 애드온, 위젯 등에서 아래와 같이 사용할 수 있습니다.

$args->name = 'zero';
$output = executeQuery('member.getMemberInfo', $args);

XML Query를 호출하여 실제 DB의 데이터를 받거나 조작하기 위해서 사용되는 executeQuery() 함수는 DB::executeQuery()의 alias입니다.

function executeQuery($xml_query_name, $args = null);

첫번째 인자로 실행하고자 하는 XML Query의 이름을 받게 됩니다.
이름은 모듈이나 위젯, 애드온에 따라 다릅니다.

모듈의 XML Query를 실행하고자 하는 경우

모듈이름.쿼리ID

위젯의 XML Query를 실행하고자 하는 경우

widgets.위젯이름.쿼리ID

애드온의 XML Query를 실행하고자 하는 경우

addons.애드온이름.쿼리ID

두번째 인자인 $args는 null 일수도 있고 해당 XML Query에서 필요 시 stdClass의 variables type으로 변수의 key, value를 설정 후 인자로 넘기게 됩니다.

결과는 Object class의 객체로 return 됩니다.

쿼리가 실패했다면 $output->toBool()이 false일 경우이고 true라면 쿼리는 정상적으로 실행이 된 것을 의미합니다.
select문의 결과 데이터는 $ouptut->data 변수에 담겨져 return 됩니다.

XML sample

  1. <query id="쿼리아이디" action="select|update|delete|insert">
        <tables>
            <table name="원테이블이름" alias="alias" />
            ...
        </tables>

        <columns>
            <column name="컬럼명" alias="alias" />
            ...
        </columns>

        <conditions>
            <condition operation="조건걸" column="Column명" var="변수명" filter="필터형식" default="기본값" notnull="notnull" minlength="최소길이" maxlength="최대길이" pipe="연결연산자" />
            ...
            <group pipe="연결연산자">
                <condition operation="조건걸" column="Column명" var="변수명" filter="필터형식" default="기본값" notnull="notnull" minlength="최소길이" maxlength="최대길이" pipe="연결연산자" />
                ...
            </group>
            ...
        </conditions>

        <navigation>
            <index var="이름" default="기본값" order="desc|asc" />
            <list_count var="변수명" default="기본값" />
            <page_count var="변수명" default="기본값" />
            <page var="변수명" default="변수명" />
        </navigation>

        <groups>
            <group column="GroupBy 대상" />
        </groups>
    </query>
  • <query>의 attribute
    • id : 쿼리를 찾을 수 있는 아이디입니다.
    • action : select, update, delete insert 4가지 종류가 있습니다.
  • <tables>
    • 테이블 조인 시 여러 개의 <table>을 사용할 수 있습니다.
    • name : 원 테이블 명 (XE에서의 테이블 머릿말(prefix)는 무시)
    • alias : join 또는 다른 용도로 원 테이블 명을 바꾸어 사용할 경우
  • <columns>
    • 처리하고자 하는 컬럼명을 입력하시면 됩니다.
    • name : 컬럼명
    • alias : 다른 이름으로 바꾸어 결과를 만들고자 할 경우 지정
  • <conditions>
    • 조건절을 구성합니다.
    • 조건절을 여러 개의 그룹으로 사용하고자 할 때에는 <group> 태그를 이용해 묶어 주실 수 있습니다.
  • <group> ... </group>
    • 조건절을 그룹으로 사용할 경우 pipe="and|or" 을 이용하여 그룹끼리의 조건을 지정할 수 있습니다.
  • <condition>
    • operation : 아래와 같은 연산자로 처리가 됩니다.
      • equal : column = (var|default)
      • more : column >= (var|default)
      • excess : column > (var|default)
      • less : column <= (var|default)
      • below : column < (var|default)
      • notequal : column != (var|default)
      • notnull : column is not null
      • null : column is null
      • like_prefix : column like 'var|default%'
      • like_tail : column like '%var|default'
      • like : column like '%var|default%'
      • in : column in (var|default)
      • notin : column not in (var|default)
    • column : 칼럼명을 지정할 수 있습니다.
    • var : executeQuery() 함수에서 2번째 인자의 key 값을 지정할 수 있습니다.
    • filter : var 값의 조건을 filtering 합니다. filter에 맞지 않으면 var 값이 null이 되어 default 값으로 대체됩니다. 아래와 같은 filter를 지원합니다.
      • email, email_address : 메일 형식
      • homepage : http|https:// 등의 홈페이지 형식
      • userid, user_id : 사용자 아이디 형식 (첫글자는 영문, 2번째부터는 숫자+영문+_)
      • number : 숫자만 허용
      • alpha : 영문자만 허용
      • alpha_number : 숫자+영문자만 허용
    • default : var 값이 null 일 경우 default 값으로 대체됩니다. 아래와 같은 함수값을 가질 수도 있습니다.
      • ipaddress() : 접속자의 ip 주소
      • unixtime() : unix time (php의 time() 함수)
      • curdate : 현재 시간 (YYYYMMDDHHIISS)
      • plus(int count) : column = column + count
      • minus(int count) : column = column - count
    • notnull : not null check를 하게 됩니다.
    • minlength : 최소 길이를 검사합니다.
    • maxlength : 최대 길이를 검사합니다.
    • pipe : and|or등의 조건을 지정할 수 있습니다.
  • <navigation> : navigation은 정렬 순서(order by) 또는 페이징 기능을 지원합니다.
    • <index> 정렬할 칼럼과 정렬 방법을 지정할 수 있습니다.
      • var : 대상 컬럼명을 담은 변수명
      • default : var 값이 없을 경우 기본으로 정렬할 컬럼명 지정
      • order : asc|desc
    • <list_count> 페이징을 한 결과를 받을 수 있습니다.
      • var : 목록의 rows를 지정
      • default : var 값이 없을 경우 기본 rows 값
    • <page_count> 페이징 계산 시에 페이지 네비게이션의 수를 지정
      • var : 페이지 네비게이션의 수
      • default : var 값이 없을 경우 기본 페이징 네비게이션의 수
    • <page> 현재 몇번째 페이지인지를 지정할 수 있습니다.
      • var : 현재 몇번째 페이지인지를 지정할 변수
      • default : var 값이 지정되지 않았을 경우 페이지 번호
  • <groups> : group by 절을 사용할 수 있습니다.
    • <group> 그룹핑할 칼럼을 지정할 수 있습니다.
      • column : 그룹핑할 칼럼명 지정

Select query 예제

  • member.getMemberList : member테이블에서 특정 조건을 가진 회원들을 페이징을 하면서 select

    1. <query id="getMemberList" action="select">
      <tables>
         <table name="member" />
      </tables>

    2. <columns>
         <column name="*" />
      </columns>

    3. <conditions>
          <condition operation="equal" column="is_admin" var="is_admin" />
         <condition operation="equal" column="denied" var="is_denied" pipe="and" />
         <group pipe="and">
              <condition operation="like" column="user_id" var="s_user_id" />
              <condition operation="like" column="user_name" var="s_user_name" pipe="or" />
              <condition operation="like" column="nick_name" var="s_nick_name" pipe="or" />
              <condition operation="like" column="email_address" var="s_email_address" pipe="or" />
              <condition operation="like_prefix" column="regdate" var="s_regdate" pipe="or" />
              <condition operation="like_prefix" column="last_login" var="s_last_login" pipe="or" />
          </group>
      </conditions>

      <navigation>
          <index var="sort_index" default="member_srl" order="desc" />
          <list_count var="list_count" default="20" />
          <page_count var="page_count" default="10" />
          <page var="page" default="1" />
      </navigation>
      </query>
  • document.getMonthlyArchivedList : 모듈을 '년월'일을 기준으로 group by 한 결과를 가져옴
  1. <query id="getMonthlyArchivedList" action="select">
    <tables>
        <table name="documents" />
    </tables>

    <columns>
        <column name="substr(regdate,1,6)" alias="month"/>
        <column name="count(*)" alias="count" />
    </columns>

    <conditions>
       <condition operation="in" column="module_srl" var="module_srl" filter="number" />
    </conditions>

    <groups>
        <group column="substr(regdate,1,6)" />
    </groups>
    </query>

Join Select 예제

document.getTrashList 예제입니다.

<query id="getTrashList" action="select">
    <tables>
        <table name="documents" />
        <table name="document_trash" />
    </tables>
    <columns>
        <column name="documents.*" />
        <column name="document_trash.trash_srl" alias="trash_srl" />
        <column name="document_trash.module_srl" alias="module_srl" />
        <column name="document_trash.trash_date" alias="trash_date" />
        <column name="document_trash.description" alias="trash_description" />
        <column name="document_trash.ipaddress" alias="trash_ipaddress" />
        <column name="document_trash.user_id" alias="trash_user_id" />
        <column name="document_trash.user_name" alias="trash_user_name" />
        <column name="document_trash.nick_name" alias="trash_nick_name" />
        <column name="document_trash.member_srl" alias="trash_member_srl" />
    </columns>
    <conditions>
        <condition operation="equal" column="document_trash.document_srl" default="documents.document_srl" notnull="notnull" />
        <condition operation="in" column="document_trash.module_srl" var="module_srl" filter="number" pipe="and" />
        <condition operation="equal" column="document_trash.member_srl" var="member_srl" filter="number" pipe="and" />

        <group pipe="and">
            <condition operation="like" column="documents.title" var="s_title" />
            <condition operation="like" column="documents.content" var="s_content" pipe="or" />
            <condition operation="like" column="documents.user_name" var="s_user_name" pipe="or" />
            <condition operation="like" column="documents.user_id" var="s_user_id" pipe="or" />
            <condition operation="like" column="documents.nick_name" var="s_nick_name" pipe="or" />
            <condition operation="like" column="documents.email_address" var="s_email_addres" pipe="or" />
            <condition operation="like" column="documents.homepage" var="s_homepage" pipe="or" />
            <condition operation="like" column="documents.tags" var="s_tags" pipe="or" />
            <condition operation="equal" column="documents.is_secret" var="s_is_secret" pipe="or" />
            <condition operation="equal" column="documents.member_srl" var="s_member_srl" pipe="or" />
            <condition operation="more" column="documents.readed_count" var="s_readed_count" pipe="or" />
            <condition operation="more" column="documents.voted_count" var="s_voted_count" pipe="or" />
            <condition operation="more" column="documents.comment_count" var="s_comment_count" pipe="or" />
            <condition operation="more" column="documents.trackback_count" var="s_trackback_count" pipe="or" />
            <condition operation="more" column="documents.uploaded_count" var="s_uploaded_count" pipe="or" />
            <condition operation="like_prefix" column="documents.regdate" var="s_regdate" pipe="or" />
            <condition operation="like_prefix" column="documents.last_update" var="s_last_update" pipe="or" />
            <condition operation="like_prefix" column="documents.ipaddress" var="s_ipaddress" pipe="or" />
        </group>


    </conditions>
    <navigation>
        <index var="sort_index" default="documents.list_order" order="order_type" />
        <list_count var="list_count" default="20" />
        <page_count var="page_count" default="10" />
        <page var="page" default="1" />
    </navigation>
</query>

Letf Join Select 예제

<query id="getDocumentsExtraVars" action="select">
    <tables>
        <table name="document_extra_keys" alias="extra_keys" />
        <table name="document_extra_vars" alias="extra_vars" type="left join">
            <conditions>
                <condition operation="equal" column="extra_keys.module_srl" default="extra_vars.module_srl" />
                <condition operation="in" column="extra_vars.document_srl" var="document_srl" pipe="and" />
                <condition operation="equal" column="extra_keys.eid" default="extra_vars.eid" pipe="and" />
            </conditions>
        </table>
    </tables>
    <columns>
        <column name="extra_keys.module_srl" alias="module_srl" />
        <column name="extra_keys.var_name" alias="name" />
        <column name="extra_keys.var_type" alias="type" />
        <column name="extra_keys.var_is_required" alias="is_required" />
        <column name="extra_keys.var_search" alias="search" />
        <column name="extra_keys.var_default" alias="default" />
        <column name="extra_keys.var_desc" alias="desc" />
        <column name="extra_keys.var_idx" alias="idx" />
        <column name="extra_vars.document_srl" alias="document_srl" />
        <column name="extra_vars.lang_code" alias="lang_code" />
        <column name="extra_vars.value" alias="value" />
        <column name="extra_keys.eid" alias="eid" />
    </columns>
    <navigation>
        <index var="sort_index" default="extra_keys.var_idx" order="asc" />
    </navigation>
</query>

Insert 예제

  • document.insertCategory : 문서 카테고리 추가

    1. <query id="insertCategory" action="insert">
      <tables>
          <table name="document_categories" />
      </tables>

      <columns>
          <column name="category_srl" var="category_srl" filter="number" notnull="notnull" />
          <column name="module_srl" var="module_srl" filter="number" default="0" notnull="notnull" />
          <column name="title" var="title" notnull="notnull" minlength="2" maxlength="250" />
          <column name="document_count" var="document_count" default="0" />
          <column name="regdate" var="regdate" default="curdate()" />
          <column name="last_update" var="last_update" default="curdate()" />
          <column name="list_order" var="list_order" default="0" />
      </columns>
      </query>

update 예제

  • document.updateCategory : 특정 카테고리의 제목이나 순서, 최근 수정일을 변경

    1. <query id="updateCategory" action="update">
      <tables>
          <table name="document_categories" />
      </tables>

      <columns>
          <column name="title" var="title" />
          <column name="list_order" var="list_order" />
          <column name="last_update" var="last_update" default="curdate()" />
      </columns>

      <conditions>
          <condition operation="equal" column="category_srl" var="category_srl" filter="number" notnull="notnull" />
      </conditions>
      </query>

delete 예제

  • document.deleteCategory : 특정 카테고리를 삭제

    1. <query id="deleteCategory" action="delete">
      <tables>
          <table name="document_categories" />
      </tables>

      <conditions>
          <condition operation="equal" column="category_srl" var="category_srl" filter="number" notnull="notnull" />
      </conditions>
      </query>

Select Click Count 예제

Select 시 조회수 등의 정수의 숫자 컬럼을 +1 하는 기능입니다.

Cubrid의 경우에는 incr()이라는 함수를 사용하고 다른 데이타베이스의 경우 해당 컬럼을 Select후 Update 합니다.

XE Core 1.2.6 이상 버전에서 지원하고 있습니다.

document.getDocument XML Query에 Click Count 를 적용해 본 예제입니다.

select시 정수 숫자 컬럼 node에 attribute는 click_count, 값은 Argument로 매핑되는 변수명을 기입합니다.

<query id="getDocument" action="select">
    <tables>
        <table name="documents" />
    </tables>

    <columns>
        <column name="document_srl" />
        <column name="module_srl" />
        <column name="category_srl" />
        <column name="lang_code" />
        <column name="is_notice"  />
        <column name="is_secret"  />
        <column name="title"  />
        <column name="title_bold" />
        <column name="title_color" />
        <column name="content"  />
        <column name="readed_count" click_count="incr_readed_count"/>
        <column name="voted_count" />
        <column name="blamed_count" />
        <column name="comment_count" />
        <column name="trackback_count" />
        <column name="uploaded_count" />
        <column name="password"  />
        <column name="user_id"  />
        <column name="user_name"  />
        <column name="nick_name" />
        <column name="member_srl"  />
        <column name="email_address"  />
        <column name="homepage" />
        <column name="tags" />
        <column name="extra_vars" />
        <column name="regdate" />
        <column name="last_update"  />
        <column name="last_updater" />
        <column name="ipaddress"  />
        <column name="list_order"  />
        <column name="update_order"  />
        <column name="allow_comment"  />
        <column name="lock_comment" />
        <column name="allow_trackback" />
        <column name="notify_message" />
    </columns>
    <conditions>
        <condition operation="equal" column="document_srl" var="document_srl" filter="number" notnull="notnull" />
    </conditions>
</query>

click_count 의 매핑변수 값이 true이면 해당 컬럼을 +1 증가합니다.

$args->document_srl = $this->document_srl;
$args->incr_readed_count = true;
$output = executeQuery('document.getDocument', $args);


잇큐

2010.11.26 17:15:37
*.57.163.94

php 기본에 쿼리 초보가 ... 쿼리문에 막 익숙해 진 상태에서는 정말 .. ㅡㅡ;; 복잡하게 느껴지는군요...


profile

씨지

2010.12.01 12:34:04
*.10.175.181

입문하는 분들을 위해서 위 xml예제들이
가장많이 사용하는 MySql 과 요즘 밀고 계시는 큐브리드의 실제쿼리문으로 해석된 결과를 함께 적는게어떨까하고건의드려봅니다. ^^

묻고답하기에 올라왔던 질문링크 http://www.xpressengine.com/19299110

st.june

2011.01.16 21:43:20
*.39.176.17

저도 개발자 매뉴얼 삼아 쭉 읽고 있는데... 이번 글에서는 마치 우주를 체험한 느낌이 드는군요.

zb4에서 select, insert, update, delete 사용했던 것처럼 하려면 어떻게 코드를 작성해야 하는지 알고 싶은데 코드가 너무 방대해요.

황진성

2011.02.20 00:28:28
*.204.8.67

like_prefix 와 like_tail이 설명이 반대로 되어있네요!!!!

SMaker

2011.02.20 09:43:40
*.22.160.117

오류를 수정하였습니다.


감사합니다 :D

황진성

2011.02.20 13:03:03
*.204.8.67

헉.. 빠르다.. 일요일인데 수정해주셨네요 ~ 한시간 고생햇었는데 기분 싹 풀리는데요 ^^

차오이

2011.05.09 23:39:17
*.203.195.211

큐브리드 기준으로 모듈을 개발하고 있습니다.
그런데, SELECT 할 때 SQL 힌트를 주는 것과 안 주는 것의 SELECT 속도가 많이 차이가 납니다.

해서, "/*+ USE_IDX */" 를 추가로 주려고 하는데, 어떻게 해야 할까요??

쿼리 힌트 관련 큐브리드 도움말: http://www.cubrid.com/online_manual/840/syntax/syntax_retreive_opt_hint.htm

select /*+ USE_IDX */ "a"."member_srl" as "member_srl","a"."user_name" as "user_name","a"."user_id" as "user_id"
from "xe_member" as "a"
left join "xe_timebook" "b" on ("a"."member_srl" = "b"."member_srl")
group by "a"."member_srl"

SMaker

2011.05.10 14:09:30
*.22.160.117

1.5.0 버전에서 MySQL 인덱스 힌트가 추가되었습니다.


곧 다른 DBMS에서도 추가되지 않을까요?