第一组:
1、
con = ConnectionPool.getConnection();
state = con.createStatement();
StringBuffer sb = new StringBuffer();
sb.append("exec P_DayWorkPay '");//P_DayWorkPay 是一个存储过程
sb.append(cs);//cs是一个变量参数
sb.append("'");
rs = state.executeQuery(sb.toString());2、
con = ConnectionPool.getConnection();
state = con.createStatement();
rs = state.executeQuery("exec P_DayWorkPay "+cs+"');-------------------------------------------------------------------
第二组
1、
conn = ConnectionPool.getConnection();
state = conn.createStatement();
rs = state.executeQuery("exec P_DayWorkPay "+cs+"');2、
conn = ConnectionPool.getConnection();
ps = conn.prepareStatement("exec P_DayWorkPay ?');
ps.setString(2, volumeCode);
rs = ps.executeQuery();还有如果执行的是一条非超长的SQL语句的话,这两组中分别不同的两种写发有没有什么优缺点?还是没有什么优劣?
(ps:这是在公司里两个同事的不同写发,但又方都坚持自己的写发法拒绝统一,所以拿大向大家讨个说法。)

解决方案 »

  1.   

    解释:
    第一组的不同是一个直接用的STRING 另一个是用StringBuffer (那同事这么认为)
    第二组的不同是一个用的createStatement 另一个用的prepareStatement
      

  2.   

    对第一组:
    第二种方法好,原因:
    使用第一种方法的人可能是看了《effective java》的33条吧,认为StringBuffer比String在连接字符串的时候效率高。其实是误会了,StringBuffer代替String只适合这种情况,如
    for(i=0;;)
    {
    String s = s + s'; 
    }
    在这种情况下,不用StringBuffer会重复生成字符串,但对于("exec P_DayWorkPay "+cs+"')的情况,中间的字符串连接结果不会被用到,编译器自己就创造了一个StringBuffer来生成字符串。
    System.out.println(""+""+"")是更典型的例子,自己弄,没必要吗。对第二组:
    假如ps要被重复使用的话,第二组好,设计更优美;否则,选第一种,至少,少了许多语句,SQL语句也能大概看出个样子,便于检查。
      

  3.   

    就我个人而言,第一组我倾向于2的写法,原因就是简洁
    虽然StringBuffer的运算效率比String高,但在这样的代码里,增添这么多无谓的运算操作没意义。第二组要看具体情况,如果该存储过程只因具体参数不同而被频繁地调用,那么显然用绑定方法2效率就更高,但如果也只是一次简单地调用,那么还是1的写法更简洁。这好像跟SQL语句的长度关系不是很大
      

  4.   

    呵呵 
    第一组:StringBuffer的确在多次字符串连接的时候效率高,但如果只是执行一次那么还是用"+"连接符处理的快.
    第二组:如果也是执行一次(执行这条语句的时间间隔大),不是连续传入参数执行查询,那么基本没有什么差别啊.不过楼上说的一样,第一种代码看起来简洁而已.
    但如果是连续传入参数(比如每隔500毫秒)执行查询,显然是第二种方法的效率高于其他的.
      

  5.   

    感谢楼上各位的解释!
    第二组中实际用过的朋友们肯定也有过经验 就是用prepareStatement时对一些日期类型的处理非常方便只要ps.setXXX就搞定了,要是用createStatement还得组合时先把日期转成字符串,所以第二组俺同意prepareStatement不过用第一组 1方法 的同事说如果SQL语句篇幅过大的话用StringBuffer 这种方式比第二种节约内存,不知道是有道理还是牵强赴会?
      

  6.   

    偶也觉得第2组好,prepareStatement是一种预处理,在大量调用的时候,效率比较高,而至于StringBuffer e_Zkz()同胞已经说的很清楚了……偶就不废话了
      

  7.   

    1.java中String的+运算的实现其实就是开辟一个StringBuffer进行append然后再返回String的。就上例而言,其实1就是2在底层的执行,几乎就是一样的。不过String s = s + "abc"和使StringBuffer就有差距了。2.prepareStatement是一种预处理是会好一点
      

  8.   

    SQL语句篇幅过大的话用StringBuffer 这种方式比第二种节约内存,如果不采用S=S+"aaa"这样方法拼凑string 两者所耗内存是一样的
      

  9.   

    预先估计你的字符串长度,用StringBuffer 直接分配逾期长度,效率肯定要好。少了分配memory步骤。
    用prepare 当然最好了,而且读起来也明了
      

  10.   

    讨论的这个问题这好像和这段代码本身没有太大关系。而是在讨论字符串连接的两种方式。
    1. 使用StringBuffer进行连接:
    优点:效率高,不需要创建临时对象
    缺点:写起来麻烦,看起来不直观2. 使用String的+运算符进行连接
    优点:方便,直观
    缺点:产生大量临时对象,降低效率那种方法好,主要看代码中字符串连接操作的次数和连接后字符串的长度。
      

  11.   

    什么事情都不可以一概而论,仔细的讲一下就我所知道的:
    StringBuffer sb = new StringBuffer();
    sb.append("exec P_DayWorkPay '");//P_DayWorkPay 是一个存储过程
    sb.append(cs);//cs是一个变量参数
    sb.append("'");
    在这个情况下的开销
    一个StringBuffer对象
    "exec P_DayWorkPay '","'"两个字符串常量对象
    一次cs的toString()调用
    三次append操作
    还有就是最后的sb.toString();"exec P_DayWorkPay "+cs+"'"
    这个字符串+运算实际上就是开辟一个StringBuffer进行append然后再返回String的,那么这个的开销是:
    "exec P_DayWorkPay "+cs时
    一个StringBuffer对象
    "exec P_DayWorkPay '"字符串常量对象
    一次cs的toString()调用
    两次append操作
    还有就是最后的结果.toString();
    而后第一个"exec P_DayWorkPay "+cs的结果再+"'"时再开销
    一个StringBuffer对象
    "'"字符串常量对象
    一次cs的toString()调用
    两次append操作
    还有就是最后的结果.toString();可以看到如果这里并没有String s = s+"abc";这样反复创建s对象。但就是这样也只有在直+一次的时候开销相当。而且可以知道加的越多,差距越大。因为第一个方法StringBuffer只创建一次而+号则每次都创建而且每次都将结果toString()。总结
    +一次两者相当
    +多次StringBuffer必然高效
      

  12.   

    笔误,以上
    而后第一个"exec P_DayWorkPay "+cs的结果再+"'"时再开销


    一次cs的toString()调用——错误
    这里没有开销这个toString()
      

  13.   

    to:huanming(寰明)感谢你的回复不过有两个问题:
    1、你可能没能看明白我的意思,我是指导第一组里面的1,2作比较;第二组里面的1,2作比较;并不是第一组跟第二组作比较,看来我在三楼解释的还不够明白,语言表达太差不要见怪。
    2、还有这么两句程序就看出有很多据点来了?不防说说,如果有道理另开帖给你加分,说到做到!
      

  14.   

    两组都不对!
    执行存储过程任何一个 exec 都能做!
    但JDBC 有专门的处理存储过程的对象!好象根本不用 String 对象!看来你们公司技术力量不怎么样!...
    ccstm =  .....(?=过程名(?,?))
    ccstm.setString(1,...);
    ......
      

  15.   

    to:ireport991(古城浪子) 晕一个先,俺还是学过JAVA的,呵呵
      

  16.   

    执行存储过程 用 prepareStatement 的子类!