MyBatis 操作ORACLE 中CLOB字段

MyBatis 操作ORACLE 中CLOB字段相关功能:
1.插入
2.查询

一、背景

近期项目中遇到了用mybatis中ORACLE 数据库CLOB类型的相关操作,记录一下,方便以后查阅。

二、实例代码

varchar2类型的字符长度是4000,注意:oracle对汉字的存储占3个字符
表结构:

create table T_RECRUITMENT_ORDER
(
  id                NUMBER(8) not null,
  user_id           NUMBER(8),
  club_id           NUMBER(8),
  recruitment_title VARCHAR2(255),
  recruitment_img   VARCHAR2(200),
  createtime        DATE default sysdate,
  club_introduce    CLOB
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Add comments to the columns 
comment on column T_RECRUITMENT_ORDER.user_id
  is '创建者用户id';
comment on column T_RECRUITMENT_ORDER.club_id
  is '俱乐部id';
comment on column T_RECRUITMENT_ORDER.recruitment_title
  is '招募令标题';
comment on column T_RECRUITMENT_ORDER.recruitment_img
  is '招募令海报';
comment on column T_RECRUITMENT_ORDER.createtime
  is '创建时间';
comment on column T_RECRUITMENT_ORDER.club_introduce
  is '俱乐部介绍';

在这里插入图片描述

功能1:MyBatis +ORACLE 插入CLOB

mybatis映射文件中编写如下 insert语句(CLUB_INTRODUCE 定义 jdbcType类型为CLOB),实现类正常调用即可:

 <!-- 创建集结令 -->
     <insert id="addRecruitmentOrder"  parameterType="java.util.HashMap" >
        <selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="ID">
     		 SELECT SEQ_T_RECRUITMENT_ORDER.nextval AS ID FROM dual
        </selectKey>
        insert into t_recruitment_order(
            id,
            user_id,
            club_id,
            recruitment_title,
            recruitment_img,
            club_introduce,
            createtime
        )values(
        	#{ID,jdbcType=DECIMAL},
            #{MY_USERID,jdbcType=DECIMAL},
            #{CLUB_ID,jdbcType=DECIMAL},
            #{RECRUITMENT_TITLE,jdbcType=VARCHAR},
            #{RECRUITMENT_IMG,jdbcType=VARCHAR},
            #{CLUB_INTRODUCE,jdbcType=CLOB},
            sysdate
        )
     </insert>

在这里插入图片描述
上面的方法只适合 4000字符以内的数据插入。 超过4000字符,则会报如下错:
在这里插入图片描述
解决方法:使用变量,通过PL/SQL将数据赋予CLOB变量,通过引用变量将数据插入:

<!-- 创建集结令 -->
     <insert id="addRecruitmentOrder"  parameterType="java.util.HashMap" >
        <selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="ID">
     		 SELECT SEQ_T_RECRUITMENT_ORDER.nextval AS ID FROM dual
        </selectKey>
         DECLARE
            club_introduce CLOB :=#{CLUB_INTRODUCE,jdbcType=CLOB};
		 BEGIN
	        insert into t_recruitment_order(
	            id,
	            user_id,
	            club_id,
	            recruitment_title,
	            recruitment_img,
	            club_introduce,
	            createtime
	        )values(
	        	#{ID,jdbcType=DECIMAL},
	            #{MY_USERID,jdbcType=DECIMAL},
	            #{CLUB_ID,jdbcType=DECIMAL},
	            #{RECRUITMENT_TITLE,jdbcType=VARCHAR},
	            #{RECRUITMENT_IMG,jdbcType=VARCHAR},
	            club_introduce,
	            sysdate
	        );
        END;
     </insert>

功能2:MyBatis +ORACLE 查询CLOB

方案一:ORACLE 函数(有长度限制)

方式1:dbms_lob.substr(CLOB字段)

-- Clob字段查看方法1: 此方法查询出的数据长度不可超过4000个字符
select t.id,dbms_lob.substr(t.club_introduce) as text from T_RECRUITMENT_ORDER t

注意:此方法查询出的数据长度不可超过4000个字符
执行结果:
在这里插入图片描述

方式2:to_char(CLOB字段)

注意:此方法查询出的数据长度不可超过4000个字符

-- Clob字段查看方法2: 此方法查询出的数据长度不可超过4000个字符
select t.id,to_char(t.club_introduce) as text from T_RECRUITMENT_ORDER t

执行结果:

在这里插入图片描述
这两个方法都有数据长度的限制。

方案二:直接读取, 将Clob转成String(最终方案)

最终解决方案如下:

直接读取clob: select column from …
Clob columnClob = (Clob) map.get(“column”);
将Clob转成String

(1)sql语句直接读取
<!--根据集结令id获取集结令详情信息-->
 <select id="getRecruitmentOrderInfo" parameterType="java.util.HashMap" resultType="java.util.HashMap">
        select * 
        from t_recruitment_order
        where ID =#{recruitment_id,jdbcType=DECIMAL}
 </select>
(2)编写工具类:将Clob转成String
package com.njpp.wxxcx.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.Clob;
import java.sql.SQLException;

public class ClobToString {
	
	/**
	 *  Clob类型 转String
	 * @param clob
	 * @return
	 * @throws SQLException
	 * @throws IOException
	 */
    public static String ClobToString(Clob clob) throws SQLException, IOException {
        String ret = "";
        Reader read= clob.getCharacterStream();
        BufferedReader br = new BufferedReader(read);
        String s = br.readLine();
        StringBuffer sb = new StringBuffer();
        while (s != null) {
            sb.append(s);
            s = br.readLine();
        }
        ret = sb.toString();
        if(br != null){
            br.close();
        }
        if(read != null){
            read.close();
        }
        return ret;
    }
}

(3)在相应的ClubServiceImpl中调用工具类ClobToString中的方法
	/**
	 * 根据集结令id获取集结令详情信息
	 */
	@Override
	public Map<String, Object> getRecruitmentOrderInfo(HttpServletRequest request) throws Exception {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Object> paramMap = GetParamToMap.getParameterMapCode(request);
		//根据集结令id获取集结令详情信息
		Map<String, Object> recruitmentOrder = clubMapper.getRecruitmentOrderInfo(paramMap);
        //处理 CLUB_INTRODUCE(clob类型)
        Clob columnClob = (Clob) recruitmentOrder.get("CLUB_INTRODUCE");
        String CLUB_INTRODUCE = ClobToString.ClobToString(columnClob);//Clob类型 转String
        recruitmentOrder.put("CLUB_INTRODUCE", CLUB_INTRODUCE);
        
		result.put("recruitmentOrder", recruitmentOrder);// 集结令详情
		
		result.put(ErrCode.STATE, ErrCode.SUCCESS);
		return result;
	}

参考资料:
MyBatis 读取CLOB格式字段 返回Map相关问题

oracle插入CLOB类型超过4000个字符报ORA-01704错的解决方法及其它相关场景解决方案

Mybatis向oracle数据库插入clob字段,长度大于4000时报错

CLOB 类型是达梦数据库特有的数据类型,与其他数据库的数据类型不同。因此,在使用 MyBatis 查询达梦数据库CLOB 类型字段时,需要进行特殊处理。 下面是一个示例代码,演示如何使用 MyBatis 查询达梦数据库CLOB 类型字段: 1. 在 MyBatis 配置文件添加类型处理器: ``` <typeHandlers> <typeHandler jdbcType="CLOB" javaType="java.lang.String" handler="com.example.ClobTypeHandler" /> </typeHandlers> ``` 其,`jdbcType` 表示数据库的数据类型,`javaType` 表示Java的数据类型,`handler` 表示自定义的类型处理器。 2. 自定义类型处理器: ``` public class ClobTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { StringReader reader = new StringReader(parameter); ps.setCharacterStream(i, reader, parameter.length()); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { Reader reader = rs.getCharacterStream(columnName); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Reader reader = rs.getCharacterStream(columnIndex); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Reader reader = cs.getCharacterStream(columnIndex); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } } ``` 该类型处理器将 CLOB 类型转换为 Java 的 String 类型,并在查询结果返回。 3. 在 MyBatis 映射文件使用类型处理器: ``` <resultMap id="userResultMap" type="User"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="description" property="description" jdbcType="CLOB" javaType="java.lang.String" typeHandler="com.example.ClobTypeHandler" /> </resultMap> ``` 其,`jdbcType` 表示数据库的数据类型,`javaType` 表示Java的数据类型,`typeHandler` 表示自定义的类型处理器。 通过以上步骤,你可以在 MyBatis 查询达梦数据库CLOB 类型字段,并将其转换为 Java 的 String 类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值