这里对blob的读是直接在数据库建了一个函数Blob_To_Varchar ,这样方便项目里面其它地方用到查询blob:
CREATE OR REPLACE Function Blob_To_Varchar (Blob_In In Blob) Return Varchar2Is V_Varchar Varchar2(4000); V_Start Pls_Integer := 1; V_Buffer Pls_Integer := 4000;Begin If Dbms_Lob.Getlength(Blob_In) Is Null Then Return ‘‘; End If; For I In 1..Ceil(Dbms_Lob.Getlength(Blob_In) / V_Buffer) Loop --当转换出来的字符串乱码时,可尝试用注释掉的函数 --V_Varchar := Utl_Raw.Cast_To_Varchar2(Utl_Raw.Convert(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start),‘SIMPLIFIED CHINESE_CHINA.ZHS16GBK‘, ‘AMERICAN_THE NETHERLANDS.UTF8‘)); V_Varchar := Utl_Raw.Cast_To_Varchar2(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start)); V_Start := V_Start + V_Buffer; End Loop; Return V_Varchar;End Blob_To_Varchar;
直接在sql里面用创建的Blob_To_Varchar函数。
SELECT Blob_To_Varchar(req_tpl) as req_tpl FROM inf_xml;
二、写blob
oracle存大数据的时候,要先插入一个empty_blob()占位符,占到blob字段,其次在查询出来这个大字段用流的方式写入。
首先是插入一个empty_blob()占位符
//插入数据int insertLogInf = this.logControllerDao.insertLogInfo(params); if(insertLogInf > 0){ //插入大字段数据 for(int i=0;i<2;i++){ if(i == 0){ insertBlob(i,log_id,Const.getStrValue(params, "req_xml")); }else{ insertBlob(i,log_id,rsp_xml); } } }
insertBlob方法(由于要插入2个blob,又不能同时写进去,所以用比较笨的方法循环下)
public void insertBlob(int i , String log_id ,String insertXml)throws Exception{ BLOB blobXML = null; //查询数据 LogInterfaceXML retLogInf = this.logControllerDao.queryBlobLogInfByLogid(log_id); if(i == 0){ blobXML = (BLOB) retLogInf.getReq_xml(); }else{ blobXML = (BLOB) retLogInf.getRsp_xml(); } OutputStream ops = null; try { byte[] data = null; ops = blobXML.setBinaryStream(0); data = insertXml.getBytes(); ops.write(data); } catch (Exception e) { e.printStackTrace(); } finally { try { if(ops!=null){ ops.close(); } } catch (IOException e) { e.printStackTrace(); } } }
这里的req_xml rsp_xml 要用 Object
@Alias("logInterfaceXML")public class LogInterfaceXML { private String log_id; private String op_code ; private String req_time ; private String rsp_time ; private String ep_address ; private String result_desc ; private Object req_xml ; private Object rsp_xml ; public String getOp_code() { return op_code; } public void setOp_code(String op_code) { this.op_code = op_code; } public String getReq_time() { return req_time; } public void setReq_time(String req_time) { this.req_time = req_time; } public String getRsp_time() { return rsp_time; } public void setRsp_time(String rsp_time) { this.rsp_time = rsp_time; } public String getEp_address() { return ep_address; } public void setEp_address(String ep_address) { this.ep_address = ep_address; } public String getResult_desc() { return result_desc; } public void setResult_desc(String result_desc) { this.result_desc = result_desc; } public Object getReq_xml() { return req_xml; } public void setReq_xml(Object req_xml) { this.req_xml = req_xml; } public Object getRsp_xml() { return rsp_xml; } public void setRsp_xml(Object rsp_xml) { this.rsp_xml = rsp_xml; } public String getLog_id() { return log_id; } public void setLog_id(String log_id) { this.log_id = log_id; } }
对数据库的操作用的是mybatis
<resultMap id="logInterfaceResultMap" type="logInterfaceXML"> <result property="log_id" column="id"/> <result property="op_code" column="op_code"/> <result property="req_time" column="req_time" /> <result property="rsp_time" column="rsp_time" /> <result property="ep_address" column="ep_address" /> <result property="req_xml" column="req_xml" jdbcType="BLOB" /> <result property="rsp_xml" column="rsp_xml" jdbcType="BLOB" /> <result property="result_desc" column="result_desc" /> </resultMap> <select id="queryBlobLogInfByLogid" resultType="logInterfaceXML" parameterType="string" databaseId="oracle"> select * from inf_xml c where c.log_id = #{log_id} for update </select> <insert id="insertLogInfo" parameterType="map" databaseId="oracle"> insert into inf_xml (log_id,op_code,req_time,rsp_time,ep_address,req_xml,rsp_xml,state,result_desc) values (#{log_id},#{op_code},to_date(#{req_time},‘YYYY-MM-DD HH24:MI:SS‘),to_date(#{rsp_time},‘YYYY-MM-DD HH24:MI:SS‘),#{ep_address},empty_blob(),empty_blob(),‘1‘,#{result_desc}) </insert>
可能是由于网路问题,这里写入blob的xml数据,时不时的会出现延时问题。
如果马上查询数据的话,可能不一定有数据,要等会才有数据。
具体是什么原因导致的,还在研究中,有哪位大神要是知道,可以告诉小弟一声,谢谢了。
oracle blob mybatis xml读写
标签:
小编还为您整理了以下内容,可能对您也有帮助:
mybatis如何读取clob数据 详细过程
1、MyBatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
2、CLOB
SQL CLOB 是内置类型,它将字符大对象 (Character Large Object) 存储为数据库表某一行中的一个列值。默认情况下,驱动程序使用 SQL locator(CLOB) 实现 Clob 对象,这意味着 CLOB 对象包含一个指向 SQL CLOB 数据的逻辑指针而不是数据本身。Clob 对象在它被创建的事务处理期间有效。
3、MyBatis对CLOB类型数据实现增删改查
oracle表结构
create table T_USERS(
ID NUMBER not null,
NAME VARCHAR2(30),
SEX VARCHAR2(3),
BIRS DATE,
MESSAGE CLOB
)
create sequence SEQ_T_USERS_ID
minvalue 1
maxvalue 99999999
start with 1
increment by 1
cache 20;
配置mybatis配置文件UsersMapper.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN">
<mapper namespace="examples.mapper.UsersMapper" >
<!-- Result Map-->
<resultMap type="examples.bean.Users" id="BaseResultMap">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="sex" column="sex" />
<result property="birs" column="birs" jdbcType="TIMESTAMP"/>
<result property="message" column="message" jdbcType="CLOB"
javaType = "java.lang.String" typeHandler ="examples.service.OracleClobTypeHandler"/>
</resultMap>
<sql id="Tabel_Name">
t_users
</sql>
<!-- 表中所有列 -->
<sql id="Base_Column_List" >
id,name,sex,birs,message
</sql>
<!-- 查询条件 -->
<sql id="Example_Where_Clause">
where 1=1
<trim suffixOverrides=",">
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like concat(concat('%', '${name}'), '%')
</if>
<if test="sex != null and sex != ''">
and sex like concat(concat('%', '${sex}'), '%')
</if>
<if test="birs != null">
and birs = #{birs}
</if>
<if test="message != null">
and message = #{message}
</if>
</trim>
</sql>
<!-- 2.查询列表 -->
<select id="queryByList" resultMap="BaseResultMap" parameterType="Object">
select
<include refid="Base_Column_List" />
from t_users
<include refid="Example_Where_Clause"/>
</select>
</mapper>
Mapper类接口
package examples.mapper;import java.util.List;
public interface UsersMapper<T> {
public List<T> queryBySelective(T t);
public List<T> queryByList(T t);
}
类型转换工具类
package examples.service;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.sql.CLOB;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
public class OracleClobTypeHandler implements TypeHandler<Object> {
public Object valueOf(String param) {
return null;
}
@Override
public Object getResult(ResultSet arg0, String arg1) throws SQLException {
CLOB clob = (CLOB) arg0.getClob(arg1);
return (clob == null || clob.length() == 0) ? null : clob.getSubString((long) 1, (int) clob.length());
}
@Override
public Object getResult(ResultSet arg0, int arg1) throws SQLException {
return null;
}
@Override
public Object getResult(CallableStatement arg0, int arg1) throws SQLException {
return null;
}
@Override
public void setParameter(PreparedStatement arg0, int arg1, Object arg2, JdbcType arg3) throws SQLException {
CLOB clob = CLOB.empty_lob();
clob.setString(1, (String) arg2);
arg0.setClob(arg1, clob);
}
}
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
xmlns:xsi="
xmlns:mvc="
xmlns:tx="
xsi:schemaLocation="
default-autowire="byType">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@127.0.0.1:1521:pms</value></property>
<property name="username"><value>pms</value></property>
<property name="password"><value>pms</value></property>
</bean>
<!-- 配完数据源 和 拥有的 sql映射文件 sqlSessionFactory 也可以访问数据库 和拥有 sql操作能力了 -->
<!--
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations">
<list>
<value>classpath:examples/mybatis/oracle/UsersMapper.xml</value>
</list>
</property>
</bean>
<!-- 通过设置 mapperInterface属性,使接口服务bean 和对应xml文件管理 可以使用其中的sql -->
<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- 此处等同于 Mybatis 中 ServerDao serverDao = sqlSession.getMapper(ServerDao.class); 指明映射关系 -->
<property name="mapperInterface" value="examples.mapper.UsersMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
测试类
package examples.service;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import examples.bean.Users;
import examples.mapper.UsersMapper;
public class TestUsersService {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ParseException {
ApplicationContext ac =
new ClassPathXmlApplicationContext("classpath:/examples/service/spring.xml");
UsersMapper<Users> = (UsersMapper<Users>)ac.getBean("");
//查询
Users nullBean = new Users();
List<Users> list = .queryByList(nullBean);
if(list != null) {
for(Users user : list) {
System.out.println(user);
}
}
}
}
用mybatis做oracle的储存过程2
如何使用Myts调用数据库中的存储过程,下面以Oracle数据库的为例:
1.在数据库中创建以下的存储过程:
2.编写SQL映射文件WxclDAO.xml:
<select id="selectWxcl2" parameterType="java.util.Map" statementType="CALLABLE">
<![CDATA[
call pro_wxcl(#{result,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=WxclMap},
#{wxclid,mode=IN,jdbcType=VARCHAR})
]]>
</select>
其中statementType="CALLABLE"表示要调用存储过程,parameterType参数类型;
jdbcType对应数据库中的数据类型,javaType对应代码中的数据类型,resultMap表示结果集‘WxclMap’
定义了返回的数据类型
3.编写JAVA代码调用存储过程:
public class WxclServiceImpl implements WxclService {
private WxclDAO wxclDAO;
public void setWxclDAO(WxclDAO wxclDAO) {
this.wxclDAO = wxclDAO;
}
@SuppressWarnings("unchecked")
public List<WxclDto> selectWxcl2(WxclBean wxclBean){
// 用作传参和接受返回值
Map<String, Object> params = new HashMap<String, Object>();
params.put("wxclid", "121212");
// 将返回值保存到List中
List<WxclDto> resultList= new ArrayList<WxclDto>();
wxclDAO.selectWxcl2(params);
// 结果集保存在params中通过获取KEY值取得结果
resultList=(List<WxclDto>) params.get("result");
return resultList;
}
4.运行结果图:
用mybatis做oracle的储存过程2
如何使用Myts调用数据库中的存储过程,下面以Oracle数据库的为例:
1.在数据库中创建以下的存储过程:
2.编写SQL映射文件WxclDAO.xml:
<select id="selectWxcl2" parameterType="java.util.Map" statementType="CALLABLE">
<![CDATA[
call pro_wxcl(#{result,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=WxclMap},
#{wxclid,mode=IN,jdbcType=VARCHAR})
]]>
</select>
其中statementType="CALLABLE"表示要调用存储过程,parameterType参数类型;
jdbcType对应数据库中的数据类型,javaType对应代码中的数据类型,resultMap表示结果集‘WxclMap’
定义了返回的数据类型
3.编写JAVA代码调用存储过程:
public class WxclServiceImpl implements WxclService {
private WxclDAO wxclDAO;
public void setWxclDAO(WxclDAO wxclDAO) {
this.wxclDAO = wxclDAO;
}
@SuppressWarnings("unchecked")
public List<WxclDto> selectWxcl2(WxclBean wxclBean){
// 用作传参和接受返回值
Map<String, Object> params = new HashMap<String, Object>();
params.put("wxclid", "121212");
// 将返回值保存到List中
List<WxclDto> resultList= new ArrayList<WxclDto>();
wxclDAO.selectWxcl2(params);
// 结果集保存在params中通过获取KEY值取得结果
resultList=(List<WxclDto>) params.get("result");
return resultList;
}
4.运行结果图:
使用mybatis将string转为blob存入数据库时出现ora-01465异常,无效的十六进制转换!求解,求解
oracle中用于保存位串的数据类型是RAW,LONG RAW(推荐使用BLOB)。
RAW,类似于CHAR,声明方式RAW(L),L为长度,以字节为单位,作为数据库列最大2000,作为变量最大32767字节。
LONG RAW,类似于LONG,作为数据库列最大存储2G字节的数据,作为变量最大32760字节
RAW类型的好处就是:在网络中的计算机之间传输 RAW 数据时,或者使用 Oracle 实用程序将 RAW 数据从一个数据库移到另一个数据库时,Oracle 服务器不执行字符集转换。存储实际列值所需要的字节数大小随每行大小而异,最多为 2,000 字节。可能这样的数据类型在数据库效率上会提高,而且对数据由于字符集的不同而导致的不一致的可能性在这边也排除了。
下面是官方的定义:
Note:
The LONG RAW datatype is provided for backward compatibility with existing applications. For new applications, use the BLOB and BFILEdatatypes for large amounts of binary data.
The RAW and LONG RAW datatypes are used for data that is not to be interpreted (not converted when moving data between different systems) by Oracle. These datatypes are intended for binary data or byte strings. For example, LONG RAW can be used to store graphics, sound, documents, or arrays of binary data. The interpretation depends on the use.
RAW is a variable-length datatype like the VARCHAR2 character datatype, except Oracle Net Services (which connects user sessions to the instance) and the Import and Export utilities do not perform character conversion when transmitting RAW or LONG RAW data. In contrast, Oracle Net Services and Import/Export automatically convertCHAR, VARCHAR2, and LONG data between the database character set and the user session character set (set by the NLS_LANGUAGE parameter of the ALTER SESSION statement), if the two character sets are different.
When Oracle automatically converts RAW or LONG RAW data to and from CHAR data, the binary data is represented in hexadecimal form with one hexadecimal character representing every four bits of RAW data. For example, one byte of RAW data with bits 11001011 is displayed and entered as 'CB.'
LONG RAW data cannot be indexed, but RAW data can be indexed.
常用于操作raw类型的函数:UTL_RAW.CAST_TO_RAW,hextoraw.
RAW保存的为16进制数。当使用HEXTORAW时,会把字符串中数据当作16进制数。而使用UTL_RAW.CAST_TO_RAW时,直接把字符串中每个字符的ASCII码存放到RAW类型的字段中。
下面是常用到了两个函数:
utl_raw.cast_to_raw([varchar2]);--将varchar2转换为raw类型
utl_raw.cast_to_varchar2([raw]);--将raw转换为varchar2类型
这里varchar2的字符集一般是GB2312。
因为RAW保存的为16进制数。故下面的SQL会报错: insert into test_raw values (hextoraw('hh'))
insert into test_raw values (hextoraw('hh'))
*
ERROR 位于第 1 行:
ORA-01465: 无效的十六进制数字
raw类型数据列常用的位操作:
utl_raw.bit_or();
utl_raw.bit_and();
utl_raw.bit_xor();
mybatis generator为什么会生成withblobs
前面几个回答的都是什么东西。。。
说白了就是优化。
blob,longtext这些类型的数据数据量可能会很大。频繁的操作会有效率问题。
当我们不需要操作这些数据时,就可以使用id不带withBlobs的方法。(比如展示分页列表的时候,我们只需要展示简单的数据就可以了)
需要操作它们到时候,再通过id带withBlobs的方法来操作就行了(比如展示详情数据时)
可以类比延迟加载。