Spring基础:数据访问(2)

上一篇主要将了Spring JDBC的基本操作CURD,涉及到的类型也是基础类型,int,varchar,time,timestamp之类的简单类型,这一篇中主要说明在Spring中如何处理CLOB,BLOB类型数据。

[size=large]1.操作BLOB/CLOB数据[/size]
BLOB被称作二进制对象,CLOB被称作大文本对象。他们在不同的数据库中可能名字也不相同,比如:在Sql Server中就是IMAGE/TEXT,在Mysql中就是BLOB/LONGTEXT,处理方式也不完全相同,在Mysql中LONGTEXT处理方式和VARCHAR是相同的。BLOB可能以块方式处理,也可以以流方式处理。

首先需要配置LobHandler,这个类可以专业的处理BLOB/CLOB

<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>

[color=red]注意,如果使用的是Oracle 9i需要特殊处理,配置NativeJdbcExtrator,并且需要将Extrator加入到JdbcTemplate和LobHandler的对象属性中[/color]
下面我们来看下LOB的处理,

@Repository
public class PostDao {
@Autowired
private JdbcTemplate jdbcTemplate;

@Autowired
private LobHandler lobHandler;

public void addPost(final Post post) {
String sql = "INSERT INTO t_post(user_id,post_text,post_attach) VALUES(?,?,?)";
jdbcTemplate.execute(sql, new AbstractLobCreatingPreparedStatementCallback(this.lobHandler) {
@Override
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException, DataAccessException {
ps.setInt(1, post.getUserId());
lobCreator.setClobAsString(ps, 2, post.getPostText());
lobCreator.setBlobAsBytes(ps, 3, post.getPostAttach());
}
});
}
}

需要使用AbstractLobCreatingPreparedStatementCallback类来代替普通的Callback类,还需要向它的构造函数中传入lobHander。

以块数据的方式处理LOB数据
以byte[]的方式来处理

public List<Post> getAttaches(final int userId) {
String sql = "SELECT post_id,post_attach,post_text FROM t_post WHERE user_id=? and post_attach IS NOT NULL";
return jdbcTemplate.query(sql, new Object[] { userId }, new RowMapper<Post>(){
public Post mapRow(ResultSet rs, int rowNum) throws SQLException {
int postId = rs.getInt("post_id");
byte[] attach = lobHandler.getBlobAsBytes(rs, "post_attach");
String text = lobHandler.getClobAsString(rs, "post_text");
Post post = new Post();
post.setPostId(postId);
post.setUserId(userId);
post.setPostAttach(attach);
post.setPostText(text);
return post;
}
});
}


以流的方式来处理LOB对象
如果LOB对象很大,比如100M,如果采用块的方式来处理,将会消耗很大的内存,所以采用流的方式来处理比较好。

public void getAttach(final int postId, final OutputStream os) {
String sql = "SELECT post_attach FROM t_post WHERE post_id=?";
jdbcTemplate.query(sql, new Object[] { postId }, new AbstractLobStreamingResultSetExtractor<Post>() {
@Override
protected void streamData(ResultSet rs) throws SQLException,
IOException, DataAccessException {
InputStream is = lobHandler.getBlobAsBinaryStream(rs, 1);
if(is != null)
FileCopyUtils.copy(is, os);
}
});
}


[size=large]2.自增键和行集[/size]
自增键有两种方式,一种是Oracle基于序列的方式,一种是基于表的方式,这里仅描述针对表的方式。自增键的基类是DataFieldMaxValueIncrementer,有兴趣可以自己看下。

<bean id="incre" class="org.springframework.jdbc.support.incrementer.DerbyMaxValueIncrementer"
p:incrementerName="t_post_id"
p:columnName="sequence_id"
p:cacheSize="10"
p:dataSource-ref="basicDataSource"/>

在DAO类中,注入以上Bean,就可以使用incre.nextIntValue()获取主键了。

行集SqlRowSet的内容不是很清楚,这里暂时跳过。

[size=large]3.其他类型的JdbcTemplate[/size]
主要是NamedParameterJdbcTemplate,下面看下实例。

<bean id="namedParamJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"
p:dataSource-ref="basicDataSource"/>


@Repository
public class PostDao {
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

public void addPostByNamedParams(final Post post) {
String sql = "INSERT INTO t_post(user_id,post_text) VALUES(:userId,:postText)";
SqlParameterSource sps = new BeanPropertySqlParameterSource(post);
namedParameterJdbcTemplate.update(sql, sps);
}

public void addPostByMapSqlParams(final Post post) {
String sql = "INSERT INTO t_post(user_id,post_text) VALUES(:userId,:postText)";
SqlParameterSource sps = new MapSqlParameterSource()
.addValue(":userId", post.getUserId())
.addValue(":postText", post.getPostText());
namedParameterJdbcTemplate.update(sql, sps);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值