要将文件直接插入数据库,可以通过使用BLOB和CLOB字段类型来完成:大致是先在数据中插入记录,然后再通过for update 语句将对象查询出来(这里有事务提交问题),最后通过oracle包的BLOB字段获取输出流,将对象写进数据库。

  使用Mybatis如下:

  1.POJO:

public class FileInfo  {
  private String fileId;
  //文件二进制流字段,这里要用Object类型,我试了BLOB类型都不行。
  private Object fileContent;
  ...
}

    2.Service方法:         

           //先将对象插入
          dao.insertFile(fileInfo);
//再获取文件二进制流,将文件对象插入数据
          fileInfo=dao.getFileById(fileInfo.getFileId()); 
oracle.sql.BLOB blob = (BLOB) fileInfo.getFileContent(); os = blob.setBinaryStream(0); //这是最新的获取流方法 URL url = new URL(fileInfo.getFileDownloadUrl()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); is = new BufferedInputStream(conn.getInputStream()); byte[] bytes = new byte[2048]; int len; while ((len = is.read(bytes)) != -1) {
            //这里不能直接os.write(bytes),会导致文件损坏 os.write(bytes,
0, len); } os.flush();

3.sql语句:

    <insert id="insertFile">
        <selectKey  keyProperty="fileId" resultType="String" order="BEFORE">
            SELECT file_seq.nextval FROM dual
        </selectKey>
        INSERT INTO file(
        file_id,
        CONTENT,
        creation_Date
        )
        VALUES (
        #{fileId},
        empty_blob(),   <--用 empty_blob() 函数占位-->
        sysdate
        )
    </insert>

     <--在用for update 语句将BLOB字段写入-->
    <select id="getFileById" resultType="entity.abuteInter.FileInfo">
        SELECT * FROM file WHERE file_id=#{fileId} for update
    </select>

   这样基本就OK了,不过一开始出现了一个怪现象,我在一个for循环里插入多个文件,最后一个文件却总是为空。经检查发现,在for update查询语句之后没有提交事务,前面的数据因为后面会继续执行insert操作,所以事务自动提交了,而最后一条记录结束就没办法了。一般网上很多例子都是用Connection 打开连接,然后用提交事务,但是我用mybatis没法,只得再执行一个方法,sql:

<select id="commit">
        COMMIT
</select>

这是oracle提交事务的sql语句。用Connection.commit方法是对当前连接的事务操作,也就是对其他的连接事务无效,但是这个语句应该是数据库整体事务。

posted on 2018-08-03 14:33  OverTheWay  阅读(505)  评论(0编辑  收藏  举报