1 数据库删除代码
多选删除的一个业务逻辑,为了减少数据的连接断开,直接把ids传入dao里边。
原本是用StringBuilder
的append()
方法优化了String
的+
拼接操作
StringBuilder sql = new StringBuilder("delete from banji where id in (");
//StringBuilder线程不安全 效率高 StringBuffer 线程安全 效率低
for (int i = 0; i < ids.length; i++) {
//sqll += (i == ids.length - 1) ? "?)" : "?,";
sql.append((i == ids.length - 1) ? "?)" : "?,");
}
System.out.println(sql);
无意间在GPT回答中看到
String.join()
方法
于是想对比一下
2 提问
@Test
public void test1() {
String[] ids = {"1", "2", "3"};
StringBuilder sql = new StringBuilder("delete from banji where id in (");
//StringBuilder线程不安全 效率高 StringBuffer 线程安全 效率低
for (int i = 0; i < ids.length; i++) {
//sqll += (i == ids.length - 1) ? "?)" : "?,";
sql.append((i == ids.length - 1) ? "?)" : "?,");
}
System.out.println(sql);
}
@Test
public void test2() {
String[] ids = {"1", "2", "3"};
String[] questionMarks = new String[ids.length];
Arrays.fill(questionMarks, "?");
String sql = "delete from banji where id in (";
String str = String.join(",", questionMarks);
sql = sql + str + ")";
System.out.println(str);
System.out.println(sql);
}
对比下这两个方案哪个更好
4O-免费回答
ChatGPT 也可能会犯错。请核查重要信息。
在这两个测试方法中,目的是生成一个包含占位符 ?
的 SQL 查询字符串。我们可以从以下几个角度对比这两个方案的优缺点:可读性、性能、简洁性和可维护性。
方案对比
方法1:使用StringBuilder
和循环
@Test
public void test1() {
String[] ids = {"1", "2", "3"};
StringBuilder sql = new StringBuilder("delete from banji where id in (");
for (int i = 0; i < ids.length; i++) {
sql.append((i == ids.length - 1) ? "?)" : "?,");
}
System.out.println(sql);
}
优点:
- 性能:
StringBuilder
性能高,因为它是可变的字符串类,避免了多次字符串拼接带来的性能开销。 - 控制力:可以精确控制每个字符的添加,适合需要复杂字符串操作的场景。
缺点:
- 可读性:代码相对较长,不如简洁的API调用直观。
- 易错性:手动拼接字符串容易出错,例如在处理逗号和括号时。
方法2:使用Arrays.fill
和String.join
@Test
public void test2() {
String[] ids = {"1", "2", "3"};
String[] questionMarks = new String[ids.length];
Arrays.fill(questionMarks, "?");
String sql = "delete from banji where id in (";
String str = String.join(",", questionMarks);
sql = sql + str + ")";
System.out.println(str);
System.out.println(sql);
}
优点:
- 可读性:使用
Arrays.fill
和String.join
使代码更简洁,易于理解和维护。 - 简洁性:一行代码即可完成占位符拼接,减少了手动拼接的错误风险。
缺点:
- 性能:在大多数场景下,性能差异可以忽略不计,但
String.join
可能在处理非常大的数组时性能稍逊于StringBuilder
。
结论
两种方法在生成包含占位符的SQL字符串上都可以实现目标,选择哪种方法主要取决于具体需求和偏好。
- 推荐方法2:对于大多数场景,尤其是代码可读性和维护性更重要时,使用
Arrays.fill
和String.join
更简洁直观,且减少了出错的可能。 - 使用方法1的场景:如果在生成SQL字符串的过程中需要进行复杂的字符串处理和拼接,或对性能有极高要求时,使用
StringBuilder
会更灵活和高效。
最终建议在代码中优先考虑可读性和维护性,因为这对长期项目的健康和开发效率至关重要。以下是综合两者优点的实现:
综合实现
将 StringBuilder
和 String.join
结合起来,既保留了 StringBuilder
的高效拼接,又利用 String.join
的简洁性:
@Test
public void test3() {
String[] ids = {"1", "2", "3"};
String[] questionMarks = new String[ids.length];
Arrays.fill(questionMarks, "?");
StringBuilder sql = new StringBuilder("delete from banji where id in (");
sql.append(String.join(",", questionMarks)).append(")");
System.out.println(sql.toString());
}
这种实现方法简洁且高效,适用于大多数场景。
4O-付费回答
ChatGPT 也可能会犯错。请核查重要信息。
两个方案各有优劣,具体选择取决于具体需求和使用场景。让我们详细对比一下这两个方案的优缺点。
方案 1
@Test
public void test1() {
String[] ids = {"1", "2", "3"};
StringBuilder sql = new StringBuilder("delete from banji where id in (");
for (int i = 0; i < ids.length; i++) {
sql.append((i == ids.length - 1) ? "?)" : "?,");
}
System.out.println(sql);
}
优点
- 高效:
StringBuilder
被认为是高效的,因为它不会创建不必要的字符串对象。 - 灵活:可以在循环中动态地构建字符串。
缺点
- 复杂性:代码较为复杂,不易于阅读和维护。
- 线程不安全:
StringBuilder
线程不安全,但在单线程的测试方法中问题不大。
方案 2
@Test
public void test2() {
String[] ids = {"1", "2", "3"};
String[] questionMarks = new String[ids.length];
Arrays.fill(questionMarks, "?");
String sql = "delete from banji where id in (";
String str = String.join(",", questionMarks);
sql = sql + str + ")";
System.out.println(str);
System.out.println(sql);
}
优点
- 简单明了:代码更加简洁,易于阅读和维护。
- 线程安全:虽然
String
的操作本身是线程安全的,但使用String
拼接也不会有线程安全问题。
缺点
- 效率稍低:在大量字符串拼接操作时,
String.join
和+
操作符的效率不如StringBuilder
高。 - 内存占用:
String.join
和+
操作符会创建更多的中间字符串对象,可能会增加内存占用。
性能对比
- 效率:在字符串拼接方面,
StringBuilder
通常比String
拼接操作(如+
和String.join
)更高效,尤其是在大量拼接操作时。 - 可读性:方案 2 更加简洁明了,更适合于容易理解和维护的代码。
选择建议
- 如果注重代码简洁性和可维护性:推荐使用方案 2,代码更容易阅读和维护,适合大多数情况。
- 如果注重性能:在需要大量字符串拼接的情况下,方案 1 使用
StringBuilder
可能会更高效。
进一步优化
无论选择哪种方案,都可以进行进一步优化。例如,可以将拼接操作封装成一个方法,提高代码的重用性和可读性。
结合两者的优化方案
public String buildDeleteSql(String[] ids) {
String[] questionMarks = new String[ids.length];
Arrays.fill(questionMarks, "?");
return "delete from banji where id in (" + String.join(",", questionMarks) + ")";
}
@Test
public void testOptimized() {
String[] ids = {"1", "2", "3"};
String sql = buildDeleteSql(ids);
System.out.println(sql);
}
这种方式结合了方案 2 的简洁性,并将代码的拼接操作封装到一个方法中,使得代码更加模块化和易于维护。