简体   繁体   中英

Spring boot Get request with multiple optional params using QuerySL

I am trying to create a GET endpoint in spring with multiple Optional Request parameters to query data from mongo (think and query) and return it.

What I have so far- MyController.java

@GetMapping
    public ResponseEntity<Iterable<Item>> searchItem(@RequestParam Map<String, Optional<String>> requestParams){
            List<Item> items = itemService.findItem(requestParams);
            return (new ResponseEntity<>(Item, HttpStatus.Ok));

    }

@GetMapping
    public ResponseEntity<Iterable<Item>> getAllItems(){
        Iterable<Item> items= itemService.listItems();
        return (new ResponseEntity<>(items, HttpStatus.OK));
    }

Heres my service layer-

@Override
    public List<Item> findItem(Map<String,Optional<String>> params) {
        QItem qItem = QItem.item;
        BooleanBuilder builder = new BooleanBuilder();
        params.forEach( (String key, Optional<String> value) -> {
            if(value.isPresent()) {
                builder.and(qUser.key.eq(value.get()));
            }
        });
        List<Item> items = itemRepository.findAll(builder);
        return resultItems;
    }

    @Override
    public Iterable<Item> listItems() {
        List<Item> items = userRepository.findAll();
        return items;
    }


If it isn't apparent already, I am struggling to build the predicate using booleanBuilder and pass it to the repository layer. The key in the map will contain the name of the QItems required field name.

Also how do I resolve the 2 GET Mappings for get all users and get by parameter? I can make a GET request -> /item to retrieve all items or I can make a GET request with params to query by parameters -> /item?param1=value1&param2=value2

For your first question you can use Expression.stringPath() method to get full path of parameter from root object as following,

 @Override
    public List<Item> findItem(Map<String,Optional<String>> params) {
        QItem qItem = QItem.item;
        BooleanBuilder builder = new BooleanBuilder();
        params.forEach( (String key, Optional<String> value) -> {
            if(value.isPresent()) {
               StringPath column = Expressions.stringPath(qItem, key);
               builder.and(column.eq(value));
            }
        });
        List<Item> items = itemRepository.findAll(builder);
        return resultItems;
    }

For your second clarification, it's based on your choice but you can do both in a single GetMapping by adding some condition for checking whether your params map empty or not,

If empty -> call itemRepository.findAll(),

else -> call itemRepository.findAll(builder)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM