myBatis와 iBatis에서 쿼리를 실행할때 PrepareStatement 방식으로 작동을 하게 되고 이때 쿼리로 전달값은 값을 각각 아래처럼 적용한다.
1 2 3 4 5 6 7 8 9 | <!-- 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이 전달되었을 경우 오라클에서는
uncategorized SQLException for SQL []; SQL state [99999]; error code [17004]; 부적합한 열 유형: 1111; nested exception is java.sql.SQLException: 부적합한 열 유형: 1111
이런 에러를 발생시키게 된다. Spring을 사용했을 경우는 이런에러를 발생시킨다.
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
그렇다고 항상 쿼리에서 null을 체크하는 방식을 사용하는것은 너무나도 귀찮은 일!! 그래서 if(myBatis)문 혹은 isNotEmpty(ibatis)를 사용하지 않는 방법이 있다. (자세히 보면 Spring Framework에서 발생시키는 에러에 답이있다.)
1 2 3 4 5 6 7 8 9 | <!-- 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
쿼리마다 적당이 jdbcType을 지정해서 사용하자.
출처: http://krespo.net/163 [KRESPO.NET]
'프로그래밍 > Spring & MyBatis' 카테고리의 다른 글
HandlerInterceptor 핸들러 인터셉터 (0) | 2018.02.22 |
---|---|
[Mybatis] 동적 쿼리문 작성시 자바메소드 호출 (0) | 2018.02.18 |
Transaction (0) | 2018.02.15 |
Spring Framework: annotation 정리 #1 (0) | 2018.02.15 |
@Autowired, @Resource, @Inject의 차이 (0) | 2018.02.15 |