<select id="selectClob" parameterType="java.util.HashMap" resultType="egovMap">
SELECT
ID,
TO_CHAR(CLOB_COLUMN)
FROM TABLE
</select>
문제 발단 : clob형 데이터들은 varchar2 형 데이터 처럼 단순히 select 하여 값을 갖고오면 바로 우리가 볼 수 있는 string형으로 보이지 않는다. 그래서 to_char를 사용해서 위와 같이 쿼리문을 작성했으나 아래와 같은 에러가 발생했다.
; uncategorized SQLException for SQL []; SQL state [99999]; error code [22835]; ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4944, maximum: 4000) ; nested exception is java.sql.SQLException: ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4944, maximum: 4000)
; uncategorized SQLException for SQL []; SQL state [99999]; error code [22835]; ORA-22835: 버퍼가 너무 작아 CLOB를 CHAR 또는 BLOB에서 RAW로 변환할 수 없습니다(실제: 4944, 최대: 4000). ; nested exception is java.sql.SQLException: ORA-22835: 버퍼가 너무 작아 CLOB를 CHAR 또는 BLOB에서 RAW로 변환할 수 없습니다(실제: 4944, 최대: 4000).
문제 이유 : 쿼리 상에서 CLOB 타입의 컬럼을 TO_CHAR 를 통해 VARCHAR2 형태로 변환시 버퍼 사이즈(4000Byte)가 부족해 발생한 문제. (VARCHAR2 최대 사이즈 4000Byte)
문제 해결방법
1. CLOB 데이터를 VARCHAR2로 변환해서 가지고 올경우, Oracle의 DBMS_LOB.SUBSTR 함수를 사용하여 필요한 만큼의 데이터를 가져올 수 있으므로 최대사이즈까지만 잘라서 사용하기
SELECT DBMS_LOB.SUBSTR(CLOB_COLUMN, 4000, 1) AS CLOB_COLUMN FROM TABLE;
2. 마이바티스에서 CLOB 필드를 직접 매핑하여 전체 내용을 가지고 오기.
이 경우, CLOB 필드를 별도의 변수로 매핑하고, CLOB를 처리할 수 있는 Java 타입으로 설정해야 한다.
예를 들어, Mapper XML에서 resultType을 적절하게 설정하고, Java 객체에서 CLOB를 String으로 처리합니다.
이렇게 하면 마이바티스가 CLOB 필드를 Java의 String으로 자동 변환하여 가져올 수 있다.
<resultMap type="HashMap" id="리저트맵 이름">
<result property="컬럼명" column="컬럼명" jdbcType="CLOB" javaType="java.lang.String" />
</resultMap>
<select id="셀렉트쿼리문 이름" parameterType="HashMap" resultType="HashMap" resultMap="리저트맵 이름">
셀렉트 문 쿼리 내용
</select>
두번째 방법을 사용한 예
<resultMap id="clobMap" type="HashMap">
<result property="id" column="ID" />
<result property="clobColumn" column="CLOB_COLUMN" javaType="java.lang.String" jdbcType="CLOB" />
</resultMap>
<select id="selectClob" parameterType="java.util.HashMap" resultMap="clobMap">
SELECT
ID,
CLOB_COLUMN
FROM TABLE
</select>
이런식으로 myBatis에서 resultType을 resultMap으로 받아서 설정을 변경하여 처리해 주면
clob 형 데이터 (nclob 등) 를 string형으로 처리하여
자바에서 별도의 처리 없이 view단에서 뿌려주기만 하면 string형으로 잘 보인다.
주의점은 resultMap 태그는 select 태그에서는 사용가능한데, sql태그에서는 해당 resultMap을 불러오지 못하기 때문에 select 태그 위에서 선언하여 select 태그에서 해당 resultMap의 이름을 가져와 써줘야 한다.
마이바티스 jdbcType
SQL Server 형식 | JDBC 형식(jdbcType) | Java(JavaType) |
bigint | BIGINT | long |
binary | BINARY | byte[] |
bit | BIT | boolean |
char | CHAR | String |
date | DATE | java.sql.Date |
datetime | TIMESTAMP | java.sql.Timestamp |
datetime2 | TIMESTAMP | java.sql.Timestamp |
datetimeoffset(2) | microsoft.sql.Types.DATETIMEOFFSET | microsoft.sql.DateTimeOffset |
decimal | DECIMAL | java.math.BigDecimal |
float | DOUBLE | double |
image | LONGVARBINARY | byte[] |
int | INTEGER | int |
money | DECIMAL | java.math.BigDecimal |
nchar | CHAR | String |
ntext | LONGVARCHAR | String |
numeric | NUMERIC | java.math.BigDecimal |
nvarchar | VARCHAR | String |
nvarchar(max) | VARCHAR | String |
real | REAL | float |
smalldatetime | TIMESTAMP | java.sql.Timestamp |
smallint | SMALLINT | short |
smallmoney | DECIMAL | java.math.BigDecimal |
text | LONGVARCHAR | String |
time | TIME(1) | java.sql.Time(1) |
timestamp | BINARY | byte[] |
tinyint | TINYINT | short |
udt | VARBINARY | byte[] |
uniqueidentifier | CHAR | String |
varbinary | VARBINARY | byte[] |
varbinary(max) | VARBINARY | byte[] |
varchar | VARCHAR | String |
varchar(max) | VARCHAR | String |
xml | LONGVARCHAR | String |
참고 : https://tomining.tistory.com/95
https://hiworldbye.tistory.com/26
https://lts0606.tistory.com/615
'STUDY > DB SQL' 카테고리의 다른 글
[MySQL][JAVA] 연동 시 Public key retrieval is not allowed 오류 (0) | 2024.10.11 |
---|---|
[MyBatis] <selectKey> 시퀀스 획득 (0) | 2024.10.11 |
[SQL] 오라클 삭제한 데이터 복구 (0) | 2024.07.30 |
[MyBatis] <trim> 사용법 (0) | 2024.04.29 |
[MyBatis] LIKE + % 문자열 검색 DBMS별 SQL문 (0) | 2024.04.24 |