java用spring-data-mongodb操作mongodb的时间问题
来源:互联网 发布:网络卖彩票会坐牢吗 编辑:程序博客网 时间:2024/05/16 11:06
最近项目用到了mongodb,做了个时间段查询,自己调试的时候,发现把时间放到查询条件类QueryBuilder中之后就会自动向前推8小时。。纠结了好几天,终于找到答案,这里跟大家分享一下,希望大家会避免。
先贴出主要代码:
// 构建查询条件QueryBuilder queryBuilder = new QueryBuilder();Date startDate = DateUtil.fromStringToDate("yyyy-MM-dd HH:mm:ss", "2017-01-07 10:00:00");queryBuilder.put("createTime").greaterThanEquals(startDate);// 要查询的字段BasicDBObject fieldsObject = new BasicDBObject();fieldsObject.put("name", 1);fieldsObject.put("age", 1);fieldsObject.put("createTime", 1);// 执行查询Query query = new BasicQuery(queryBuilder.get(), fieldsObject);List<Map> list = mongoTemplate.find(query, Map.class, COLLECTION);
当queryBuilder.put(“createTime”).greaterThanEquals(startDate);执行之后,debug调试查看queryBuilder会发现startDate的值向前推了8小时,百度了半天发现是时区的问题,可是也没有具体解答,只好看源码跟进问题。
一开始以为是QueryBuilder的greaterThanEquals等方法做了时区的转换,于是找出来greaterThanEquals方法的源码:
public QueryBuilder greaterThanEquals(Object object) { addOperand(QueryOperators.GTE, object); return this; } //里面做了一个addOperand方法,我们看addOperand的源码 private void addOperand(String op, Object value) { if(op == null) { if (_hasNot) { value = new BasicDBObject(QueryOperators.NOT, value); _hasNot = false; } // 这里预警,put之后_query里的时间就变了 _query.put(_currentKey, value); return; } Object storedValue = _query.get(_currentKey); BasicDBObject operand; if(!(storedValue instanceof DBObject)) { operand = new BasicDBObject(); if (_hasNot) { DBObject notOperand = new BasicDBObject(QueryOperators.NOT, operand); _query.put(_currentKey, notOperand); _hasNot = false; } else { _query.put(_currentKey, operand); } } else { operand = (BasicDBObject)_query.get(_currentKey); if (operand.get(QueryOperators.NOT) != null) { operand = (BasicDBObject) operand.get(QueryOperators.NOT); } } operand.put(op, value); }
源码跟进来之后,发现是 _query.put(_currentKey, value);这句之后时间就会变,大家看图,我们先看传进去的时间,2017年01月10日10点整,如下图:
再来看put之后的_query值,下图:
可以看到,变成了2017年1月7日2点,于是又把问题放到了_query上面,看他的put里干了什么,我们要知道_query是什么类型。继续看源码:
public QueryBuilder() { _query = new BasicDBObject(); }
初始化的时候创建了BasicDBObject对象,继续到BasicDBObject中看put方法,如下:
public class BasicBSONObject extends LinkedHashMap<String,Object> implements BSONObject { ... public Object put( String key , Object val ){ return super.put( key , val ); } ...}
到这也不用看了,发现put方法是直接用的父类,点进去是HashMap类的put方法。。。到这线索没了,已疯。。。左思右想,spring-data-mongo肯定不会这么坑,一定是我的打开方式不对,于是想先往BasicDBObject中put个时间值,再把他get出来,看看get出来的值还改变吗,结果get出来的值没有向前推8小时,没有没有没有。
为了进一步证实调用数据库查询时用的是我们传进去的时间,还是向前推8小时之后的时间,我在mongodb中插入一条时间为2017-01-10 10:00:00的数据,然后在java中传2017-01-10 10:00:00这个时间条件进行查询,可以看到put之后仍然变成了2017-01-10 02:00:00,可是查询结果确实是查到了时间为2017-01-10 10:00:00的数据。
可以看到,这与我们的期望值一致,可是中间出了些问题,纠结了一段时间,突然想到会不会是toString的时候把时区改了呢,导致打印和显示的时候出来的是格林时间,事实证明真的是这样,BasicDBObject在toString方法中有个处理java.util.Date的地方,把时区设置成了格林时间,如下图:
现在我该说什么。。我们眼睛看到的,未必是真实的。。。
至此,时间的问题就分析完了,分享给大家,希望大家以后遇到不要绕弯路~第一次写博客,有点紧张~有什么不对欢迎指正~~
- java用spring-data-mongodb操作mongodb的时间问题
- java 操作mongoDB(DBobject,非spring data)
- 通过使用spring-data-mongodb操作mongodb
- spring data mongodb的Converter问题
- Spring Data MongoDB 级联操作
- 使用Spring Data操作mongoDB
- Spring Data MongoDB基本操作
- java操作Mongodb,Spring-data-mongo简单配置
- 使用Spring Data MongoDB 做聚合操作出现的问题及解决方案
- spring-data-mongodb 对于collection的upsert操作
- MongoDB学习笔记(三)使用Spring Data操作MongoDB
- 使用Spring Data来操作MongoDB
- 使用Spring Data来操作MongoDB
- Spring Data MongoDB 二:添加、删除操作
- Spring Data MongoDB 二:添加、删除操作
- java操作MongoDB遇到的一些问题
- Java 访问 MongoDB (使用Spring-Data-MongoDB)
- MongoDB的Java操作
- 安卓 动画效果 Animation
- How to become a proficient Python programmer
- shared_ptr的线程安全性分析
- pat-bl-1050
- QSS编辑预览工具
- java用spring-data-mongodb操作mongodb的时间问题
- 375. Guess Number Higher or Lower II
- PAT TEST 甲级1005. Spell It Right (20)
- PAT TEST甲级1006. Sign In and Sign Out (25)
- 使用MFC操作Word(使用模板)
- 共享onload事件(addLoadEvent函数)
- 设计模式-From Jason McDonald
- Activiti工作流引擎——用户与组、部署管理
- [模板] 斜率优化Dp详解