文章目录
- 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);
}
}
}