文章目录

  • Mybatis操作Oracle中的Clob和Blob字段 [ 我测试用的Mybatis Plus ]
  • A、数据准备
  • A-1. Oracle中创建测试的表结构:Byte_Array_Test,手动插入几条数据
  • A-2 代码中用到的工具类FileUtil :将节数组byte[]写入到文件
  • B、方式一实现 [推荐,简单方便,易读; String<-->Clob , byte[]<-->Blob]:
  • B-1. 创建实体Entity:ByteArrayTest
  • B-2. Mapper或者Dao:ByteArrayTestDao
  • B-3. Junit测试代码:Clob和Blob的读取+写入,测试代码如下
  • C、方式二实现:
  • C-1. Mapper或Dao中添加接口方法:任意的Mapper或Dao中添加如下测试方法
  • C-2. Mapper.Xml或Dao.Xml书写Sql
  • C-3. Junit测试代码


Mybatis操作Oracle中的Clob和Blob字段 [ 我测试用的Mybatis Plus ]

说明:
	CLOB和BLOB的区别,这两个被统称为LOB,即Large Object(大对象类型)
	最本质的区别:
		CLOB的C,可以理解为Char,保存的是字符大对象
		BLOB的B,即Binary,保存的是二进制大对象
	CLOB应该转换成String
	BLOB应该转换成byte[]

A、数据准备

A-1. Oracle中创建测试的表结构:Byte_Array_Test,手动插入几条数据

create table BYTE_ARRAY_TEST
(
  ID     VARCHAR2(32) not null,
  CLOB   CLOB,
  BLOB   BLOB,
  REMARK VARCHAR2(1000)
);
alter table BYTE_ARRAY_TEST add 
      constraint PK_BYTE_ARRAY_TEST primary key (ID);

A-2 代码中用到的工具类FileUtil :将节数组byte[]写入到文件

public class FileUtil {
	 /**
	   * 方法功能:将字节数组写入到新建文件中。
	   * @param String fname
	   * @param byte[] msg
	   * @return boolean
	   * */
	  public static boolean save2File(String fname, byte[] msg){
	    OutputStream fos = null;
	    try{
	      File file = new File(fname);
	      File parent = file.getParentFile();
	      boolean bool;
	      if ((!parent.exists()) && 
	        (!parent.mkdirs())) {
	        return false;
	      }
	      fos = new FileOutputStream(file);
	      fos.write(msg);
	      fos.flush();
	      return true;
	    }catch (FileNotFoundException e){
	      return false;
	    }catch (IOException e){
	      File parent;
	      return false;
	    }
	    finally{
	      if (fos != null) {
	        try{
	          fos.close();
	        }catch (IOException e) {}
	      }
	    }
	  }
	
	// 写入文件功能测试
	public static void main(String[] args)  {
		String msgStr = "我是java爱好者,测试数据";
		byte[] bytes = msgStr.getBytes();
		
		String filename = "D:\\test\\test.txt";//注意修改为自己的文件名
		boolean flag = FileUtil.save2File(filename, bytes);
		System.out.println("flag = "+ flag );
    }
}

B、方式一实现 [推荐,简单方便,易读; String<–>Clob , byte[]<–>Blob]:

B-1. 创建实体Entity:ByteArrayTest

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * (ByteArrayTest)表实体类
 *
 * @author Zhaof
 * @since 2023-04-11 14:39:33
 */
@SuppressWarnings("serial")
@Data
@NoArgsConstructor
@AllArgsConstructor
//@TableName("BYTE_ARRAY_TEST")  //指定数据库表名   使用了泛型Model<>,这里可以不需要
public class ByteArrayTest extends Model<ByteArrayTest> {
    @TableId  //  指定主键
    private String id;
    private String clob;
    private byte[] blob;
    private String remark;
}

B-2. Mapper或者Dao:ByteArrayTestDao

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mediinfo.entity.ByteArrayTest;
/**
 * (ByteArrayTest)表数据库访问层
 *
 * @author Zhaof
 * @since 2023-04-11 14:39:32
 */
public interface ByteArrayTestDao extends BaseMapper<ByteArrayTest> {

}

B-3. Junit测试代码:Clob和Blob的读取+写入,测试代码如下

import com.mediinfo.dao.ByteArrayTestDao;
import com.mediinfo.dao.FileUtil;
import com.mediinfo.entity.ByteArrayTest;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@SpringBootTest
class ClobAndBlobTest {

	// SpringBoot下,自动注入Dao
	@Resource
	private ByteArrayTestDao byteArrayTestDao;

	@Test
	void Test() throws Exception {
		// 直接通过selectById获取实体
		ByteArrayTest byteArrayTest = byteArrayTestDao.selectById("123");

		// 1. 读取Db的Clob和Blob:
		// 		得到Clob的长字符串值
		String clobVal = byteArrayTest.getClob();
		// 		得到Blob的字节数组值
		byte[] bytes = byteArrayTest.getBlob();
		System.out.println("clobVal = " + clobVal + ",blob的lenggh=" + bytes.length);

		// 将Blob的字节数组byte[]写入文件
		boolean b = FileUtil.save2File("D:\\test\\22.png", bytes);
		System.out.println(b);

		// 2. 写入Db:
		ByteArrayTest byteArrayTest2 = new ByteArrayTest();
		byteArrayTest2.setId("111");
		// 		直接将上方读取到的数据,写入新插入的行,观察
		byteArrayTest2.setClob(byteArrayTest.getClob() + "||||666666666");
		byteArrayTest2.setBlob(bytes);
		int insert = byteArrayTestDao.insert(byteArrayTest2);
		System.out.println(insert);
	}
}

C、方式二实现:

C-1. Mapper或Dao中添加接口方法:任意的Mapper或Dao中添加如下测试方法

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mediinfo.entity.UserOracle;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Mapper
@Repository
public interface UserOracleDao extends BaseMapper<UserOracle> {

	// 这个测试方法,可以放在任意的Dao中,通过Mapper.xml或Dao.Xml操作Sql
    @MapKey("id")
    public List<Map<String,Object>> findVal(String id);
}

C-2. Mapper.Xml或Dao.Xml书写Sql

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mediinfo.dao.UserOracleDao">

	<!-- 根据Id获取Oracle数据库中的数据 含Clob和Blob字段 -->
    <select id="findVal" resultType="java.util.Map">
        select * from byte_array_test where id = #{id}
    </select>
    
</mapper>

C-3. Junit测试代码

import com.mediinfo.dao.UserOracleDao;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.sql.Blob;
import java.sql.Clob;
import java.util.List;
import java.util.Map;

@SpringBootTest
class TestClobAndBlob {
	@Resource
	private UserOracleDao userOracleDao;

	@Test
	void testBlob() throws Exception {
		// 查询数据库,返回List集合
		List<Map<String, Object>> val = userOracleDao.findVal("123");
		
		if (val!=null && val.size() > 0 ){
			Map<String, Object> temp = val.get(0);
				
			// 获取到Clob字段中的数据,并转为字符串输出
			Clob clobData = (Clob) temp.get("CLOB");
			String str = clobData.getSubString(1, (int) clobData.length());
			System.out.println(str);

			// 获取到Blob字段中的数据,并写入本地文件观察是否有效
			Blob blobData = (Blob) temp.get("BLOB");
			byte[] bytes = blobData.getBytes(1, (int) blobData.length());
			
			// 将Blob的字节数组bytes写入文件
			boolean b = FileUtil.save2File("D:\\test\\22.png", bytes);
			System.out.println(b);
		}
	}
	
}