![](/img/trans.png)
[英]How to write a Conditional Custom Query in Spring boot Crud Repository
[英]How to parse json in Spring Boot and write to a repository
我正在尝试使用可能的数千行来解析历史时间序列数据的JSON API响应。 响应采用以下格式:
{
"name": "AAPL",
"history": {
"2019-03-05": {
"open": "175.94",
"close": "175.53",
"high": "176.00",
"low": "174.54",
"volume": "19163899"
},
"2019-03-04": {
"open": "175.69",
"close": "175.85",
"high": "177.75",
"low": "173.97",
"volume": "27436203"
}
}
}
我想将响应写到Spring存储库。 我有一个简单的代码可以做到这一点,下面显示了一个部分:
RestTemplate restTemplate = new RestTemplate();
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = (JsonObject) jsonParser.parse(result);
JsonElement jsonElement = jsonObject.get("history");
Set<Map.Entry<String, JsonElement>> entrySet = jsonElement.getAsJsonObject().entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
StockHistory stockHistory = new StockHistory();
stockHistory.setSymbol(stk);
// .... Other code
}
我根据JSON响应设置对象属性,将对象添加到列表中,最后将列表保存到存储库中。 据推测,此过程非常缓慢,因为我正在为JSON返回中的每个元素创建一个新的StockHistory
对象。 我想知道是否有更好的方法。
由于您无法修改JSON结构。 我想添加以下代码,这些代码可以解析您在名为Repo
的简单类中提供的JSON。 为此,您需要从这里使用我添加的库 。
现在,您需要在代码中添加以下类。
public class Repo {
public String name;
public ArrayList<History> histories;
public Repo() {
histories = new ArrayList<History>();
}
}
public class History {
public String date;
public HistoryElements elements;
}
public class HistoryElements {
public String volume;
public String high;
public String low;
public String close;
public String open;
}
因此,我编写了一个RepoParser
并使用您的JSON字符串对其进行了测试,它将JSON解析为类。
import com.oracle.javafx.jmx.json.JSONException;
import org.json.JSONObject;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
public class RepoParser {
public static Repo parseRepo(String jsonString) throws ParseException, JSONException {
JSONObject jsonObject = new JSONObject(jsonString);
Iterator<?> iterator = jsonObject.keys();
Repo repo = new Repo();
while (iterator.hasNext()) {
String obj = iterator.next().toString();
if (obj.equals("name")) repo.name = obj;
else repo.histories = parseHistory((JSONObject) jsonObject.get(obj));
}
return repo;
}
public static ArrayList<History> parseHistory(JSONObject jsonObject) throws ParseException, JSONException {
Iterator<?> iterator = jsonObject.keys();
ArrayList<History> historyList = new ArrayList<>();
while (iterator.hasNext()) {
String obj = iterator.next().toString();
History history = new History();
history.date = obj;
history.elements = parseHistoryElement((JSONObject) jsonObject.get(obj));
historyList.add(history);
}
return historyList;
}
public static HistoryElements parseHistoryElement(JSONObject jsonObject) throws ParseException, JSONException {
Iterator<?> iterator = jsonObject.keys();
HistoryElements historyElements = new HistoryElements();
while (iterator.hasNext()) {
String obj = iterator.next().toString();
if (obj.equals("open")) historyElements.open = jsonObject.getString("open");
if (obj.equals("close")) historyElements.close = jsonObject.getString("close");
if (obj.equals("high")) historyElements.high = jsonObject.getString("high");
if (obj.equals("low")) historyElements.low = jsonObject.getString("low");
if (obj.equals("volume")) historyElements.volume = jsonObject.getString("volume");
}
return historyElements;
}
}
只需使用RepoParser
类,如下所示。
try {
Repo repo = RepoParser.parseRepo(jsonString);
} catch (Exception e) {
e.printStackTrace();
}
为方便起见,我也创建了一个Gist 。
更新资料
您可能会考虑将所有的Repo
列表中,然后所有的人都保存到数据库中一次使用save
库的方法。
因此,代码应类似于以下内容。
try {
while(there is no repo left for parsing) {
Repo repo = RepoParser.parseRepo(jsonString);
repoList.add(repo)
}
yourRepository.save(repoList); // Save all values at once
} catch (Exception e) {
e.printStackTrace();
}
希望有帮助!
经过研究,我发现问题出在休眠状态。 据我了解,hibernate的一个有用功能是它可以缓存对象,但是当创建大量用于插入的对象时,这会引起问题。 可以通过使用spring.jpa.properties.hibernate.jdbc.batch_size属性并在实体类中使用序列生成器进行批处理来解决此问题。 现在保存成千上万行的列表要快得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.