jquery ajax 로 spring 과 통신하여 데이터를 전송하고 mybatis annotation 으로 Oracle DB의 데이터를 받을때 

List<Map<String, Object>> 으로 받았다.


그런데 

HTTP Status 500 - Could not write content: Direct self-reference leading to cycle (through reference chain: java.util.ArrayList[0]->java.util.HashMap["RPL_CONTENT"]->oracle.sql.CLOB["dbaccess"]->oracle.jdbc.driver.T4CConnection["wrapper"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle (through reference chain: java.util.ArrayList[0]->java.util.HashMap["RPL_CONTENT"]->oracle.sql.CLOB["dbaccess"]->oracle.jdbc.driver.T4CConnection["wrapper"])


DB의 RPL_CONTENT 컬럼의 타입이 CLOB 라서 제대로 받아지지 않았다. 

구글링을 해보니 

1. DB에서 컬럼의 타입을 VARCHAR2로 바꿔서 받는 방법

http://dev4u.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-CLOB-VARCHAR%EB%A1%9C-%EB%B3%80%ED%99%98


2. JAVA에서 CLOB을 String 으로 변환하는 방법

http://thebad.tistory.com/entry/HashMap-%EC%9D%84-%ED%86%B5%ED%95%98%EC%97%AC-Clob-%EB%A5%BC-%EB%B0%9B%EC%9D%84-%EA%B2%BD%EC%9A%B0-String-%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98


이 나오는데 내 상황은 Mybatis Annotation 으로 DB에 Query문을 날리는거라 1번 밖에 답이 없었으나 DB 데이터를 건들기는 싫었다. 그래서 Mybatis 공식 문서를 찾아보니 Results 와 Result 를 사용해서 XML 형식처럼 해당 결과값 컬럼의JdbcType 과 JavaType 을 선언해줄수 있는걸 발견했다.

그래서


@Results(id = "결과값ID", value = {

...

@Result(property = "Map안에 저장될 키값", column = "해당 컬럼명", jdbcType = JdbcType.CLOB, javaType = String.class),

...

})


으로 하니 오류없이 제대로 Map안에 저장해서 사용할수 있었다.


결국 키포인트는 Mybatis Annotation 방식에서 Results 와 Result 를 사용하는 방법.

2. 


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

Mybatis 에서 if문 사용하기  (0) 2018.09.14
SelectKey를 Select구문의 if안에서 쓸수 있을까?  (0) 2018.09.14

Spring에서 mybatis를 사용하여 query문을 날릴때, if문을 사용할 때가 있다.

xml 형식이든 annotation(interface에서 바로 작성하는것) 이든 방식은 거의 비슷한다.


단, 차이는 어떻게 parameter 나 result를 받고 전달하느냐의 차이.


Interface 형식


@Options(useGeneratedKeys=false)

@Update({"<script> ",

"UPDATE SPORTS_MEMBER SET ",

"<if test=\"vo.mem_pw eq null\">",

" MEM_NAME = #{vo.mem_name}, ",

" MEM_AGE = #{vo.mem_age}, ",

" MEM_EMAIL = #{vo.mem_email}, ",

" MEM_IMG = #{vo.mem_img}, ",

" MEM_DETAIL = #{vo.mem_detail} ",

"WHERE MEM_ID = #{vo.mem_id} AND MEM_CHECK = 1 ",

"</if>",

"<if test=\"vo.mem_pw neq null\">",

" MEM_PW = #{vo.mem_pw}, ",

" MEM_NAME = #{vo.mem_name}, ",

" MEM_AGE = #{vo.mem_age}, ",

" MEM_EMAIL = #{vo.mem_email}, ",

" MEM_IMG = #{vo.mem_img}, ",

" MEM_DETAIL = #{vo.mem_detail} ",

"WHERE MEM_ID = #{vo.mem_id} AND MEM_CHECK = 1 ",

"</if>",

"</script>"})

public int ajaxUpdateMemOne(@Param("vo") Sports_Member vo);


if의 비교문에 vo의 값이 들어갈 경우 paramname.vo의변수name 로 사용한다. 그리고 annotation 방식에서는 "" 안에 쿼리문을 넣으므로 "를 사용할때는 \(역슬래시, 보통 백스페이스 왼쪽에 있는 키)를 그앞에 추가해서 IDE가 제대로 인식하게 해준다.


xml 형식은 그냥 간단한게


<update id="ajaxUpdateMemOne" parameterType="Sports_Member">

<if text="mem_pw eq null">

</if> 

</update>



형 비교는 여기 참조해보는게 좋을것 같다


http://madnix.tistory.com/entry/%EB%A7%88%EC%9D%B4%EB%B0%94%ED%8B%B0%EC%8A%A4%EB%8A%94-%EB%8F%99%EC%A0%81-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%83%9D%EC%84%B1%EC%97%90-%EC%82%AC%EC%9A%A9%EB%90%98%EB%8A%94-if-%EA%B5%AC%EC%84%B1-%EC%9A%94%EC%86%8C%EB%A5%BC-%EC%A0%9C%EA%B3%B5


간략히 요약하면


기본 자료형 비교, 참조 자료형 비교, 문자열 비교가 있고

(eq, ==, neq, != 를 사용)

자료형 비교는 프로버티 속성 값과 기준값을 비교하고


참조 자료형 비교는 null 인지 아닌지를 비교


문자열 비교는 

프로퍼티 속성 값과 한자리 문자열을 비교, 한자리 이상 문자열을 비교하는 경우가 있다.

비교 형식은

프로퍼티속성값 == "a"

   eq

   !=

   neq


인데 한자리 이상도 똑같이 하면 된다.





조건은, selectkey로 반환되는 값이 Select 할 테이블의 컬럼에 존재하지 않고 if문의 조건으로 사용한다고 가정하자.


먼저 결론은, 안된다.


Mybatis 공식 Document를 찾아보니 selectKey는 insert update 구문 에서만 사용이 되어진다.

혹시나 해서 실제로 Select문에서 selectkey 사용을 시도해봤는데, selectkey를 읽지를 못한다.


사용하려고 했던 이유는 select 쿼리를 두번 날리기 싫었고,

selectKey에서 먼저 select 를 해서 나오는 값으로 비교문에 사용하여 select를 분기적으로 하려고 했다.

결국 안되므로 Select를 두번하는 수밖에....


@Options(useGeneratedKeys=true, keyProperty="cnt")

@Select({"<script>",

"<if test=\"#{cnt} == 0\">",

"SELECT ", 

"    MEM_ID, MEM_AGE, MEM_DETAIL, MEM_IMG, MEM_EMAIL, MEM_NAME ", 

"FROM SPORTS_MEMBER ",

"WHERE MEM_ID = #{id}",

"</if>",

"<if test=\"#{cnt} > 0\">",

"SELECT ",

"    sm.MEM_ID, sm.MEM_AGE, sm.MEM_DETAIL, sm.MEM_IMG, sm.MEM_EMAIL, sm.MEM_NAME,", 

"    NVL(COUNT(grpno.GRP_NO), 0) mcnt ", 

"FROM (", 

"    SELECT DISTINCT g.GRP_NO, GRP_LEADER FROM SPORTS_GRP g ", 

"    INNER JOIN SPORTS_GRP_MEM m ON g.GRP_NO = m.GRP_NO ", 

"    WHERE GRP_LEADER = #{id} OR GRP_MEM = #{id}", 

"    ) grpno ", 

"INNER JOIN SPORTS_MEMBER sm ON grpno.GRP_LEADER = sm.MEM_ID ", 

"WHERE MEM_ID = #{id}", 

"GROUP BY sm.MEM_ID, sm.MEM_AGE, sm.MEM_DETAIL, sm.MEM_IMG, sm.MEM_EMAIL, sm.MEM_NAME ",

"</if>",

"</script>"})

@SelectKey(before = true, keyProperty = "cnt",

resultType = Integer.class, 

statement = {

"SELECT DISTINCT NVL(COUNT(g.GRP_NO), 0) cnt FROM SPORTS_GRP g", 

"    INNER JOIN SPORTS_GRP_MEM m ON g.GRP_NO = m.GRP_NO",

"    WHERE GRP_LEADER = #{id} OR GRP_MEM = #{id}" 

})

public Map<String, Object> ajaxSelectMemOne(@Param("id") String id);

+ Recent posts