반응형

마이바티스에서는 CDATA 구문을 많이 씁니다


이유는 쿼리문에 문자열 비교연산자나 부등호를 처리할 때가있습니다


그러면 < 와 같은 기호를 괄호인지 아니면 비교연산자 인지 확인이 되지않아요


이외에도 특수문자 사용하는데 제한이있습니다


그런이유에서 하나의 규칙같이 부등호가 없는 쿼리문에도 전부CDATA를 쓰는곳도 많습니다


CDATA는 태그안에서는 전부 문자열로 치환시켜버리기 때문입니다


하나의 예시를 보자면


1.CDATA 를 사용하지 않은쿼리


1
2
3
4
5
6
7
8
9
<select id="findAll" resultMap="MemberResultMap">
 
    select *
 
    from employees
 
    where salary > 100
 
</select>
cs



해당 쿼리는 에러가 납니다


부등호 '>' 가 닫힘 태그로 인식이 되어버리기 때문이죠


그래서 CDATA 태그를 사용해서 감싸준다면


2.CDATA 를 사용한 쿼리


1
2
3
4
5
6
7
8
9
<select id="findAll" resultMap="MemberResultMap">
    <![CDATA[
    select *
 
    from employees
 
    where salary > 100
    ]]>
</select>
cs


이런식으로사용이 가능합니다 하지만 중간에 조건문 태그를 감싸면 곤란합니다

태그가 인식을 못하기 때문입니다



3.조건 태그에서의 CDATA 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<select id="findAll" resultMap="MemberResultMap">
    <![CDATA[
    select *
 
    from employees
 
    where  1=1
    ]]>
    <choose>
        <when test='user_type != null and user_type =="1"'>
            <![CDATA[
                salary > 100
            ]]>
        </when>
 
        <otherwise>
            <![CDATA[
                salary < 100
            ]]>
        </otherwise>
    </choose>
</select>
cs



이런식으로 사용하시면 되겠습니다




검색해보면 

reg_date는 datetime형이고, 인덱스가 걸려있다고 가정한다.

1
2
3
4
5
6
7
SELECT *
FROM    Test
WHERE   date_format(reg_date, '%Y-%m-%d') BETWEEN '2013-01-01' AND '2013-01-31';
 
SELECT *
FROM    Test
WHERE   date(reg_date) BETWEEN '2013-01-01' AND '2013-01-31';
cs


이렇게 하라고 많이 써있는데,

좋은 글 발견

http://egloos.zum.com/tiger5net/v/5751776


1
2
3
4
SELECT *
from tb_user_logs
where log_time >= '2016-07-29'
and log_time < '2016-08-01'
cs


이렇게 짜면 검색속도가 엄청 빠르다고 한다.


분명 pgAdmin에서 쿼리 돌렸을 땐 잘 돌아갔는데?

왜 어? 이클립스에서 오류나지?


Mybatis는 XML에 정의하기 때문에 부등로를 그냥 쓰면 오류가 난다고,

태그에 존재하는 <tag> 꺽쇠랑 동일하여, 파싱에러가 난다고 한다.


<![CDATA[ ]]> 로 감싸주면 해결!


1
2
3
4
5
6
7
8
9
10
11
SELECT
    USER_ID,
    LOG_LEVEL,
    LOG_MSG,
    coalesce(to_char(LOG_TIME,'YYYY-MM-DD HH24:MI'),'') LOG_TIME
FROM JDN.TB_USER_LOGS
    <![CDATA[
        WHERE LOG_TIME >='2016-07-29' AND LOG_TIME < '2016-08-01'
    ]]>
ORDER BY LOG_TIME DESC
 
cs


http://tost.tistory.com/144


이제 입력받은 날짜로 제한되어 결과 값이

나와야 하는데 그러면 파라미터를 넘겨받아야겠다.


그때에 이코드가 유용할듯 


1
2
3
4
<![CDATA[
    attendance_date >=to_date(#{start_date}, 'YYYY-MM-DD' )
    and attendance_date < to_date(#{finish_date}, 'YYYY-MM-DD')
]]>
cs


참조: http://kmckmc.tistory.com/entry/MyBatis-%EC%82%AC%EC%9A%A9-%EA%B8%B0%EA%B0%84%EA%B2%80%EC%83%89




#@!@$%#$#@!!그런데!

왜 안나와???????????????

내문제다. 내가 잘 몰라서~~~~

나는 기본 초기값을 오늘날짜부터 오늘날짜까지 해서 하루치 리스트를 초기상태로 뿌리고 싶었는데.

저렇게 했을 때 '2016-07-29' 가 시작데이터고, '2016-07-29' 가 끝 데이터 일때 count 가 0으로 나와 리스트가 나오지 않는 문제가 발생했다.


DB에 찍히는 시간 값은 timestamp값이고, VO로 만들어 보내는 값은 String이고 

첨에 형이 다르다고 해서 형변환을 했다.


1
2
3
<![CDATA[
    WHERE CAST(LOG_TIME AS CHARACTER VARYING) >= #{fromDate} AND CAST(LOG_TIME AS CHARACTER VARYING)<= #{toDate}
]]>
cs


근데도 안되

왜????????

봤더니 , DB timestamp에서는 시간 분 초 그이후까지 나오는데, 강제적으로 char형으로 변환시켜놓은것이고

fromDate값으로 들어오는 '2016-07-29' 가  날짜만 가지고 비교를 하니까 기본적으로 000000으로 시간을 임의로 넣었기 때문에

값비교가 안되었던 것이다.(제기랄)


그리고 date format인 컬럼을 to_char(컬럼,'YYYY-MM-DD") 변환 후 변수와 비교할 경우 매 컬럼마다 to_char함수가 

실행되기에 컬럼건수가 많을 경우 performence에 영향을 미치게 된다.

차라리 다음과 같은 방법으로 처리하도록 하자.

1. 변수를 to_date함수를 통하여 날짜 형식으로 변환 후 비교한다.

2. Date가 아닌 VARCHAR형식의 컬럼을 추가하고 해당 컬럼에 인덱스를 추가한 다음 변수와 비교하도록 한다.


1
2
3
4
<![CDATA[
    WHERE CAST(LOG_TIME AS CHARACTER VARYING) >= (#{fromDate}||'00:00:00'
    AND CAST(LOG_TIME AS CHARACTER VARYING)<=    ( #{toDate}||'23:59:59')
]]>
cs



출처: http://daydreamer-92.tistory.com/33 [아는게1도없다]

반응형

'IT > Mybatis' 카테고리의 다른 글

mybatis , 멀티 파라메터 전달 ,anotation parameter injection  (0) 2018.02.21

+ Recent posts