转载

项目案例剖析(1):springJdbc解决对Blob读写,实现照片上传预览

【需求】:1.用户功能中要求实现对用户照片的上传、以及用户照片查看功能。


                 2.为了提升数据的移植性,要求照片文件以流的形式保存到数据库,提供跨数据库的机制。



【思考】:1.传统意义上的角度来看,文件应以路径的形式存储到数据库,通过路径来读写文件流,从而完成对照片的上传、预览,但是


                    数据库如果要备份、转移,项目要重新部署到其他路径上,那我们又要把存放照片的文件copy过来,把项目的路径更新一次,


                    由于考虑到项目部署的空间和范围,以及数据库流动性大的问题,这种情况显然不成立。


                  2.系统采用的SSH框架,实现跨数据库很简单,只需改对datasource的配置进行修改即可。前期表结构以及entity对象,包括hbm文件


                     都相应的生成好了,本着弹性原则,没有去修改user中pic字段的映射,而hibernate本身对blob或者clob字段处理显得很繁琐,不如实际


                     jdbc处理的好,所以决定用springjdbc来实现,解决了jdbc控制流关闭、连接等以及hibernate自身对特殊字段处理一些不便利的操作。



【实现部分】:


                  1. 上传(springJdbc实现对用户照片写===>对用户照片中 blob字段的更新操作)


  1. public void upload(final File file, final String userId) throws Exception {
  2.             final FileInputStream fis = new FileInputStream(file);
  3.             String sql = "update ST_USER  set PIC=?  where  SM_USER_ID=?";
  4.             JdbcTemplate jdbcTemplate = jdbcDao.getJdbcTemplate();
  5.             jdbcTemplate.execute(sql,
  6.                          new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
  7.                           protected void setValues(PreparedStatement ps,
  8.                          LobCreator lobCreator) throws SQLException {
  9.            int length = (int) file.length();
  10.            lobCreator.setBlobAsBinaryStream(ps, 1, fis, length);
  11.            ps.setString(2, userId);
  12.          }
  13.          });
  14.            fis.close();
  15.         }
复制代码

【备注】:1.通过前台获取的file,转换成fileInputStream,在springJdbc进行操作之前对照片这个字段进行设置,通过AbstractLobCreatingPreparedStatement 来对照片字段设置流。  


                 2.值得注意的是lobHandler需要进行配置,它是专门针对clob或者blob进行处理的handler,配置如下:


                                <!-- lobhander 用于处理BLOB 或者 CLOB 字段 -->


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


                                注:加入spring配置文件即可,然后在具体实现类中进行进行依赖注入即可得到。




               2.预览 (springJdbc实现对用户照片读===>读取照片流文件并将结果集转换成byte数组):


  1. public byte [] preview(String userId) throws Exception {
  2.             String sql = "select PIC from  ST_USER where SM_USER_ID=?";
  3.             final String BLOB_KEY="BLOB";
  4.             JdbcTemplate jdbcTemplate = jdbcDao.getJdbcTemplate();
  5.             List<Map<String, byte[]>> list = jdbcTemplate.query(sql,new Object[]{userId}, new RowMapper() {
  6.                     public Object mapRow(ResultSet rs, int i) throws SQLException {
  7.                            Map<String, byte[]> results = new HashMap<String, byte[]>();
  8.                            byte[] blobBytes = lobHandler.getBlobAsBytes(rs, "PIC");
  9.                            results.put(BLOB_KEY, blobBytes);
  10.                   return results;
  11.            }
  12.         });
  13.            return list.get(0).get(BLOB_KEY);
  14.         }
复制代码
【备注】:读取要比存储简单的多,通过jdbc查询,我们得到结果集,在结果集我们将读取出来的照片转换一下,变成byte数组,然后返回。


【后续】:这部分功能只是体现在持久层的实现,如果大家感兴趣,我会放出上传和预览功能的前台端实现(struts2+ext)。


正文到此结束
Loading...