JDBC访问数据库Oracle, MySQL经验总结(一)

 访问效率

    范围:8i&9i的jdbc driver。
    敬告:对于其他版本,想来差不多,但用时总先测测才好,这些经验也是……用时测测最好。

1、PrepareStatement 和 Statement
           如果这个语句唯一,只执行一次(对所有的客户端都是唯一的,即每次执行都需要oracle解析),那么用Statement比较好,不需要额外的通信。如果这个语句会执行多次,一定要用PrepareStatement。如:

PreparedStatement preparedstatement = null;
Connection conn = null;
java.util.Properties prop = new java.util.Properties();
                    prop.setProperty("user", userName);
                    prop.setProperty("password", passwd);
Connection conn = DriverManager.getConnection(urlOfDb, prop);
conn.prepareStatement("insert into test values(?)");
preparedstatement.setString(1,"test");   

2、addBatch()的理解
         (1) 比单个:无区别。如果是不同的sql语句用addBatch,效率和一条条语句单独执行的效率基本上一样(我没有测出区别):
如:
   Statement st = conn.createStatement();
   st.addBatch("update test set s='xxx'");
   st.addBatch("update test set s='yyy''");
   st.executeBatch();

   Statement st = conn.createStatement();
   st.execute("update test set s='xxx'");
   st.execute("update test set s='yyy''");        


       (2) 比单个:高效。如果是PrepareStatement,对参数的批处理,则效率相当的高,比如N(N很大)个插入的情况下,效率可以是原来的N倍上下(时间达到1/N)--当然是通常情况下,具体应用考虑网络,程序等因素。
语句如下:
    conn.prepareStatement("insert into test values(?)");
    for(int i=0; i<1000;i++){
        preparedstatement.setString(1,"test"+i);
        preparedstatement.addBatch();
    }
    int[] updateCounts = preparedstatement.executeBatch();  

3、更新和查询(测试不深,使用时可测试一下,差别也并不大,敬请赐教)
    在查询时,用execute或者executeQuery。
    在更新(或者执行ddl语句)而不要返回数据时,用executeUpdate较好。

MySQL Oracle 查询第10到第100个记录等区间数据时的对比和原因探讨

   由于项目的关系,需要同时支持MySQL和Oracle数据库,所以有一些小的细节,这里也写出来。本来这些都很简单,但是和程序的其他方面混在一起,就让人费时,让人头晕了。这里写的一点,其实也希望以后有更多的总结,更希望大家献出宝贵经验,指点指点。

首先是查询固定数目的记录:

查询MySQLOracle
从第10条开始的100条select * from test limit 10,100select * from (select test.*, rownum ro from test where rownum <=100) where ro >10

 

 

1、rownum 是指选择出来的记录的计数,所以只能用<,<=,(即结果集每得到一条记录,rownum才+1,使用>则永远找不到记录)
2、语句
select id,name from test where rownum <=100 order by id;
会先选择出100条记录然后再排序,所以要选择按顺序排列的记录的前100个,应该使用
select * from (select id,name from test order by id) where rownum <=100;

其次,min,sum等聚集函数时,一定要在取得数据后,判断是否为NULL,否则结果是不对的:

     stmt = dbCon.prepareStatement("select min(i) from test"); 
     rs = stmt.executeQuery();
     if(rs.next())
     {
      long k= rs.getLong(1);
      if(rs.wasNull()) //需要在getLong之后判断
        System.out.println("NUll!!");
     }

另外,如果用到statement.getMetaData(),一定要注意,Oracle的元数据都是大写的。

大对象的问题 BLOB,CLOB,Long Raw(Oracle,MySQL)

1、ORACLE,如果要把一个二制文件存入ORACLE,用标准的JDBC你就要用LONG ROW类型(BLOB需要使用Oracle特定处理,见后)
  InputStream fin = new FileInputStream(file);
  PreparedStatement pstmt = con.prepareStatement("insert into tb_file values('aaa.gif',?)");
  pstmt.setBinaryStream (1, fin, fileLength);
  pstmt.executeUpdate(); 
        fin.close();
 记得update以后才能关闭流。

2、ORACLE,使用BLOB
  con.setAutoCommit(false);
  stmt.executeUpdate("insert into tb_file values('aaa.gif',empty_blob())");
  下面必须SELECT得到BLOB的对象再向里写:
  rs = stmt.executeQuery("select detail from tb_file where name='aaa.gif' for upfdate" );
  if(rs.next())
  {
   Blob blob = rs.getBlob(1);
   BinaryOutputStream out = ((oracle.sql.BLOB)blob).getBinaryOutputStream();
   byte[] b = new byte[((oracle.sql.BLOB)blob).getBufferSize];
   InputStream fin = new FileInputStream(file);
   int len = 0;
   while( (len = fin.read(b)) != -1)
    out.write(b,0,len);
   fin.close();
   out.close();
   con.commit();
  }
  如果用setBinaryInputStream对BLOB操作,大于1k左右的Byte就异常了。

  同样读取数据你并不能象LONG ROW那样
  InputStream in = rs.getBinaryInputStream("detail");
  而要
  Blob blob = rs.getBlob("detail");
  in = blob.getBinaryStream();

3、MySQL
  Varchar最大长度只有255,所以长了就建议用blob。MySQL的blob也奇怪,分成几种:TINYBLOB 其容量为 256 字节、 BLOB 其容量为 64KB MEDIUMBLOB 其容量为 16MB LONGBLOB 其容量为 4GB

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值