마이바티스에서는 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 |
이제 입력받은 날짜로 제한되어 결과 값이
나와야 하는데 그러면 파라미터를 넘겨받아야겠다.
그때에 이코드가 유용할듯
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 |
---|