© Young 2016-04-04 14:34
Welcome to My GitHub
概要
使用Mybatis在MySQL数据库中存取BLOB类型数据比较简单唯一需要注意的是乱码的问题,但是在Oracle中存取BLOB类型数据则相对来说有一些复杂…
使用Mybatis在MySQL数据库中存取BLOB类型数据
1、实体里边使用String类型即可,实体类代码片段:
/* 文章内容 */
private String content;
2、在Mybatis的mapper配置文件中,resultMap应该是:
<!-- 实体类全属性和表全字段对应关系 -->
<resultMap id="articleResult" type="knowledge.article.model.Article" >
<!-- 其它属性省略 -->
<result property="content" column="CONTENT" typeHandler="common.architect.ConvertBlobTypeHandler"/>
</resultMap>
typeHandler="common.architect.ConvertBlobTypeHandler"
主要是为了解决乱码的问题,类具体代码如下:
3、package common.architect;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
/**
* 自定义typehandler,解决mybatis存储blob字段后,出现乱码的问题
* 配置mapper.xml:
* <result typeHandler="common.architect.ConvertBlobTypeHandler"/>
*/
public class ConvertBlobTypeHandler extends BaseTypeHandler<String> {
//###指定字符集
private static final String DEFAULT_CHARSET = "utf-8";
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ByteArrayInputStream bis;
try {
//###把String转化成byte流
bis = new ByteArrayInputStream(parameter.getBytes(DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
ps.setBinaryStream(i, bis, parameter.length());
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
//###把byte转化成string
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Blob blob = cs.getBlob(columnIndex);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(ResultSet arg0, int arg1)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
4、读取和插入SQL就和其它基本类型一样处理就可以了,就拿单记录插入SQL举例:
<!-- 增加一条记录(返回主键) -->
<insert id="insert" parameterType="article">
INSERT INTO
NEW_KNOWLEDGE_ARTICLE (
<!-- 其它属性省略 -->
CONTENT
) VALUES (
<!-- 其它属性省略 -->
#{content,jdbcType=BLOB}
)
<!-- MySQL插入返回主键和Oracle不一样,留意一下 -->
<selectKey keyProperty="id" resultType="Long" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
</insert>
使用Mybatis在Oracle数据库中存取BLOB类型数据
1、实体里边使用只能使用Object类型,不能使用byte[],也不能使用BLOB,我试过会有问题…实体类代码片段:
/* 文章内容 */
private Object content;
2、由于在前台需要展示文章内容,所以不管你是用jsp或者其它模板,这里还需要转换成String类型才行,转换代码片段:
try{
BLOB blob = (BLOB)this.getContent();
contentStr = new String(blob.getBytes((long)1, (int)blob.length()));
} catch(SQLException e) {
e.printStackTrace();
}
3、在Mybatis的mapper配置文件中,resultMap应该是:
<!-- 实体类全属性和表全字段对应关系 -->
<resultMap id="articleResult" type="knowledge.article.model.Article" >
<!-- 其它属性省略 -->
<result property="content" column="CONTENT" jdbcType="BLOB"/>
</resultMap>
4、此外Oracle数据库插入BLOB类型数据的时候,要先插入一个empty_blob()占位符,然后再查询出来这个大字段用流的方式写入,所以用Mybatis在Oracle数据库中插入BLOB类型
数据时要在DAO以及mapper配置文件中分两步处理。mapper配置文件片段(
<!-- 增加一条记录(返回主键) -->
<insert id="insert" parameterType="article">
<!-- Oracle插入返回主键和MySQL不一样,留意一下 -->
<selectKey resultType="long" order="BEFORE" keyProperty="id">
SELECT seq_new_knowledge_article.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO
NEW_KNOWLEDGE_ARTICLE T (
<include refid="allColumn"/>
) VALUES (
#{id},
#{addTime,jdbcType=TIME},
#{editTime,jdbcType=TIME},
#{type,jdbcType=VARCHAR},
#{title,jdbcType=VARCHAR},
#{author,jdbcType=VARCHAR},
#{summary,jdbcType=VARCHAR},
#{keywords,jdbcType=VARCHAR},
#{localUrl,jdbcType=VARCHAR},
empty_blob(),
#{showPic,jdbcType=VARCHAR},
#{lookNum,jdbcType=INTEGER},
#{memo,jdbcType=VARCHAR},
#{lastLookTime,jdbcType=TIME}
)
</insert>
<!-- 辅助插入BLOB -->
<select id="helperInsertBlob" resultMap="articleResult">
SELECT
<include refid="allColumn"/>
FROM NEW_KNOWLEDGE_ARTICLE T
WHERE T.ID = #{id}
FOR UPDATE
</select>
//DAO处理方法
/**
* 新增
* @param article
* @return
*/
public Long insert(Article article){
sqlSessionTemplate.insert("newKnowledgeArticle.insert", article);
Article result = this.helperInsertBlob(article.getId());
BLOB blob = (BLOB)result.getContent();
OutputStream ops = null;
ops = blob.getBinaryOutputStream();//暂时使用这个废弃的方法
//ops = content.setBinaryStream(0);//ojdbc14支持,ojdbc6,5都不支持
String contentStr = (String)article.getContent();
byte[] data = contentStr.getBytes();
ops.write(data);
ops.close();
return article.getId();
}
/**
* 辅助新增BLOB
* @param id
* @return
*/
private Article helperInsertBlob(@Param("id")long id){
return sqlSessionTemplate.selectOne("newKnowledgeArticle.helperInsertBlob",id);
}