Framework/myBatis
[Mybatis] 쿼리 파라미터 null 처리방법
louis.dev
2013. 11. 14. 14:08
myBatis와 iBatis에서 쿼리를 실행할때 PrepareStatement 방식으로 작동을 하게 되고 이때 쿼리로 전달값은 값을 각각 아래처럼 적용한다.
<!-- ibatis 방식--> <insert id="insertQuery" parameterType="java.util.Map"> INSERT INTO table (id , name, title) VALUES (#id#, #name#, #title#) </select> <!-- mybatis 방식 --> <insert id="insertQuery"> INSERT INTO table (id , name, title) VALUES (#{id}, #{name}, #{title}) </insert>그런데 이때 insert 하려는 값 중에 null이 전달되었을 경우 오라클에서는
이런 에러를 발생시키게 된다. Spring을 사용했을 경우는 이런에러를 발생시킨다.uncategorized SQLException for SQL []; SQL state [99999]; error code [17004]; 부적합한 열 유형: 1111; nested exception is java.sql.SQLException: 부적합한 열 유형: 1111
그렇다고 항상 쿼리에서 null을 체크하는 방식을 사용하는것은 너무나도 귀찮은 일!! 그래서 if(myBatis)문 혹은 isNotEmpty(ibatis)를 사용하지 않는 방법이 있다. (자세히 보면 Spring Framework에서 발생시키는 에러에 답이있다.)Caused by: org.springframework.jdbc.UncategorizedSQLException: Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters. Cause: java.sql.SQLException : 부적합한 열 유형: 1111
<!-- ibatis 방식--> <insert id="insertQuery" parameterType="java.util.Map"> INSERT INTO table (id , name, title) VALUES (#id:VARCHAR#, #name:VARCHAR#, #title:VARCHAR#) </insert> <!-- mybatis 방식 --> <insert id="insertQuery"> INSERT INTO table (id , name, title) VALUES (#{id, jdbcType=VARCHAR}, #{name, jdbcType=VARCHAR}, #{title, jdbcType=VARCHAR}) </insert>위와 같이 전달되는 파라미터 값의 jdbcType이 무엇인지를 정해 주면 쿼리는 자연스럽게 null로 변경되어 insert query가 수행된다.(물론 해당 column이 NULL값을 저장가능한 column 이어야 한다) 지원하는 jdbcType은 아래와 같다.
- BIT
- FLOAT
- CHAR
- TIMESTAMP
- OTHER
- UNDEFINED
- TINYINT
- REAL
- VARCHAR
- BINARY
- BLOB
- NVARCHAR
- SMALLINT
- DOUBLE
- LONGVARCHAR
- VARBINARY
- CLOB
- NCHAR
- INTEGER
- NUMERIC
- DATE
- LONGVARBINARY
- BOOLEAN
- NCLOB
- BIGINT
- DECIMAL
- TIME
- NULL
- CURSOR