当前位置: 首页 > 面试题库 >

在SQL中使用StringBuilder的正确方法

施彬郁
2023-03-14
问题内容

我刚刚在我的项目中发现了一些这样的sql查询构建

return (new StringBuilder("select id1, " + " id2 " + " from " + " table")).toString();

这是否StringBuilder达到其目标,即减少内存使用量?

我对此表示怀疑,因为在构造函数中使用了“
+”(字符串concat运算符)。像下面的代码那样,将占用与使用String相同的内存量吗?我了解,使用时有所不同StringBuilder.append()

return "select id1, " + " id2 " + " from " + " table";

两条语句的内存使用量是否相等?请澄清。

提前致谢!

编辑:

顺便说一句, 这不是我的代码 。在一个旧项目中发现它。而且,查询的大小不如我的示例中的查询小。:)


问题答案:

使用StringBuilder的目的是减少内存。完成了吗?

一点都不。该代码未StringBuilder正确使用。(不过,我认为您的报价有误;id2和的周围肯定没有引号table吗?)

请注意,通常的目的是减少内存 流失, 而不是减少使用的总内存,以使垃圾收集器的工作更轻松。

这样占用的内存等于使用如下所示的String吗?

不,这将导致 更多的
内存流失,而不仅仅是您引用的直接连接。(除非/除非JVM优化器认为StringBuilder代码中的显式内容是不必要的,否则将其优化)。

如果该代码的作者想要使用StringBuilder(有参数支持,但也有反对;请参见此答案末尾的注释),则最好做得好(在此我假设id2和之间实际上没有引号table):

StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, ");
sb.append(id2);
sb.append(" from ");
sb.append(table);
return sb.toString();

请注意,我已经some_appropriate_sizeStringBuilder构造函数中列出了它,以便它以足够的容量开始要添加的全部内容。如果未指定一个字符,则使用的默认大小为16个字符,通常太小,导致StringBuilder必须进行重新分配以使其自身变大(IIRC,在Sun
/ Oracle JDK中,它会自身加倍[或更多,如果它知道append每次用完房间都需要更多满足特定条件。

您可能听说过,如果使用Sun / Oracle编译器进行编译,则字符串连接
StringBuilder在幕后使用。的确如此,它将StringBuilder为整体表达使用一个。但是它将使用默认构造函数,这意味着在大多数情况下,它将不得不进行重新分配。不过,它更容易阅读。请注意,这对于
一系列 串联 不是 正确的。因此,例如,它使用一个: __StringBuilder

return "prefix " + variable1 + " middle " + variable2 + " end";

它大致翻译为:

StringBuilder tmp = new StringBuilder(); // Using default 16 character size
tmp.append("prefix ");
tmp.append(variable1);
tmp.append(" middle ");
tmp.append(variable2);
tmp.append(" end");
return tmp.toString();

所以没关系,虽然默认的构造函数和随后的重新分配(S)不理想,赔率是它不够好-以及级联是一个 很大 的可读性。

但这仅适用于单个表达式。StringBuilder为此使用了多个:

String s;
s = "prefix ";
s += variable1;
s += " middle ";
s += variable2;
s += " end";
return s;

最终变成这样的东西:

String s;
StringBuilder tmp;
s = "prefix ";
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable1);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" middle ");
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable2);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" end");
s = tmp.toString();
return s;

…这很丑。

但是要记住,重要的是,在几乎所有情况下, 这都无关紧要 ,除非有特定的性能问题, 否则最好选择 可读性(增强可维护性)。



 类似资料:
  • 本文向大家介绍Linux中Homebrew的正确使用方法,包括了Linux中Homebrew的正确使用方法的使用技巧和注意事项,需要的朋友参考一下 很多人都在使用Linux Homebrew ,有三个技巧可以帮助你更好的使用它: 避免环境污染 首先要避免将 Homebrew 的 bin 目录添加到 $PATH ,而仅仅将你需要使用的几个可执行做软连接放到 ~/bin 下面(这个目录在 $PATH

  • 问题内容: 我正在尝试学习如何在PyQt Gui应用程序中使用QThreads。我有一些可以运行一段时间的东西,(通常)可以在其中更新Gui的点,但是我想将主要工作拆分为自己的线程(有时东西会卡住,最终有一个取消/重试按钮,如果Gui被冻结(因为主循环被阻塞),则该按钮显然不起作用)。 我已阅读https://mayaposch.wordpress.com/2011/11/01/how-to-re

  • 问题内容: 这个想法是使用更少的连接和更好的性能。连接是否随时终止? 对于另一个问题,是否打开新连接? 问题答案: 不,多路复用器不会过期。没有GetDatabase不会打开新连接。basics.md涵盖了所有内容 -特别是: 从GetDatabase返回的对象是便宜的直通对象,不需要存储。

  • 我有一个使用jquery mobile的应用程序,它由几个html页面组成,每个页面中都有几个jquery页面元素。在桌面浏览器上,一切正常,但当我把它加载到我的android设备(运行2.3)上时,第一个页面看起来很好,但只要你点击一个链接(比如从index.html)- 那么,是否有正确的方法在不同的html页面之间移动呢?我没有得到任何浏览器错误,所以一切似乎都工作正常,但没有jqm的样式或

  • 问题内容: 我正在尝试对表单中的某些字段使用get_or_create,但尝试这样做时却出现500错误。 其中一行如下所示: 对于以上代码,我得到的错误是: 问题答案: 从文档get_or_create中: 说明: 要评估相似性的字段必须在外部提及。其余字段必须包含在中。如果发生CREATE事件,则会考虑所有字段。 看起来你需要返回一个元组,而不是单个变量,请执行以下操作: