Skip to content

Commit 1fd87ed

Browse files
committed
DATAMONGO-1245 - Adopt QBE API refactoring.
Adopt changes from query by example API refactoring. Related ticket: DATACMNS-810.
1 parent 9e18a54 commit 1fd87ed

File tree

7 files changed

+205
-145
lines changed

7 files changed

+205
-145
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2015 the original author or authors.
2+
* Copyright 2010-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -139,6 +139,7 @@
139139
* @author Chuong Ngo
140140
* @author Christoph Strobl
141141
* @author Doménique Tilleuil
142+
* @author Mark Paluch
142143
*/
143144
@SuppressWarnings("deprecation")
144145
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
@@ -646,7 +647,7 @@ public <S extends T, T> List<T> findByExample(S sample) {
646647
public <S extends T, T> List<T> findByExample(Example<S> sample) {
647648

648649
Assert.notNull(sample, "Sample object must not be null!");
649-
return (List<T>) find(new Query(new Criteria().alike(sample)), sample.getSampleType());
650+
return (List<T>) find(new Query(new Criteria().alike(sample)), sample.getProbeType());
650651
}
651652

652653
public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java

+35-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015 the original author or authors.
2+
* Copyright 2015-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@
2424
import java.util.regex.Pattern;
2525

2626
import org.springframework.data.domain.Example;
27-
import org.springframework.data.domain.Example.NullHandler;
28-
import org.springframework.data.domain.Example.StringMatcher;
29-
import org.springframework.data.domain.PropertySpecifier;
27+
import org.springframework.data.domain.ExampleSpec;
28+
import org.springframework.data.domain.ExampleSpec.PropertyValueTransformer;
29+
import org.springframework.data.domain.ExampleSpecAccessor;
3030
import org.springframework.data.mapping.PropertyHandler;
3131
import org.springframework.data.mapping.context.MappingContext;
3232
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
@@ -41,6 +41,7 @@
4141

4242
/**
4343
* @author Christoph Strobl
44+
* @author Mark Paluch
4445
* @since 1.8
4546
*/
4647
public class MongoExampleMapper {
@@ -57,41 +58,43 @@ public MongoExampleMapper(MongoConverter converter) {
5758
/**
5859
* Returns the given {@link Example} as {@link DBObject} holding matching values extracted from
5960
* {@link Example#getProbe()}.
60-
*
61+
*
6162
* @param example
6263
* @return
6364
* @since 1.8
6465
*/
6566
public DBObject getMappedExample(Example<?> example) {
66-
return getMappedExample(example, mappingContext.getPersistentEntity(example.getSampleType()));
67+
return getMappedExample(example, mappingContext.getPersistentEntity(example.getProbeType()));
6768
}
6869

6970
/**
7071
* Returns the given {@link Example} as {@link DBObject} holding matching values extracted from
7172
* {@link Example#getProbe()}.
72-
*
73+
*
7374
* @param example
7475
* @param entity
7576
* @return
7677
* @since 1.8
7778
*/
7879
public DBObject getMappedExample(Example<?> example, MongoPersistentEntity<?> entity) {
7980

80-
DBObject reference = (DBObject) converter.convertToMongoType(example.getSampleObject());
81+
DBObject reference = (DBObject) converter.convertToMongoType(example.getProbe());
8182

82-
if (entity.hasIdProperty() && entity.getIdentifierAccessor(example.getSampleObject()).getIdentifier() == null) {
83+
if (entity.hasIdProperty() && entity.getIdentifierAccessor(example.getProbe()).getIdentifier() == null) {
8384
reference.removeField(entity.getIdProperty().getFieldName());
8485
}
8586

86-
applyPropertySpecs("", reference, example);
87+
ExampleSpecAccessor exampleSpecAccessor = ExampleSpecAccessor.of(example);
8788

88-
return ObjectUtils.nullSafeEquals(NullHandler.INCLUDE, example.getNullHandler()) ? reference : new BasicDBObject(
89-
SerializationUtils.flatMap(reference));
89+
applyPropertySpecs("", reference, example.getProbeType(), exampleSpecAccessor);
90+
91+
return ObjectUtils.nullSafeEquals(ExampleSpec.NullHandler.INCLUDE, exampleSpecAccessor.getNullHandler()) ? reference
92+
: new BasicDBObject(SerializationUtils.flatMap(reference));
9093
}
9194

92-
private String getMappedPropertyPath(String path, Example<?> example) {
95+
private String getMappedPropertyPath(String path, Class<?> probeType, ExampleSpecAccessor exampleSpecAccessor) {
9396

94-
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(example.getSampleType());
97+
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(probeType);
9598

9699
Iterator<String> parts = Arrays.asList(path.split("\\.")).iterator();
97100

@@ -136,7 +139,8 @@ public void doWithPersistentProperty(MongoPersistentProperty property) {
136139

137140
}
138141

139-
private void applyPropertySpecs(String path, DBObject source, Example<?> example) {
142+
private void applyPropertySpecs(String path, DBObject source, Class<?> probeType,
143+
ExampleSpecAccessor exampleSpecAccessor) {
140144

141145
if (!(source instanceof BasicDBObject)) {
142146
return;
@@ -155,39 +159,30 @@ private void applyPropertySpecs(String path, DBObject source, Example<?> example
155159

156160
String propertyPath = StringUtils.hasText(path) ? path + "." + entry.getKey() : entry.getKey();
157161

158-
String mappedPropertyPath = getMappedPropertyPath(propertyPath, example);
159-
if (example.isIgnoredPath(propertyPath) || example.isIgnoredPath(mappedPropertyPath)) {
162+
String mappedPropertyPath = getMappedPropertyPath(propertyPath, probeType, exampleSpecAccessor);
163+
if (exampleSpecAccessor.isIgnoredPath(propertyPath) || exampleSpecAccessor.isIgnoredPath(mappedPropertyPath)) {
160164
iter.remove();
161165
continue;
162166
}
163167

164-
PropertySpecifier specifier = null;
165-
StringMatcher stringMatcher = example.getDefaultStringMatcher();
168+
ExampleSpec.StringMatcher stringMatcher = exampleSpecAccessor.getDefaultStringMatcher();
166169
Object value = entry.getValue();
167-
boolean ignoreCase = example.isIngnoreCaseEnabled();
168-
169-
if (example.hasPropertySpecifiers()) {
170-
171-
mappedPropertyPath = example.hasPropertySpecifier(propertyPath) ? propertyPath : getMappedPropertyPath(
172-
propertyPath, example);
170+
boolean ignoreCase = exampleSpecAccessor.isIgnoreCaseEnabled();
173171

174-
specifier = example.getPropertySpecifier(mappedPropertyPath);
172+
if (exampleSpecAccessor.hasPropertySpecifiers()) {
175173

176-
if (specifier != null) {
177-
if (specifier.hasStringMatcher()) {
178-
stringMatcher = specifier.getStringMatcher();
179-
}
180-
if (specifier.getIgnoreCase() != null) {
181-
ignoreCase = specifier.getIgnoreCase();
182-
}
174+
mappedPropertyPath = exampleSpecAccessor.hasPropertySpecifier(propertyPath) ? propertyPath
175+
: getMappedPropertyPath(propertyPath, probeType, exampleSpecAccessor);
183176

184-
}
177+
stringMatcher = exampleSpecAccessor.getStringMatcherForPath(mappedPropertyPath);
178+
ignoreCase = exampleSpecAccessor.isIgnoreCaseForPath(mappedPropertyPath);
185179
}
186180

187181
// TODO: should a PropertySpecifier outrule the later on string matching?
188-
if (specifier != null) {
182+
if (exampleSpecAccessor.hasPropertySpecifier(mappedPropertyPath)) {
189183

190-
value = specifier.transformValue(value);
184+
PropertyValueTransformer valueTransformer = exampleSpecAccessor.getValueTransformerForPath(mappedPropertyPath);
185+
value = valueTransformer.convert(value);
191186
if (value == null) {
192187
iter.remove();
193188
continue;
@@ -199,16 +194,17 @@ private void applyPropertySpecs(String path, DBObject source, Example<?> example
199194
if (entry.getValue() instanceof String) {
200195
applyStringMatcher(entry, stringMatcher, ignoreCase);
201196
} else if (entry.getValue() instanceof BasicDBObject) {
202-
applyPropertySpecs(propertyPath, (BasicDBObject) entry.getValue(), example);
197+
applyPropertySpecs(propertyPath, (BasicDBObject) entry.getValue(), probeType, exampleSpecAccessor);
203198
}
204199
}
205200
}
206201

207-
private void applyStringMatcher(Map.Entry<String, Object> entry, StringMatcher stringMatcher, boolean ignoreCase) {
202+
private void applyStringMatcher(Map.Entry<String, Object> entry, ExampleSpec.StringMatcher stringMatcher,
203+
boolean ignoreCase) {
208204

209205
BasicDBObject dbo = new BasicDBObject();
210206

211-
if (ObjectUtils.nullSafeEquals(StringMatcher.DEFAULT, stringMatcher)) {
207+
if (ObjectUtils.nullSafeEquals(ExampleSpec.StringMatcher.DEFAULT, stringMatcher)) {
212208

213209
if (ignoreCase) {
214210
dbo.put("$regex", Pattern.quote((String) entry.getValue()));

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/MongoRepository.java

+20-31
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,49 @@
1919
import java.util.List;
2020

2121
import org.springframework.data.domain.Example;
22-
import org.springframework.data.domain.Page;
23-
import org.springframework.data.domain.Pageable;
2422
import org.springframework.data.domain.Sort;
2523
import org.springframework.data.repository.NoRepositoryBean;
2624
import org.springframework.data.repository.PagingAndSortingRepository;
25+
import org.springframework.data.repository.query.QueryByExampleExecutor;
2726

2827
/**
2928
* Mongo specific {@link org.springframework.data.repository.Repository} interface.
30-
*
29+
*
3130
* @author Oliver Gierke
3231
* @author Christoph Strobl
3332
* @author Thomas Darimont
33+
* @author Mark Paluch
3434
*/
3535
@NoRepositoryBean
36-
public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
36+
public interface MongoRepository<T, ID extends Serializable>
37+
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
3738

3839
/*
3940
* (non-Javadoc)
4041
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
4142
*/
43+
@Override
4244
<S extends T> List<S> save(Iterable<S> entites);
4345

4446
/*
4547
* (non-Javadoc)
4648
* @see org.springframework.data.repository.CrudRepository#findAll()
4749
*/
50+
@Override
4851
List<T> findAll();
4952

5053
/*
5154
* (non-Javadoc)
5255
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
5356
*/
57+
@Override
5458
List<T> findAll(Sort sort);
5559

5660
/**
5761
* Inserts the given a given entity. Assumes the instance to be new to be able to apply insertion optimizations. Use
5862
* the returned instance for further operations as the save operation might have changed the entity instance
5963
* completely. Prefer using {@link #save(Object)} instead to avoid the usage of store-specific API.
60-
*
64+
*
6165
* @param entity must not be {@literal null}.
6266
* @return the saved entity
6367
* @since 1.7
@@ -68,40 +72,25 @@ public interface MongoRepository<T, ID extends Serializable> extends PagingAndSo
6872
* Inserts the given entities. Assumes the given entities to have not been persisted yet and thus will optimize the
6973
* insert over a call to {@link #save(Iterable)}. Prefer using {@link #save(Iterable)} to avoid the usage of store
7074
* specific API.
71-
*
75+
*
7276
* @param entities must not be {@literal null}.
7377
* @return the saved entities
7478
* @since 1.7
7579
*/
7680
<S extends T> List<S> insert(Iterable<S> entities);
7781

78-
/**
79-
* Returns all instances of the type specified by the given {@link Example}.
80-
*
81-
* @param example must not be {@literal null}.
82-
* @return
83-
* @since 1.8
82+
/*
83+
* (non-Javadoc)
84+
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
8485
*/
85-
<S extends T> List<T> findAllByExample(Example<S> example);
86+
@Override
87+
<S extends T> List<T> findAll(Example<S> example);
8688

87-
/**
88-
* Returns all instances of the type specified by the given {@link Example}.
89-
*
90-
* @param example must not be {@literal null}.
91-
* @param sort can be {@literal null}.
92-
* @return all entities sorted by the given options
93-
* @since 1.8
89+
/*
90+
* (non-Javadoc)
91+
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
9492
*/
95-
<S extends T> List<T> findAllByExample(Example<S> example, Sort sort);
93+
@Override
94+
<S extends T> List<T> findAll(Example<S> example, Sort sort);
9695

97-
/**
98-
* Returns a {@link Page} of entities meeting the paging restriction specified by the given {@link Example} limited to
99-
* criteria provided in the {@code Pageable} object.
100-
*
101-
* @param example must not be {@literal null}.
102-
* @param pageable can be {@literal null}.
103-
* @return a {@link Page} of entities
104-
* @since 1.8
105-
*/
106-
<S extends T> Page<T> findAllByExample(Example<S> example, Pageable pageable);
10796
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java

+30-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2014 the original author or authors.
2+
* Copyright 2010-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@
4444
* @author Oliver Gierke
4545
* @author Christoph Strobl
4646
* @author Thomas Darimont
47+
* @author Mark Paluch
4748
*/
4849
public class SimpleMongoRepository<T, ID extends Serializable> implements MongoRepository<T, ID> {
4950

@@ -54,7 +55,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
5455
* Creates a new {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
5556
*
5657
* @param metadata must not be {@literal null}.
57-
* @param template must not be {@literal null}.
58+
* @param mongoOperations must not be {@literal null}.
5859
*/
5960
public SimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
6061

@@ -265,7 +266,7 @@ public <S extends T> List<S> insert(Iterable<S> entities) {
265266
* @see org.springframework.data.mongodb.repository.MongoRepository#findAllByExample(org.springframework.data.domain.Example, org.springframework.data.domain.Pageable)
266267
*/
267268
@Override
268-
public <S extends T> Page<T> findAllByExample(Example<S> example, Pageable pageable) {
269+
public <S extends T> Page<T> findAll(Example<S> example, Pageable pageable) {
269270

270271
Assert.notNull(example, "Sample must not be null!");
271272

@@ -284,7 +285,7 @@ public <S extends T> Page<T> findAllByExample(Example<S> example, Pageable pagea
284285
* @see org.springframework.data.mongodb.repository.MongoRepository#findAllByExample(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
285286
*/
286287
@Override
287-
public <S extends T> List<T> findAllByExample(Example<S> example, Sort sort) {
288+
public <S extends T> List<T> findAll(Example<S> example, Sort sort) {
288289

289290
Assert.notNull(example, "Sample must not be null!");
290291

@@ -302,7 +303,7 @@ public <S extends T> List<T> findAllByExample(Example<S> example, Sort sort) {
302303
* @see org.springframework.data.mongodb.repository.MongoRepository#findAllByExample(org.springframework.data.domain.Example)
303304
*/
304305
@Override
305-
public <S extends T> List<T> findAllByExample(Example<S> example) {
306+
public <S extends T> List<T> findAll(Example<S> example) {
306307

307308
Assert.notNull(example, "Sample must not be null!");
308309

@@ -311,6 +312,30 @@ public <S extends T> List<T> findAllByExample(Example<S> example) {
311312
return findAll(q);
312313
}
313314

315+
@Override
316+
public <S extends T> T findOne(Example<S> example) {
317+
Assert.notNull(example, "Sample must not be null!");
318+
319+
Query q = new Query(new Criteria().alike(example));
320+
return mongoOperations.findOne(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
321+
}
322+
323+
@Override
324+
public <S extends T> long count(Example<S> example) {
325+
Assert.notNull(example, "Sample must not be null!");
326+
327+
Query q = new Query(new Criteria().alike(example));
328+
return mongoOperations.count(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
329+
}
330+
331+
@Override
332+
public <S extends T> boolean exists(Example<S> example) {
333+
Assert.notNull(example, "Sample must not be null!");
334+
335+
Query q = new Query(new Criteria().alike(example));
336+
return mongoOperations.exists(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
337+
}
338+
314339
private List<T> findAll(Query query) {
315340

316341
if (query == null) {

0 commit comments

Comments
 (0)