티스토리 뷰

 

| OGNL (Object Graph Navigation Language)

MyBatis는 XML element를 줄이고 다양한 조건을 처리하기 위해 OGNL 표현식을 사용합니다.

(jsp에서 주로 사용하는 JSTL 표현식이 OGNL이기 때문에 이를 사용하던 개발자는 MyBatis의 조건문에 적용하면 됩니다.)

 

MyBatis는 "동적SQL처리" 를 지원하기 위해 지정된 엘리먼트들을 제공합니다.

그리고 기존 ibatis에서 제공되어지던 다수의 엘리먼트들은 OGNL기반의 표현식이 도입됨으로써 많이 사라지고 다음과 같은것들로 대체 됨으로써 개발자가 알아야할 엘리먼트의 개수는 줄었다는 장점이 존재합니다.

 

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

| if문

<if test=" property != '' and property != null ">
  WHERE COL1 = #{property}
</if>

여기에서 " property != '' and property != null " 이 부분이 OGNL 표현식입니다. OGNL이 대체 뭘까요? 위키에서 OGNL(Object-Graph Navigation Language)의 뜻을 확인해보면 객체에 접근하기 위한 언어라고 명시하고있습니다.

 

그럼 mybatis는 OGNL을 어떻게 지원하고 있을까요?

아주 기본적인 것부터 분석해보니 and와 or처럼 test 연산을 위한 예약어를 제외하고는 싱글쿼테이션(')이나 더블쿼테이션(") 없이 문자열이 들어오게되면 어떤 객체라고 판단을 하고 해당 객체에 접근하기 위한 다양한 처리가 수행되어 객체로 접근하게 된다는걸 우리는 경험을 통해 알 수 있습니다.

 

추가적으로 객체에서 제공되는 메소드 호출또한 가능합니다.

 

즉 mybatis에서 제공하는 OGNL기반의 표현식을 통해 개발자는 아무렇지 않게 어떤 객체값을 확인하고 분기처리하는게 쉬워졌죠.

근데 여기서 주의해야될 점이 있습니다.

mybatis에서 객체값을 비교할 경우 싱글쿼테이션으로 감싸주어서 사용하는 경우가 있는데 mybatis에게 “이건 property가 아니고 어떤 이야” 라고 알려 주는거지 문자열이라고 명시해 주는게 아니라는 점 입니다.

 

 

| choose(when, otherwise)

 

if와 달리 choose는 여러 상황들 중 하나의 상황에서만 동작합니다.

Java언어의 if~ else 나 JSTL의 <choose>와 유사합니다.

<otherwise>는 모든 조건이 충족되지 않을 경우에 사용합니다.

 

<select id="selectMember" parameterType="map", resultType="map">
    SELECT  USER_NO
            USER_ID
            NAME
            REG_DT
    FROM    USER
    <choose>
    	<when test "userNo != null">
    	WHERE USER_NO = #{userNo}
    	</when>
        <when test "name != null">
        WHERE NAME = #{name}
        </when>
        <otherwise>
        WHERE USER_NO = 1
        AND USER_ID = 'id01'
        </otherwise>
    </choose>
</select>

위에 작성한 if 코드는 사용자번호와 이름이 모두 있을 경우 결과 SQL은 where절이 두 번 생성되므로 문법 에러가 발생합니다.

 

| trim(where, set)

trim,where,set은 단독으로 사용되지 않고 <if>,<choose>와 같은 태그들을 내포하여 SQL들을 연결해 주고

앞 뒤에 필요한 구문들 (AND,OR,WHERE 등)을 추가하거나 생략하는 역할을 합니다.

 

trim element는 if element의 단점을 보완할 수 있는 기능을 제공합니다.

<select id="selectMember" parameterType="map", resultType="map">
    SELECT  USER_NO
            USER_ID
            NAME
            REG_DT
    FROM	USER
    <trim prefix="WHERE" prefixOverrides="AND|OR">
    	<if test "userNo != null">
    	AND USER_NO = #{userNo}
    	</if>
      	<if test "name != null">
      	AND NAME = #{name}
      	</if>     
    </trim>
</select>

trim 속성

- prefix : 실행 후 element의 내용이 있으면 가장 앞에 붙여줍니다

- prefixOverrides : 실행 후 element 내용 중 가장 앞에 해당하는 문자들이 있으면 자동으로 지워줍니다

- suffix : 실행 후 element의 내용이 있으면 가장 뒤에 붙여줍니다

- suffixOverrides : 실행 후 element 내용 중 가장 뒤에 해당하는 문자들이 있으면 자동으로 지워줍니다

 

trim element는 select, insert, update, delete에 사용가능합니다.

 

<update id="updateMember" parameterType="map", resultType="map">
    UPDATE  USER
    <trim prefix="SET" suffixOverrides=",">
    	<if test "userId != null">
    	USER_ID = #{userId},
    	</if>
      	<if test "name != null">
      	NAME = #{name}
      	</if>     
    </trim>
    WHERE   USER_NO = #{userNo}
</update>

 

where

<where>의 경우 태그 안족에서 SQL이 생성될 때는 where 구문이 붙고 그렇지 않는 경우에는 생성되지 않습니다.

select *
from tbl_board
<where>
	<if test="bno != null">
    	bno=#{bno}
    </if>
</where>

bno값이 존재하는 경우 : select * from tbl_board where bno=33

bno값이 존재하지 않는 경우 : select * from tbl_board

 

set

set element는 마지막으로 명시된 칼럼 표기에서 쉼표를 자동으로 제거한다. 그러나 이는 trim element로 대체 가능하기 때문에 trim을 사용하는 경우가 더 많습니다.

 

 

| foreach

List, 배열, Map 등을 이용해서 loop처리를 할 수 있습니다.

주로, IN조건에서 많이 사용합니다.

(경우에 따라 복잡한 WHERE 조건을 만들때에도 사용할 수 있습니다.)

SQL의 조회 조건에는 IN절로 조건을 추가하는 경우가 있습니다.

<select id="selectMember" parameterType="map", resultType="map">
    SELECT  USER_NO
            USER_ID
            NAME
    FROM    USER
    <trim prefix="WHERE" prefixOverrides="AND|OR">
    	<if test "userNo != null">
    	USER_NO IN
        <foreach collection="userNos" item="userNo" index="index" open="(" close=")" separator=",">
            #{userNo}
        </foreach>
    	<if>
    </trim>    
</select>

foreach 속성

- collection : 값 목록을 가진 객체를 설정한다. 

- item : 목록에서 각각의 값을 사용하는 속성이다.

index : 몇 번째 값인지 나타내는 인덱스 값이다. 시작값은 0이다.

open : 목록에서 값을 가져와서 설정할 때 가장 앞에 붙여 주는 문자를 지정하는 속성이다.

close : 목록에서 값을 가져와서 설정할 때 가장 뒤에 붙여 주는 문자를 지정하는 속성이다.

separator : 목록에서 값을 가져와서 설정할 때 값들 사이에 붙여 주는 문자를 지정하는 속성이다.

'Database > SQL 오라클' 카테고리의 다른 글

ORACLE -JOIN  (0) 2019.09.23
ORACLE -VIEW  (0) 2019.09.22
ORACLE -날짜관련 SYSDATE ,TO_DATE(),ADD_MONTHS(),MONTHS_BETWEEN()  (0) 2019.09.22
ORACLE -REVERSSE() 문자열 뒤집기  (0) 2019.09.22
ORACLE -INSTR()  (0) 2019.09.22