代码之家  ›  专栏  ›  技术社区  ›  Tin Megali

在SpringDataMongoDB上使用JSON在MongoDB上进行日期查询

  •  0
  • Tin Megali  · 技术社区  · 7 年前

    Date @Query 上的批注 SpringDataMongoDB JHipster .

    自从 吉普斯特 用于创建项目大多数查询都是使用 Spring Data query builder mechanism Type-safe Query methods @查询 允许创建 MongoDBJSON 询问。

    但是,我不能在Json查询中引用任何类型的实体字段 LocalDate .

    this thread 没有成功。

    @Repository
    public interface CourseClassRepository extends MongoRepository<CourseClass, String> {
    
        // WORKS - query with `endDate` directly constructed by Spring Data
        // This sollution however isn't enought, since 'experience_enrollments.device_id' cannot be used as a parameter
        List<CourseClass> findAllByInstitutionIdAndEndDateIsGreaterThanEqual(Long institutionId, LocalDate dateLimit);
    
        // Using @Query to create a JSON query doesn't work.
        // apparently data parameter cannot be found. This is weird, considering that in any other @Query created the parameter is found just fine.
        // ERROR: org.bson.json.JsonParseException: Invalid JSON input. Position: 124. Character: '?'
        @Query(" { 'experience_enrollments.device_id' : ?0, 'institution_id': ?1, 'end_date': { $gte: { $date: ?2 } } } ")
        List<CourseClass> findAllByExperienceDeviceAndInstitutionIdAndEndDate(String deviceId, Long institutionId, Date dateLimit);
    
        // Adopting the stackoverflow answer mentioned above also throws an error. I belive that this error is related to the fact that '?2' is being interpreted as a String value and not as reference to a parameter
        // ERROR: org.bson.json.JsonParseException: Failed to parse string as a date
        @Query(" { 'experience_enrollments.device_id' : ?0, 'institution_id': ?1, 'end_date': { $gte: { $date: '?2' } } } ")
        List<CourseClass> findAllByExperienceDeviceAndInstitutionIdAndEndDate(String deviceId, Long institutionId, Date dateLimit);
    
        // Even hardcoding the date parameter, the query throws an error
        // ERROR: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.ZonedDateTime.
        @Query(" { 'experience_enrollments.device_id' : ?0, 'institution_id': ?1, 'end_date': { '$gte': { '$date': '2015-05-16T07:55:23.257Z' } } }")
        List<CourseClass> findAllByExperienceDeviceAndInstitutionIdAndEndDate(String deviceId, Long institutionId);
    }
    

    数据库配置

    @Configuration
    @EnableMongoRepositories("br.com.pixinside.lms.course.repository")
    @Profile("!" + JHipsterConstants.SPRING_PROFILE_CLOUD)
    @Import(value = MongoAutoConfiguration.class)
    @EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware")
    public class DatabaseConfiguration {
         @Bean
            public MongoCustomConversions customConversions() {
                List<Converter<?, ?>> converters = new ArrayList<>();
                converters.add(DateToZonedDateTimeConverter.INSTANCE);
                converters.add(ZonedDateTimeToDateConverter.INSTANCE);
                return new MongoCustomConversions(converters);
            }
    }
    

    日期转换器

        public static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
    
            public static final DateToZonedDateTimeConverter INSTANCE = new DateToZonedDateTimeConverter();
    
            private DateToZonedDateTimeConverter() {
            }
    
            @Override
            public ZonedDateTime convert(Date source) {
                return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
            }
        }
    
        public static class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
    
            public static final ZonedDateTimeToDateConverter INSTANCE = new ZonedDateTimeToDateConverter();
    
            private ZonedDateTimeToDateConverter() {
            }
    
            @Override
            public Date convert(ZonedDateTime source) {
                return source == null ? null : Date.from(source.toInstant());
            }
        }
    
    0 回复  |  直到 7 年前
        1
  •  2
  •   Tin Megali    7 年前

    Christoph Strobl bug . 所以在未来的版本 . 在那之前,我会分享我的解决方案。

    import org.springframework.data.mongodb.core.MongoTemplate;
    import static org.springframework.data.mongodb.core.query.Criteria.where;
    import static org.springframework.data.mongodb.core.query.Query.query;   
    
        @Autowired
        public MongoTemplate mongoTemplate;
    
        public List<CourseClass> findEnrolledOnExperienceDeviceWithMaxEndDateAndInstitutionId(String deviceId, LocalDate endDate, Long institutionId) {
            return mongoTemplate.find(query(
                where("experience_enrollments.device_id").is(deviceId)
                    .and("institution_id").is(institutionId)
                    .and("end_date").gte(endDate)), CourseClass.class);
        }
    
    推荐文章