java上传大对象到oracle数据库

原来做数据库对图片的存储都是直接存储图片在服务器中的路径,但是今天老大要求需要存储图片进去,没办法,老老实实的存图片。下面我就这个过程写下一个测试的实例。

首先,我在数据库中建了一个表,如下:

-- Create table
create table TESTCLOB
(
  cid      NUMBER(4),
  pathname VARCHAR2(100),
  picture  CLOB
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

就三个字段,cid应该是主键,唯一标示,因为这里只是测试用,所以就没有声明为主键。pathname,当然是所需要存储的对象在服务器中的地址,我这里以图片为例,当然就是图片的地址。picture,放图片的字段,是个clob(大对象)类型。下面的是表空间,当然你可以不写,oracle会给你一个默认的表空间。

下面就是java代码了。

在myeclipse中建一个类,文件名为TestClob.java,此文件中我放了两个类,一个public的,一个默认的。

public的是用来对数据库进行插入操作的。而另一个则是管理数据库连接的DBManager类。

首先来看DBManager类:

class DbManager{
Connection conn = null;
PreparedStatement stmt = null;
String url = "jdbc:oracle:thin:@localhost:1521:orcl";

//获得数据库连接的方法
public Connection getConnection(){
  try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
   conn = DriverManager.getConnection(url, "scott", "tiger");
   //stmt=conn.prepareStatement(sql);
   System.out.println("获得连接成功!");
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } 
  return conn;
}

//获得PreparedStatement的方法
public PreparedStatement getstmt(String sql){
  try {
   stmt=conn.prepareStatement(sql);
   System.out.println("获得stmt对象!");
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return stmt;
}
}

写完可以在public类中建个DBManager对象调用这两个方法,看看连接是否成功。

下面就来看看public类:

类名当然就是文件名了,public class TestClob,显然,就是TestClob了。

下面我们来看其中的方法:

首先是主方法:

public static void main(String[] args) {
  String path="D:\\temp\\a.jpg";
  TestClob tc=new TestClob();
  tc.add(path);
}

里面创建了一个TestClob的对象,然后用此对象调用了本类的add方法(下面将会给出),传入了图片的路径。

下面就是重点了,此方法将会把对应路径的图片插入到数据库中去:

public void add(String path){
  Connection conn = null;
  PreparedStatement stmt = null;

//首先让数据库中需要插入的此条记录的clob对象初始化,用empty_clob()方法
  String sql ="insert into testclob(cid,pathname,picture) values(?,?,empty_clob())";

//这里创建DBManager类的对象db,获得连接。创建db对象你可以自己new,全局的还是局部的,由你决定,当然我这里用的全局的
  conn=db.getConnection();

//设置提交方式,这里不让数据库默认提交

//如果你的程序抛出了java.sql.SQLException: ORA-01002: 提取违反顺序  这种异常,那么你就该考虑加上这句话了
  //conn.setAutoCommit(false);
  stmt=db.getstmt(sql);
  try {

//设置参数值
   stmt.setInt(1, 1);
   stmt.setString(2, path);

//执行sql语句,我这里是PreparedStatement所以就直接executeUpdate()了,如果你的是Statement对象的话,就应该是executeUpdate(sql)方法了
   stmt.executeUpdate();
   System.out.println(path);

//下面几是插入clob对象的图片了
   String query="select picture from testclob where pathname=? for update";
   stmt=db.getstmt(query);
   stmt.setString(1, path);

//得到查询结果集,很明显,这个结果集应该只有一条记录的
   ResultSet rs =stmt.executeQuery();

//使结果集指针向下移动一位,在java中查询出来的结果集的指针当前指的都是最上面的没有数据的位置,向下移动一位才是第一条数据
   rs.next();

//使用CLOB类型接收从结果集中查询出来的大对象字段
   CLOB myClob=((OracleResultSet)rs).getCLOB("picture");

//获得对象的大小
   int chunkSize = myClob.getChunkSize();

//为此对象创建缓冲
   char [] textBuffer = new char[chunkSize];

//根据图片路径穿件文件
   File myFile = new File(path);
   FileInputStream myFileInputStream=null;
   InputStreamReader myReader=null;
   BufferedReader myBufferedReader=null;
   try {

//获得输入文件流,建立通道
    myFileInputStream = new FileInputStream(myFile);

//获得读文件流对象,从通道中读取数据
    myReader =new InputStreamReader(myFileInputStream);

//获得缓冲流对象,读取的对象到缓冲流中去,这也是一般的文件操作的步骤,以此可以看出java的层层封装
    myBufferedReader = new BufferedReader(myReader);
    long position = 1;
    int charsRead;
    while ((charsRead = myBufferedReader.read(textBuffer)) != -1){
      myClob.putChars(position, textBuffer);
      position += charsRead;
     }
   } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }finally{
    try {
     myBufferedReader.close();
     myReader.close();
     myFileInputStream.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }

//做完提交持久化改变
   stmt.execute("COMMIT");
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
}

至此这个小例子就完成了。住大家顺利!

阅读更多
个人分类: java oracle
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭