Search code examples
javaspring-restcontroller

How to use query params to filter the data?


Assume an entity Person with the following fields:

@Id
@GeneratedValue(startegy = GenerationType.IDENTITY)
int id;
String name;
String surname;
int age;

On the controller, I want the endpoint to be customizable with query parameters so that it can handle every type of combination:

/api/controller?name=John

/api/controller?surname=Doe

/api/controller?name=John&age=33&surname=Doe

Of course, I'd rather avoid having to manually type all combinations. I found that using @Spec you can define something like this:

@Spec(
path = "sample",
params = { "name", "age", "surname" },
spec = //I don't know what is this
)

But this doesn't seem to handle all combinations, rather I have to put them together myself. Defining one spec for each field seems to work, but again that doesn't handle combinations.

What am I missing? How can I achieve this?

EDIT: I've found out about QueryDSL, but I can't seem to import it into my project. I've added the following dependencies to my pom:

<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <scope>provided</scope>
</dependency>

I'm using Spring 2.3.3.RELEASE

EDIT: I have fixed the dependencies, however, upon launching the app I get the following exception:

java.lang.IllegalArgumentException: Did not find a query class net.mydom.net.entity.QUser for domain class net.mydom.net.entity.User!

This is my user entity:

@Entity
@Table(name = "users")
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String id;

    @Column(name = "enterprise_id")
    private String enterpriseID;

    private String username;
    private String name;
    private String password;
    private Short rol;
    private Short status;
    private String language;
    private String email;
    private Date lastLogin;
    private String image;
}


Solution

  • I found a solution using DslQuery

    pom.xml

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
    </dependency>
    
    <plugin>
        <groupId>com.mysema.maven</groupId>
        <artifactId>apt-maven-plugin</artifactId>
        <version>1.1.3</version>
        <executions>
            <execution>
                <goals>
                    <goal>process</goal>
                </goals>
                <configuration>
                    <outputDirectory>target/generated-sources/java</outputDirectory>
                    <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    UserRepository.java

    public interface UserRepository extends JpaRepository<User, String>,
        QuerydslPredicateExecutor<User> {
    
    }
    

    UserController.java

    @GetMapping("/dsl")
    public List<User> getUserDsl( @QuerydslPredicate(root = User.class) Predicate predicate) {
        return service.getUsersDsl(predicate);
    }
    

    UserService.java

    public List<User> getUsersDsl(Predicate predicate) {
        List<User> actualList = new ArrayList<>();
    
        Iterable<User> iterable = repository.findAll(predicate);
        iterable.forEach(actualList::add);
        return actualList;
    }