Fix jpa criteria and specification test

This commit is contained in:
DOHA 2015-01-25 18:49:55 +02:00
parent 4ad6cc93f2
commit 34ae3b72ce
10 changed files with 157 additions and 106 deletions

View File

@ -1,12 +1,12 @@
package org.baeldung.persistence.dao;
import java.util.List;
import java.util.Map;
import org.baeldung.persistence.model.User;
import org.baeldung.web.util.SearchCriteria;
public interface IUserDAO {
List<User> searchUser(Map<String, Object> params);
List<User> searchUser(List<SearchCriteria> params);
void save(User entity);
}

View File

@ -1,7 +1,6 @@
package org.baeldung.persistence.dao;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@ -11,6 +10,7 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.baeldung.persistence.model.User;
import org.baeldung.web.util.SearchCriteria;
import org.springframework.stereotype.Repository;
@Repository
@ -20,19 +20,24 @@ public class UserDAO implements IUserDAO {
private EntityManager entityManager;
@Override
public List<User> searchUser(final Map<String, Object> params) {
public List<User> searchUser(final List<SearchCriteria> params) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<User> query = builder.createQuery(User.class);
final Root r = query.from(User.class);
Predicate predicate = builder.conjunction();
for (final Map.Entry<String, Object> param: params.entrySet()){
if (param.getKey().equalsIgnoreCase("age")) {
predicate = builder.and(predicate, builder.greaterThanOrEqualTo(r.get(param.getKey()), Integer.parseInt(param.getValue().toString())));
}
else{
predicate = builder.and(predicate, builder.like(r.get(param.getKey()), "%" + param.getValue() + "%"));
for (final SearchCriteria param : params) {
if (param.getOperation().equalsIgnoreCase(">")) {
predicate = builder.and(predicate, builder.greaterThanOrEqualTo(r.get(param.getKey()), param.getValue().toString()));
} else if (param.getOperation().equalsIgnoreCase("<")) {
predicate = builder.and(predicate, builder.lessThanOrEqualTo(r.get(param.getKey()), param.getValue().toString()));
} else if (param.getOperation().equalsIgnoreCase(":")) {
if (r.get(param.getKey()).getJavaType() == String.class) {
predicate = builder.and(predicate, builder.like(r.get(param.getKey()), "%" + param.getValue() + "%"));
} else {
predicate = builder.and(predicate, builder.equal(r.get(param.getKey()), param.getValue()));
}
}
}
query.where(predicate);

View File

@ -0,0 +1,49 @@
package org.baeldung.persistence.dao;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.baeldung.persistence.model.User;
import org.baeldung.web.util.SearchCriteria;
import org.springframework.data.jpa.domain.Specification;
public class UserSpecification implements Specification<User> {
private SearchCriteria criteria;
public UserSpecification() {
}
public UserSpecification(final SearchCriteria criteria) {
super();
this.criteria = criteria;
}
public SearchCriteria getCriteria() {
return criteria;
}
public void setCriteria(final SearchCriteria criteria) {
this.criteria = criteria;
}
@Override
public Predicate toPredicate(final Root<User> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) {
if (criteria.getOperation().equalsIgnoreCase(">")) {
return builder.greaterThanOrEqualTo(root.<String> get(criteria.getKey()), criteria.getValue().toString());
} else if (criteria.getOperation().equalsIgnoreCase("<")) {
return builder.lessThanOrEqualTo(root.<String> get(criteria.getKey()), criteria.getValue().toString());
} else if (criteria.getOperation().equalsIgnoreCase(":")) {
if (root.get(criteria.getKey()).getJavaType() == String.class) {
return builder.like(root.<String>get(criteria.getKey()), "%" + criteria.getValue() + "%");
} else {
return builder.equal(root.get(criteria.getKey()), criteria.getValue());
}
}
return null;
}
}

View File

@ -1,45 +0,0 @@
package org.baeldung.persistence.dao;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.model.User_;
import org.springframework.data.jpa.domain.Specification;
public class UserSpecifications {
public static Specification<User> firstNameIsLike(final String term) {
return new Specification<User>() {
@Override
public Predicate toPredicate(final Root<User> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.like(root.get(User_.firstName), "%"+term+"%");
}
};
}
public static Specification<User> lastNameIsLike(final String term) {
return new Specification<User>() {
@Override
public Predicate toPredicate(final Root<User> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.like(root.get(User_.lastName), "%" + term + "%");
}
};
}
public static Specification<User> ageIsGreaterThan(final int minAge) {
return new Specification<User>() {
@Override
public Predicate toPredicate(final Root<User> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.greaterThanOrEqualTo(root.get(User_.age), minAge);
}
};
}
}

View File

@ -1,36 +1,23 @@
package org.baeldung.persistence.dao;
import static org.baeldung.persistence.dao.UserSpecifications.ageIsGreaterThan;
import static org.baeldung.persistence.dao.UserSpecifications.firstNameIsLike;
import static org.baeldung.persistence.dao.UserSpecifications.lastNameIsLike;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.baeldung.persistence.model.User;
import org.baeldung.web.util.SearchCriteria;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
public class UserSpecificationsBuilder {
public static Specification<User> buildUserSpecs(final Map<String, Object> params) {
public static Specification<User> buildUserSpecs(final List<SearchCriteria> params) {
if (params.size() == 0)
return null;
final List<Specification<User>> specs = new ArrayList<Specification<User>>();
String key, value;
for (final Map.Entry<String, Object> param : params.entrySet()) {
key = param.getKey();
value = param.getValue().toString();
if (key.equalsIgnoreCase("age")) {
specs.add(ageIsGreaterThan(Integer.parseInt(value)));
} else if (key.equalsIgnoreCase("firstName")) {
specs.add(firstNameIsLike(value));
} else if (key.equalsIgnoreCase("lastName")) {
specs.add(lastNameIsLike(value));
}
for (final SearchCriteria param : params) {
specs.add(new UserSpecification(param));
}
if (specs.size() == 0)

View File

@ -1,12 +1,12 @@
package org.baeldung.persistence.service.impl;
import java.util.List;
import java.util.Map;
import org.baeldung.persistence.dao.IUserDAO;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.dao.UserSpecificationsBuilder;
import org.baeldung.persistence.model.User;
import org.baeldung.web.util.SearchCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
@ -29,11 +29,11 @@ public class UserService {
dao.save(user);
}
public List<User> searchUser(final Map<String, Object> params) {
public List<User> searchUser(final List<SearchCriteria> params) {
return dao.searchUser(params);
}
public List<User> searchBySpecification(final Map<String, Object> params) {
public List<User> searchBySpecification(final List<SearchCriteria> params) {
final Specification<User> spec = UserSpecificationsBuilder.buildUserSpecs(params);
if (spec == null)
return repository.findAll();

View File

@ -1,5 +1,6 @@
package org.baeldung.web.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -10,6 +11,7 @@ import org.baeldung.persistence.model.MyUser;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.service.impl.MyUserService;
import org.baeldung.persistence.service.impl.UserService;
import org.baeldung.web.util.SearchCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -33,13 +35,13 @@ public class UserController {
@RequestMapping(method = RequestMethod.GET, value = "/users")
@ResponseBody
public List<User> findAll(@RequestParam(value = "search", required = false) final String search) {
final Map<String, Object> params = new HashMap<String, Object>();
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
if (search != null) {
final Pattern pattern = Pattern.compile("(\\w+?):(\\w+?),");
final Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
final Matcher matcher = pattern.matcher(search + ",");
while (matcher.find()) {
params.put(matcher.group(1), matcher.group(2));
params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
}
}
return service.searchUser(params);
@ -48,13 +50,13 @@ public class UserController {
@RequestMapping(method = RequestMethod.GET, value = "/users/spec")
@ResponseBody
public List<User> findAllBySpecification(@RequestParam(value = "search", required = false) final String search) {
final Map<String, Object> params = new HashMap<String, Object>();
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
if (search != null) {
final Pattern pattern = Pattern.compile("(\\w+?):(\\w+?),");
final Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
final Matcher matcher = pattern.matcher(search + ",");
while (matcher.find()) {
params.put(matcher.group(1), matcher.group(2));
params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
}
}
return service.searchBySpecification(params);

View File

@ -0,0 +1,44 @@
package org.baeldung.web.util;
public class SearchCriteria {
private String key;
private String operation;
private Object value;
public SearchCriteria() {
}
public SearchCriteria(final String key, final String operation, final Object value) {
super();
this.key = key;
this.operation = operation;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
public String getOperation() {
return operation;
}
public void setOperation(final String operation) {
this.operation = operation;
}
public Object getValue() {
return value;
}
public void setValue(final Object value) {
this.value = value;
}
}

View File

@ -2,13 +2,13 @@ package org.baeldung.persistence.query;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.service.impl.UserService;
import org.baeldung.spring.PersistenceConfig;
import org.baeldung.web.util.SearchCriteria;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -51,9 +51,9 @@ public class JPACriteriaQueryTest {
@Test
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
final Map<String, Object> params = new HashMap<String, Object>();
params.put("firstName", "John");
params.put("lastName", "Doe");
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("firstName", ":", "John"));
params.add(new SearchCriteria("lastName", ":", "Doe"));
final List<User> result = userService.searchUser(params);
@ -63,8 +63,8 @@ public class JPACriteriaQueryTest {
@Test
public void givenLast_whenGettingListOfUsers_thenCorrect() {
final Map<String, Object> params = new HashMap<String, Object>();
params.put("lastName", "doe");
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("lastName", ":", "Doe"));
final List<User> result = userService.searchUser(params);
assertEquals(2, result.size());
@ -72,9 +72,9 @@ public class JPACriteriaQueryTest {
@Test
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
final Map<String, Object> params = new HashMap<String, Object>();
params.put("lastName", "doe");
params.put("age", "25");
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("lastName", ":", "Doe"));
params.add(new SearchCriteria("age", ">", "25"));
final List<User> result = userService.searchUser(params);
@ -84,9 +84,9 @@ public class JPACriteriaQueryTest {
@Test
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
final Map<String, Object> params = new HashMap<String, Object>();
params.put("firstName", "Adam");
params.put("lastName", "Fox");
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("firstName", ":", "Adam"));
params.add(new SearchCriteria("lastName", ":", "Fox"));
final List<User> result = userService.searchUser(params);
assertEquals(0, result.size());
@ -94,12 +94,12 @@ public class JPACriteriaQueryTest {
@Test
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
final Map<String, Object> params = new HashMap<String, Object>();
params.put("firstName", "jo");
final List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("firstName", ":", "jo"));
final List<User> result = userService.searchUser(params);
assertEquals(1, result.size());
assertEquals(userJohn.getEmail(), result.get(0).getEmail());
}
}
}

View File

@ -1,15 +1,14 @@
package org.baeldung.persistence.query;
import static org.baeldung.persistence.dao.UserSpecifications.ageIsGreaterThan;
import static org.baeldung.persistence.dao.UserSpecifications.firstNameIsLike;
import static org.baeldung.persistence.dao.UserSpecifications.lastNameIsLike;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.dao.UserSpecification;
import org.baeldung.persistence.model.User;
import org.baeldung.spring.PersistenceConfig;
import org.baeldung.web.util.SearchCriteria;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -53,13 +52,17 @@ public class JPASpecificationsTest {
@Test
public void givenLast_whenGettingListOfUsers_thenCorrect() {
final List<User> result = repository.findAll(lastNameIsLike("doe"));
final UserSpecification spec = new UserSpecification(new SearchCriteria("lastName", ":", "doe"));
final List<User> result = repository.findAll(spec);
assertEquals(2, result.size());
}
@Test
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
final List<User> result = repository.findAll(Specifications.where(lastNameIsLike("doe")).and(firstNameIsLike("john")));
final UserSpecification spec = new UserSpecification(new SearchCriteria("firstName", ":", "john"));
final UserSpecification spec1 = new UserSpecification(new SearchCriteria("lastName", ":", "doe"));
final List<User> result = repository.findAll(Specifications.where(spec).and(spec1));
assertEquals(1, result.size());
assertEquals(userJohn.getEmail(), result.get(0).getEmail());
@ -67,7 +70,9 @@ public class JPASpecificationsTest {
@Test
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
final List<User> result = repository.findAll(Specifications.where(lastNameIsLike("doe")).and(ageIsGreaterThan(25)));
final UserSpecification spec = new UserSpecification(new SearchCriteria("age", ">", "25"));
final UserSpecification spec1 = new UserSpecification(new SearchCriteria("lastName", ":", "doe"));
final List<User> result = repository.findAll(Specifications.where(spec).and(spec1));
assertEquals(1, result.size());
assertEquals(userTom.getEmail(), result.get(0).getEmail());
@ -75,15 +80,19 @@ public class JPASpecificationsTest {
@Test
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
final List<User> result = repository.findAll(Specifications.where(lastNameIsLike("Adam")).and(firstNameIsLike("Fox")));
final UserSpecification spec = new UserSpecification(new SearchCriteria("firstName", ":", "Adam"));
final UserSpecification spec1 = new UserSpecification(new SearchCriteria("lastName", ":", "Fox"));
final List<User> result = repository.findAll(Specifications.where(spec).and(spec1));
assertEquals(0, result.size());
}
@Test
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
final List<User> result = repository.findAll(firstNameIsLike("jo"));
final UserSpecification spec = new UserSpecification(new SearchCriteria("firstName", ":", "jo"));
final List<User> result = repository.findAll(spec);
assertEquals(1, result.size());
assertEquals(userJohn.getEmail(), result.get(0).getEmail());
}
}
}