Ale*_*exM 5 java json mongodb mongodb-java
我有一个代码可以从 MongoDB 读取特定格式的数据。我需要测试一下。
为此,我使用要测试的数据创建了一个 JSON:
{
"id": ObjectId("57552e32e4b0839ede67e0af"),
"serial" : 574000690,
"startDate" : ISODate("2016-08-22T23:01:56.000Z"),
"endDate" : ISODate("2016-10-22T22:01:56.000Z"),
"reason": ""
}
Run Code Online (Sandbox Code Playgroud)
这是应该创建的对象:
public static class MyObject implements Serializable{
private String id;
private long serial;
private Date startDate;
private Date endDate;
private String reason;
}
Run Code Online (Sandbox Code Playgroud)
我有一个读取 JSON 文件并创建 Mongo 文档并写入数据库的代码:
List<Document> docs = dirAsDbObjects(dir + File.separator +
subDir.getName()).collect(Collectors.toList());
docs.forEach(docManipulator);
docs.forEach(doc -> doc.putIfAbsent("_id", new ObjectId()));
ret.addAll(docs);
MongoDatabase db = mongoClient.getDatabase(dbName);
MongoCollection<Document> coll = db.getCollection(subDir.getName());
List<InsertOneModel<Document>> inserts = docs.stream().map(InsertOneModel::new).collect(Collectors.toList());
coll.bulkWrite(inserts);
Run Code Online (Sandbox Code Playgroud)
写入数据后,有一段代码会尝试从 MongoDB 读取数据并将其填充到MyObject实例中:
public MyObject(Document doc) {
id = doc.getObjectId(DBConstants.ID).toString();
serial = doc.getLong(DBConstants.SERIAL);
startDate = doc.getDate("startDate");
reason = doc.getString("source");
}
Run Code Online (Sandbox Code Playgroud)
在错误消息上失败:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
Run Code Online (Sandbox Code Playgroud)
因为行serial = doc.getLong(DBConstants.SERIAL);。它基本上从我的 JSON 中获取数字为“整数”,因此无法读取它那么长时间。
我尝试了以下行,并且有效:
Long.parseLong(doc.get(DBConstants.SERIAL).toString())
Run Code Online (Sandbox Code Playgroud)
但这是最好的解决方案吗?请问.toString()总是让我一个数字的字符串表示?有没有办法在 JSON 中保留一个数字,使其被读取为Long?
更新:
@glytching 给出了一个很好的答案!
我还发现了另一种方法,显然,如果您将 JSON 的数字元素包装在NumberLong其中,它将被解析为Long从 Mongo 文档翻译时。
因此,使用旧代码,我能够通过像这样更改我的 JSON 来使其工作:
{
"id": ObjectId("57552e32e4b0839ede67e0af"),
"serial" : NumberLong(574000690),
"startDate" : ISODate("2016-08-22T23:01:56.000Z"),
"endDate" : ISODate("2016-10-22T22:01:56.000Z"),
"reason": ""
}
Run Code Online (Sandbox Code Playgroud)
Mongo Java 驱动程序已确定 的值serial可以“适合” INT32,因此将其视为此类。当您调用时,doc.getLong()您要求驱动程序将其 Integer 转换为 Long,因此类转换为异常。如果,例如,价值serial为2147483648(即最大整数值+ 1),然后蒙戈Java驱动程序会认为这是一个INT64,然后就可以放心地调用doc.getLong()。
因此,由于 (a) 您Long在类模型中将此属性建模为 a并且 (b) 并非此属性的每个持久值都需要存储为INT64... .
如何?好吧,只要serial属性作为某种数字(例如INT32, INT64)持久化,那么这个调用......
doc.get(DBConstants.SERIAL)
Run Code Online (Sandbox Code Playgroud)
...将始终返回一个对象,该对象是其某个子类,java.lang.Number因此强制转换为Number和使用longValue()将起作用。
例如:
serial = ((Number) doc.get(DBConstants.SERIAL)).longValue()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2074 次 |
| 最近记录: |