总结在spring boot 环境下,使用RestTemplate 结合mongoTemplate对mongodb数据库的访问,包含单一条件查询和日期区间查询!
首先是从mongo中查询出想要的数据:
定义mongo数据接口:
接口定义很简单,其中关于mongo在项目中的配置,就省略了!
源码:
单条件查询单条记录:
@RequestMapping("/order/getOrderBySDKOrderId")
@ResponseBody
public Order getOrderBySDKOrderId(String id){ //通过一个第三方订单唯一id查询我方次订单的详情
Query query = new Query(); //定义query
/*
*根据 Criteria类源码看出 这个类不用new 直接调用/定义
*/
query.addCriteria(Criteria.where("sdkOrder").is(id));
// 返回类型映射到一个订单对象 mongoTemplate已经注入了
Order order = mongoTemplate.findOne(query, Order.class,
"order"+bartDateFormat.format(new Date()));
//上面这句很有意思,因为这个犯了错,最后详解
return order;
}
不难看出以上代码非常的简单,在spring里使用数据库操作类,就把这操作类的jar依赖/导入到项目,通过注解就可以注入使用了!
多过滤条件查询返回集合:
@RequestMapping("/order/getOrderBySDKnameWithIn")
@ResponseBody
public List<Order> getOrderBySDKnameWithIn(String startdate, String enddate, String sdkname){
logger.info("进入到:mongodb查询"+startdate+" ; "+enddate+" ;"+sdkname);
//接口接收的数据都为string,mongo日期查询时需要用date类型
SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
//格式化string为date,引用"java.util.Date"包
Date strdate = simp.parse(startdate);
Date endate = simp.parse(enddate);
// 下面这句就验证了-Criteria-不用new 最后总结会上源码图片
Criteria criteria = Criteria.where("time").gte(strdate).lte(endate).and("sdkname").in(sdkname);
//定义query时直接把criteria传递进去
Query query = new Query(criteria);
//我用的是区间查询 返回的是集合 //这里又出现了
List<Order> list = mongoTemplate.find(query,Order.class,"order"+bartDateFormat.format(new Date()));
logger.info("query = "+query.toString());
logger.info("list = "+list.toString());
return list;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
这样两个接口就定义好了,上面提到那那个错误是,mongo数据库集合的指定问题,我们mongo中的结构下图:
这是我在服务器中查到的mongo订单集合中的结构;注意圈起来的地方,是不是很有规律,因为是按照年月来区分集合的!所以在上面代码中,提到的问题就出在这里,当时由于对mongo的生疏,照着前人的代码写的一塌糊涂,只是理解了大概,却没有仔细研究:
这里“order”后面的代码那个是在干啥,估计也猜到了,可是我当时蒙啊!
就是给数据集合名称加后缀!
定义好数据层,开始写Controller:
我的两个数据获取都通过controller中一个接口完成的,代码截图:
上图是时间区间查询的截图;
源码:
@RequestMapping("/sdks/order/mycard/queryOrder/{game}")
@ResponseBody
public String queryOrder(@PathVariable("game") String game, HttpServletRequest request) {
String StartDateTime = request.getParameter("StartDateTime");
String EndDateTime = request.getParameter("EndDateTime");
String MyCardTradeNo = request.getParameter("MyCardTradeNo");
SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
logger.info("Mycard queryOrder game =" + game+"; StartDateTime="+StartDateTime+"; EndDateTime="+EndDateTime+"; MyCardTradeNo="+MyCardTradeNo);
/**
* Many Query
*/
if (StartDateTime != null && !StartDateTime.equals("") && EndDateTime != null && !EndDateTime.equals("")) {
logger.info("Mycard Many Query !");
String startdate = StartDateTime;
String enddate = EndDateTime;
String sdkname = "mycard";
logger.info("Many Query StartDateTime=" + startdate + "; EndDateTime=" + enddate)
;
StringBuffer strB = new StringBuffer();
List<Order> list = getOrderBySDKnameWithIn(startdate, enddate, sdkname);
if (!list.isEmpty()) {
logger.info("list="+list.toString());
for (Order order : list) {
logger.info("进入list循环 ; order.getExtra() = " + order.getExtra());
JSONObject json = new JSONObject(order.getExtra());
StringBuffer sb = new StringBuffer(json.optString("PaymentType"));
sb.append(",").append(json.optString("TradeSeq")).append(",")
.append(order.getSdkOrder()).append(",")
.append(order.getId()).append(",").append(order.getRoleId()).append(",")
.append(order.getPrice()).append(",").append(order.getCurrencyType()).append(",")
.append(simp.format(order.getTime())).append("<BR>");
logger.info("Mycard 日期中的单条:" + sb.toString());
strB.append(sb);
}
logger.info("Mycard Many Query : SUCCESS!"+"返回的串:"+strB.toString());
return strB.toString();
}
logger.info("Many Query the list == null");
return "fail";
}
接下来单条查询的代码截图:
源码:
/**
* Alone Query
*/
if (MyCardTradeNo != null && !MyCardTradeNo.equals("")) {
logger.info("Mycard Alone Query !");
Order order = getOrderBySDKOrderId(MyCardTradeNo);
if (order != null) {
logger.info("Mycard Alone Query the Order:" + order.getId());
JSONObject json = new JSONObject(order.getExtra());
logger.info("json.Extra:" + json.toString());
StringBuffer sb = new StringBuffer();
sb.append(json.optString("PaymentType")).append(",")
.append(json.optString("TradeSeq")).append(",")
.append(order.getSdkOrder()).append(",")
.append(order.getId()).append(",").append(order.getRoleId()).append(",")
.append(order.getPrice()).append(",").append(order.getCurrencyType()).append(",")
.append(simp.format(order.getTime())).append("<BR>");
logger.info("SUCCESS:" + sb.toString());
return sb.toString();
} else {
logger.info(" Order == null; Possible Reasons: MyCardTradeNo != sdkOrder");
return "fail";
}
}
logger.info("Mycard : 请求参数异常!");
return "fail";
}
定义好controller就开始一步一步调用其他类接口了!我们项目controller继承了baseController,在里面定义好方法,调用resultService!
直接上截图:
继续:
resultService源码:
public Order getOrderBySDKOrderId(String payUrl, String uid){
String url = payUrl + "/order/getOrderBySDKOrderId?id="+ uid ;
logger.info(url);
RestTemplate restTemplate = new RestTemplate();
Order order= restTemplate.getForObject(url, Order.class);
return order;
}
public List<Order> getOrderBySDKnameWithIn(String payUrl, String startdate, String enddate, String sdkname){
String url = payUrl + "/order/getOrderBySDKnameWithIn?startdate="+ startdate+"&enddate="+enddate+"&sdkname="+sdkname;
logger.info("进入到service"+url);
RestTemplate restTemplate = new RestTemplate();
List<Order> orders = restTemplate.exchange(url, HttpMethod.GET,null,new ParameterizedTypeReference<List<Order>>() {}).getBody();
logger.info("orders ="+orders.toString()+"restTemplate="+restTemplate.toString());
return orders;
}
总结:开始开发这个第三方调用的接口时,照着文档很快写好了controller!问题就卡在mongo查询那块,反复测试了好多次!虽然mongo第一次接触,但是代码不难,就是还需要认真!