我正在创建android应用程序,其中发送一些数据到数据库使用spring应用程序,也是我创建的。
我用来保存数据的方法如下:
public void save(LinkedHashMap<String, Object> dataCollected) {
String sql = "INSERT INTO sys001.lm.bottle_neck_reject ("
+ "\n col_1, col_2, col_3, col_4,"
+ "\n col_5, col_6, col_7, col_8, col_9,"
+ "\n col_10, col_11, col_12,"
+ "\n col_13)"
+ "\n VALUES (?, ?, ?, ?,"
+ "\n ?, ?, ?, convert(datetime, ? + ' ' + ?, 103), ?,"
+ "\n ?, ?, ?, ?)";
dataCollected.forEach((key, value) -> {
System.out.println(key + " > " + value); // output: key_one > value_one
});
try(Connection conn = getConnection();
PreparedStatement saveStatement = conn.prepareStatement(sql)){
saveStatement.setString(1, (String) dataCollected.get("key_one"));
saveStatement.setString(2, "WH"); // this value are saved
saveStatement.setString(3, "PC"); // this value are saved
saveStatement.setString(4, (String) dataCollected.get("key_two"));
saveStatement.setString(5, "UN"); // this value are saved
saveStatement.setString(6, (String) dataCollected.get("key_three"));
saveStatement.setString(7, (String) dataCollected.get("key_four"));
saveStatement.setString(8, (String) dataCollected.get("date"));
saveStatement.setString(9, (String) dataCollected.get("time"));
saveStatement.setString(10, (String) dataCollected.get("key_five"));
saveStatement.setString(11, (String) dataCollected.get("key_six"));
saveStatement.setString(12, (String) dataCollected.get("key_seven"));
saveStatement.setString(13, (String) dataCollected.get("key_eight"));
saveStatement.setString(14, (String) dataCollected.get("key_nine"));
saveStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
问题是,当我在foreach
循环中使用此方法时,我可以正确地看到并获得key
和值
,但当我向数据库发送查询时,创建了记录,但除了位置2,3和5('wh','pc','un')之外,所有值都是null
。
有人能让我知道我的代码有什么问题吗? 或者可能是其他一些问题,与代码无关? 我毫无头绪,任何建议都将不胜感激。
在执行UPDATE调用后,这段代码正确地“关闭”了连接,这就是您看到新行的原因。
您观察到值(几乎)全部为空这一事实只能说明一件事。
DataCollected.get("KEY_ONE“)
返回NULL。 您正在打印输入映射中的值,但是您确实看到了'KEY_ONE'。
也许关键是“key_one”
(注意空格!),或者看起来(差不多?) 与“key_one”完全相同,但不等于“key_one”。 在大多数字体中,有些符号看起来和这些字母一模一样,但却不是那个字母。 例如,o
有一大堆看起来非常非常相似的符号。 还有零宽度的空格字符和其他创造性的空白,你不会在println语句中看到。
下面是调试代码的方法:
>
使用断点,或者只是添加一个sysout语句,在打开任何db连接之前,在方法的最顶端打印get调用的结果:system.out.println(datacollected.get(“key_one”));
-应该为null,这毫无疑问地表明,无论您认为使用foreach循环打印键时看到了什么,“key_one”
都不在映射中。
然后,要查看映射中的key_one-esque键是什么,循环遍历其中的每个键,并打印每个符号的char值:
public void debugString(String in) {
System.out.print(in);
System.out.print(": ");
for (char c : in.toCharArray()) {
System.out.print((int) c);
System.out.print(" ");
}
System.out.println();
}
。。。然后在保存方法的顶部:
debugString("key_one"); // see what a 'real' key_one looks like
for (String key : dataCollected.keySet()) {
debugString(key); // now debug-print each key
}
很可能这将通过给出不同的数字序列来显示问题。 找到其中的区别,抓一张ascii图表或unicode表,然后查找哪里不稳定。
例如,如果第一次打印显示第4个数字是95
,但键的第4个数字是818
,则键正在使用这个替代下划线字符,该字符看起来完全或几乎完全像下划线,但它不是同一个字符,因此,.get("key_one“)
将找不到它。
可能这是LinkedHashMap的某个子类的实例(或者不是java.util.LinkedHashMap
,它已损坏。请通过打印:System.out.println(DataCollected.getClass())
进行检查。这应该打印java.util.LinkedHashMap
-如果没有,则值得进一步研究。
使用hacks和reflection使字符串(通常是不可变的)包含不同的字符是可能的,但很棘手,当您尝试打印它时,您会看到这些字符。 除了故意搞乱代码之外,没有任何理由去做这样的事情。 如果是这样的话,找到那个恶作剧的人,告诉他们别再胡闹了。