0

I want to search something from database example i have three textfields First Name , Last Name and Gender if i input there Some Firstname , Some Lastname , Male I want to search all the people with that certain name and gender and display it how do I do this? Note: I am just new to Spring and just started learning thanks

Controller:

  @RequestMapping(value = "/student/search", method = RequestMethod.GET)
  public String searchStudent(@Param("name") String name, @Param("type") String type, Map<String, Object> model) {
    Map<String, String> params = new HashMap<String, String>();
    params.put("name", name);
    params.put("type", gender);
    model.put("students",studentRepository.findAll(StudentSpecification.search(params)));
    return "/students/list";
  }
}

Specification:

 public static Specification<Student> search(final Map<String, String> params) {
    return (root, query, criteriaBuilder) -> {
      List<Predicate> predicates = new ArrayList<Predicate>();

      params.forEach((k, v) -> {
        if (StringUtils.equals(k, "name")) {
          if (StringUtils.isNotBlank(v)) {
            Predicate hasFirstName =
                criteriaBuilder.like(root.join("user").<String>get("firstName"), "%" + v + "%");
            Predicate hasLastName =
                criteriaBuilder.like(root.join("user").<String>get("lastName"), "%" + v + "%");
            predicates.add(criteriaBuilder.or(hasFirstName, hasLastName));
          }
        }
      });

      return criteriaBuilder.and(predicates.toArray(new Predicate[] {}));
    };

  }

}

2 Answers 2

2

I presume from your code that you are using Spring data jpa, with specification, right? if so, you need to generate MetaModel of your entities, add the code below if you are using maven, and this will do it for you

     <plugin>
            <groupId>org.bsc.maven</groupId>
            <artifactId>maven-processor-plugin</artifactId>
            <version>2.0.5</version>
            <executions>
                <execution>
                    <id>process</id>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <phase>generate-sources</phase>
                    <configuration>
                        <processors>
                             <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                        </processors>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.hibernate</groupId>
                    <artifactId>hibernate-jpamodelgen</artifactId>
                    <version>4.3.6.Final</version>
                </dependency>
            </dependencies>
        </plugin> 

I suppose you have an entity called Student, this plugin declaration will generate a classe suffixed with underscore 'Student_'

and then you could implement the specification interface, something like this

 public class StudentSpecification {

    public static Specification<Student> search(final Map<String, String> params) {

        return new Specification<Student>() {
           @Override
           public Predicate toPredicate(Root<Student> studentRoot,   CriteriaQuery<?> query, CriteriaBuilder cb) {
            Predicate res = null;


            if(params.containKey("name"))
            res = cb.equal(studentRoot.get(Student_.name), params.get("name"));

            if(params.containKey("type"))
                if(res ==null)
                    res = cb.equal(studentRoot.get(Student_.name), params.get("type"));
                else
                    res = cb.and(res, cb.equal(studentRoot.get(Student_.name), params.get("type")));

           return res;
        }

    }
}

and of course your StudentRepository class should extends JpaSpecificationExecutor, something like this

interface StudentRepository extends  JpaSpecificationExecutor<Student> {
 }
Sign up to request clarification or add additional context in comments.

2 Comments

thanks i tried to use another code in specification but its not working can you help me with it ? see edited
What doesn't work exactly for you? could you post mapping between "user" and "student" entities?
0

You can do this using @Query, add method in the repository:

@Query("SELECT e FROM STUDENT e WHERE e.name = ?1 AND e.type = ?2")
public List<student> findAll(String name, String type);

Use that method in the controller:

@RequestMapping(value = "/student/search", method = RequestMethod.GET)
public String searchStudent(@Param("name") String name, @Param("type") String type, Map<String, Object> model) {
       model.put("students",studentRepository.findAll(name, type));
       return "/students/list";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.