사실 요번 편은 foreach문이 주인공이 아니다.

where절에 foreach문을 쓰고 싶은데 넘어온 파라미터가 배열이 아닐 때 배열형으로 만들어 주는 함수를 구현해본다.

 

[html]

<form name="frm" method="post">

<input type="checkbox" name="p_codes" value="01">신축

<input type="checkbox" name="p_codes" value="02">보수

<input type="checkbox" name="p_codes" value="03">증축

</form>

이 세 개의 체크박스를 모두 체크하고 submit을 했다고 치자.

 

code값이 01이거나 02이거나 03인것을 갖고 오는 쿼리문을 작성한다고 할 때 웬지 foreach문이 쓰고 싶다면 

아래함수를 만들어 배열로 구현해준다.

[Utils.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
public static  List <String> makeForeach (String s, String gb){
    List<String> list =   new ArrayList<String>();
    String[] aCode = s.split(gb);
 
    if (s == null || "".equals(s)) {
        return null;
    }
    for(int i=0; i< aCode.length; i++){
        list.add(aCode[i].toString());
    }
 
    return list;
}
cs

 

이제 파라미터를 받아서 배열로 변경해보자. logger로 찍어보면 배열로 찍힐 것이다.

1
List<String> list p_codes = Utils.makeForeach(Utils.nullToStr(parms.get("p_codes")), ","); //여기서 콤마는 구분자임. 다른 구분자로도 사용가능
cs

 

 

그리고 마무리로 foreach를 사용한 쿼리문

[query.xml]

1
2
3
4
5
6
<if test='p_codes !=null'> 
AND CODE IN
<foreach collection="p_codes" item="code" index="index" separator="," open="(" close=")">
        #{code}
</foreach>
</if>
cs

javax.el.PropertyNotFoundException에러가 나는 이유는 스펠링이 틀리거나 공백이 있어서가 대부분이지만


그렇지 않을 경우도 있다. 눈씻고 찾아봐도 공백이나 틀린철자가 없다면 다음내용을 확인해보자.


DTO정의 시 GuestTelNo라는 필드가 있다고 할 때 이렇게 가져오면 에러가 난다.


<input name="GuestTelNo"     id="GuestTelNo"       type="hidden" value="<c:out value='${vo.GuestTelNo}'/>" />


이 때 첫번째 문자를 소문자로 해주면 에러가 나지않는다. 즉 ${vo.GuestTelNo}를 ${vo.guestTelNo}로 바꿔 주어야 한다는 것!

DB : 오라클

프레임워크 : 전자정부 프레임워크 (java+spring+mybatis 등등)


보통은  select문을 써서 원하는 값을 가져오곤하는데 다른사람이 작성한 프로시져로 값을 받아와야하는 상황이 생겼다. 우선 sqlquery맵부터 작성해보자


sqlmap.xml


inParam01, inParam02 두 값을 던져서 outParam01, outParam02, outParam03라는 값을 받고 싶어하는 단순한 프로시져이다.

그럼 Controller를 작성해보자.  (Service와 DAO는 생략함)


testController.java


여기까지 하고 실행했을 때 NullpointException이 난다.

왜일까?.....왜일까....왜일까...
분명 result로 받았는데 왜 resultVo는 null일까...

그것은 바로 return이 resultVo로 오는게 아니라 parameter로 넘겼던 vo에 담기는 것이기 때문이었다. (왜 그런지는 다음에...)


자 이제 제대로된 소스를 작성해보자


sqlmap.xml

testController.java


sqlmap.xml에 있던 resultType을 삭제했다. 필요없으니까.

testController에서는 resultVo로 받는 것이 아니라 그냥 vo객체를 출력한다. testService.getValues(vo);를 호출함으로해서 vo에 값이 이미 담겼으니까.



VO에 useYN이라는 변수가 있다. 물론 String형으로 선언된.

이 변수에 'Y'라는 값을 받아와서 query xml에서 조건문으로 비교를 했는데 NumberformatException이 난다면?

당황하지말고...다음과 같이 해본다.





자, 금방 해결되었다.


이는  myBatis 문제는 아니고 OGNL(Object Graph Navigation Language) 의 문제.

OGNL 인터프리터에서는 위 구문의 ‘Y’를 char 형으로 인식하고, ‘YY’나 “Y”는 String으로 인식한다. java의 char형은 실제로 문자의 코드값을 저장하기 때문이라고 한다.

해결책으로는 다음과 같은 방법이 있다.

1. <if test=’stringValue == “Y”‘> – 쌍따옴표와 홑따옴표의 위치를 변경 (이건 헷갈릴거같고)
2. <if test=”stringValue == &quot;Y&quot;”> – 쌍따옴표를 HTML 코드로 변경(이건..음...)
3. <if test=”stringValue == ‘Y’.toString()”> – toString() 함수를 사용해 String 형으로 변환(당첨)

(출처 : http://t-ara72.blogspot.kr/2013/10/mybatis-numberformatexception.html)





mybatis에서 조건문 쓰는 것은 간단하다.

if나 when을 써주면 된다.


if문


when문 


test에 조건내용을 써주면 되는데 연산문은 일반적이다.


==, eq, !=, or, and 뭐 이런식으로 써주면 된다.


그렇다면 반복문은 어떻게 할 것인가?


예를들어 query의 where절에 in을 쓰고 싶다.


회원아이디들을 여러개 조회해와서 그 아이디가 있는 데이터만 가져오고 싶은 것이다.


요런 쿼리가 있다고 치자. 물론 서브쿼리로 간단히 할수 있다


select * from tblEventJoiner where event_no=#{event_no} and userid in (select userid from tblMember where smsyn = 'Y')


그런데 서브쿼리를 썼더니 시간이 너무 많이 걸린다. (물론 저런 간단한 쿼리에서는 걸리지않는다. 조인이 네다섯개 이상 걸린 경우)


프로시져를 짜도 되지만...이게 귀찮다면 다음과 같이 해보자.


1. 우선 SMS수신동의자 회원을 가져온다. (query.xml)


2. DAO부분에서 이 리스트를 받아 다시 query를 조회한다. (eventDAO.java)


3. 다시 query.xml로 돌아가서 받아온 회원아이디 리스트로 where절에 in을 넣어보자




- The END -

+ Recent posts