2

我的 java 项目有问题。

以下函数应该为 SQL 语句提供一个字符串:

private static String createInsertString(Pat p)
{   
    StringBuilder x = new StringBuilder();


    x.append(""  + p.getPatnr() +","+ p.getSvnr());

    java.sql.Date andat = null,gebdat;

    if(p.getAndat()==null)
        andat=null;
    else
        andat=new java.sql.Date(p.getAndat().getTimeInMillis());

    if(p.getGebdat()==null)
        gebdat=null;
    else
        gebdat=new java.sql.Date(p.getGebdat().getTimeInMillis());

    x.append("," + andat==null?"null":andat);
    x.append("," + p.getTele()==null?"null":p.getTele());
    x.append("," + p.getVName() +","+ p.getNname());
    x.append("," + p.getKk()==null?"null":p.getKk());
    x.append("," + gebdat==null?"null":gebdat);
    x.append("," + p.getAdrplzort()==null?"null":6);
    x.append("," + p.getAdrstr()==null?"null":p.getAdrstr());
    x.append("," + p.getAdrhnr()==null?"null":p.getAdrhnr());
    s.append("," + p.getReplzort()==null?"null":p.getReplzort().getPlzortnr());
    x.append("," + p.getRestr()==null?"null":p.getRestr());
    x.append("," + p.getRehnr()==null?"null":p.getRehnr());
    x.append("," + p.getLevel());
    x.append("," + p.getCon()==null?"null":p.getCon());
    x.append("," + (p.isPa()?"y":"n")+","+ (p.isLonly()?"y":"n") +","+ (p.isGest()?"y":"n"));
    x.append("," + p.getBem()==null?"null":p.getBem());
    x.append("," + (p.isKat1()?'y':'n') +","+ (p.isKat2()?'y':'n') +","+ (p.isKat3()?'y':'n'));

    System.out.println(x);

    return x.toString();
} 

输出是

6,6465136nullnull,Jürgen,Wieslernullnull6nullnullnullnull,0null,n,n,nnull,n,n,n

但它应该是这样的:

6,6465136,null,null,Jürgen,Wiesler,null,null,6,null,null,null,null,0,null,n,n,n,null,n,n,n

任何人的想法?我在 debian(64 位)上使用 jdk 1.7

4

3 回答 3

11

问题是运营商如何绑定。看这个:

x.append("," + andat==null?"null":andat);

现在把它想象成:

x.append(("," + andat) == null ? "null" : andat);

LHS永远不会为空,所以它总是只是附加andat... 如果引用为空,它仍然会转换为“null”,因为这是StringBuilder.

您的代码比它需要的要复杂得多且效率低下。考虑将其重写为:

private static String createInsertString(Pat p)
{   
    StringBuilder x = new StringBuilder();
    java.sql.Date andat = p.andat == null ? null 
        : new java.sql.Date(p.getAndat().getTimeInMillis());
    java.sql.Date gebdat = p.getGebdat() == null ? null 
        : new java.sql.Date(p.getGebdat().getTimeInMillis());

    x.append(p.getPatnr()).append(",")
     .append(p.getSvnr()).append(",")
     .append(andat).append(",")
     .append(p.getTele()).append(",")

     // etc

    return x.toString();
}

请注意,我认为您在原始版本中有一个错误:

x.append("," + p.getVName() +","+ p.getNname());

这些意味着在哪里调用两个不同的吸气剂?

于 2012-04-24T14:50:26.133 回答
4

.append()通过将连接放入其中来滥用!这错过了StringBuilder应该使用的全部要点。

 x.append("," + andat==null?"null":andat);

应该

 x.append(",").append( andat == null ? "null" : andat);

这将是使您的三元运算符按预期工作的正确逻辑。

.append()返回对的引用,StringBuilder以便您可以.append()根据需要链接调用。

每当您在内部放置字符串连接时,.append()只会创建更多的中间String对象,这些对象会占用内存、cpu 周期,然后使用更多资源,因为它们现在需要被垃圾收集。

此外,您应该预先分配StringBuilder一个比您期望的内容稍大的默认大小,以避免浪费分配和垃圾创建。

有关构造函数,请参见JavadocStringBuilder(int)

于 2012-04-24T14:52:51.827 回答
3

问题来自您的“+”。

  1. 如果您使用 StringBuilder,请不要使用“+”:效率不高
  2. "," + andat==null?"null":andat结果",null"==null?"null":andat如果 andat 为空。

'+' 字符串连接优先于三元运算符

当您将“+”与 String 一起使用时,您的编译器实际上会将其转换为 StringBuilder(或 Java5 之前的 StringBuffer)

所以有

String s = a + b + c;

实际上翻译为:

String s = new StringBuilder().append(a).append(b).append(c).toString().

因此,在 StringBuilder 中使用 + 会适得其反,因为您会创建额外的不必要的 StringBuilder。

于 2012-04-24T14:51:35.213 回答