如何使用Java ResultSet转换结果为字符串?MySQL导出.sql处理Blob与Date
其实这个需求得看你想要什么格式的字符串——比如CSV、JSON,或者自定义分隔格式。我给你两种常用的实现思路:
方法1:拼接为CSV格式字符串
这种方式简单直观,适合快速导出表格数据:
public String resultSetToCsv(ResultSet rs) throws SQLException { StringBuilder sb = new StringBuilder(); ResultSetMetaData meta = rs.getMetaData(); int columnCount = meta.getColumnCount(); // 先写表头 for (int i = 1; i <= columnCount; i++) { sb.append(meta.getColumnName(i)); if (i < columnCount) sb.append(","); } sb.append("\n"); // 遍历每一行数据 while (rs.next()) { for (int i = 1; i <= columnCount; i++) { Object value = rs.getObject(i); // 处理字符串类型,避免逗号冲突,用引号包裹并转义内部引号 if (value instanceof String) { sb.append("\"").append(value.toString().replace("\"", "\"\"")).append("\""); } else { sb.append(value != null ? value.toString() : ""); } if (i < columnCount) sb.append(","); } sb.append("\n"); } return sb.toString(); }
方法2:自定义格式拼接
如果需要更灵活的格式(比如每行用括号包裹,列用分号分隔),可以调整拼接逻辑:
public String resultSetToCustomString(ResultSet rs) throws SQLException { StringBuilder sb = new StringBuilder(); ResultSetMetaData meta = rs.getMetaData(); int columnCount = meta.getColumnCount(); while (rs.next()) { sb.append("("); for (int i = 1; i <= columnCount; i++) { Object value = rs.getObject(i); // 转义单引号避免SQL语法错误 sb.append(value != null ? "'" + value.toString().replace("'", "''") + "'" : "NULL"); if (i < columnCount) sb.append("; "); } sb.append(")\n"); } return sb.toString(); }
注意:处理字符串时一定要转义特殊字符(比如单引号、双引号),避免格式混乱或者后续复用字符串时出现SQL语法问题。
你提到的getObject(column)是可以用的,但要针对Blob和Date类型做针对性转换——直接调用toString()会得到不符合SQL语法的结果(比如Date会变成java.sql.Date@xxx,Blob会变成com.mysql.cj.jdbc.Blob@xxx)。下面是具体的处理方案:
1. Date类型的处理
Java里的java.sql.Date、java.sql.Timestamp可以直接转成MySQL支持的日期字符串格式,用单引号包裹即可:
Object value = rs.getObject(columnIndex); String insertValue; if (value instanceof java.sql.Date || value instanceof java.sql.Timestamp) { // 转成MySQL认可的'YYYY-MM-DD HH:MM:SS'格式 String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value); insertValue = "'" + dateStr + "'"; }
也可以尝试用rs.getString(columnIndex),部分JDBC驱动会直接返回格式化后的日期字符串,但自己手动格式化更稳妥。
2. Blob类型的处理
Blob类型在INSERT语句里有两种常见写法:
方式A:转成十六进制字符串(推荐)
MySQL支持用0x前缀的十六进制字符串表示Blob数据,这样可以直接写入SQL:
Object value = rs.getObject(columnIndex); String insertValue; if (value instanceof Blob) { Blob blob = (Blob) value; byte[] bytes = blob.getBytes(1, (int) blob.length()); // 把字节数组转成十六进制字符串 StringBuilder hexSb = new StringBuilder(); for (byte b : bytes) { hexSb.append(String.format("%02X", b)); } insertValue = "0x" + hexSb.toString(); // 记得关闭Blob资源释放内存 blob.free(); }
方式B:用BASE64编码(适合小Blob)
如果Blob数据不大,也可以用BASE64编码后,在INSERT时用FROM_BASE64()函数解析:
Object value = rs.getObject(columnIndex); String insertValue; if (value instanceof Blob) { Blob blob = (Blob) value; byte[] bytes = blob.getBytes(1, (int) blob.length()); String base64Str = Base64.getEncoder().encodeToString(bytes); insertValue = "FROM_BASE64('" + base64Str + "')"; blob.free(); }
通用的字段值处理逻辑
把这些逻辑整合到你的INSERT生成代码里,大概是这样:
public String getInsertValue(ResultSet rs, int columnIndex) throws SQLException { Object value = rs.getObject(columnIndex); if (value == null) { return "NULL"; } if (value instanceof String) { // 转义单引号 return "'" + ((String) value).replace("'", "''") + "'"; } else if (value instanceof Number) { return value.toString(); } else if (value instanceof java.sql.Date || value instanceof java.sql.Timestamp) { String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value); return "'" + dateStr + "'"; } else if (value instanceof Blob) { Blob blob = (Blob) value; byte[] bytes = blob.getBytes(1, (int) blob.length()); StringBuilder hexSb = new StringBuilder(); for (byte b : bytes) { hexSb.append(String.format("%02X", b)); } blob.free(); return "0x" + hexSb.toString(); } else { // 其他类型默认转字符串并转义 return "'" + value.toString().replace("'", "''") + "'"; } }
调用这个方法就能把每个字段的值转换成符合SQL语法的字符串,直接拼到INSERT INTO语句里使用了。
内容的提问来源于stack exchange,提问作者Forseth11

