使用RSQL實(shí)現(xiàn)端到端的動(dòng)態(tài)查詢

本文主要研究一下如何使用RSQL實(shí)現(xiàn)從前端到后端的動(dòng)態(tài)數(shù)據(jù)查詢。

RSQL

RSQL(RESTful Service Query Language)是Feed Item Query Language (FIQL) 的超集,是一種RESTful服務(wù)的查詢語(yǔ)言。這里我們使用rsql-jpa來(lái)實(shí)踐,它依賴rsql-parser來(lái)解析RSQL語(yǔ)法,然后將解析后的RSQL轉(zhuǎn)義到JPA的Specification。

maven

<dependency>
    <groupId>com.github.tennaito</groupId>
    <artifactId>rsql-jpa</artifactId>
    <version>2.0.2</version>
</dependency>

它依賴了rsql-parser

實(shí)例

domain

@Entity
public class TodoTask {

    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private Long totalNum = 0L;

    private String title;

    @Version
    private Long version;

    //...
}    

controller

@RestController
@RequestMapping("/rsql")
public class RsqlController {

    @Autowired
    TodoTaskService todoTaskService;

    /**
     * @param condition
     * @param page
     * @param size
     * @return
     */
    @GetMapping("")
    public Page<TodoTask> query(@RequestParam String condition,
                                @RequestParam(required = false,defaultValue = "0") int page,
                                @RequestParam(required = false,defaultValue = "20") int size){
        return todoTaskService.query(condition,new PageRequest(page,size));
    }
}

service

@Component
public class TodoTaskService {

    @Autowired
    private EntityManager entityManager;

    public Page<TodoTask> query(String condition, Pageable pageable){
        // 1.Create the JPA Visitor
        RSQLVisitor<CriteriaQuery<TodoTask>, EntityManager> visitor = new JpaCriteriaQueryVisitor<TodoTask>();
        // 2.Parse a RSQL into a Node
        Node rootNode = new RSQLParser().parse(condition);
        // 3.Create CriteriaQuery
        CriteriaQuery<TodoTask> criteriaQuery = rootNode.accept(visitor, entityManager);
        List<TodoTask> total = entityManager.createQuery(criteriaQuery).getResultList();
        List<TodoTask> resultList = entityManager.createQuery(criteriaQuery)
                .setFirstResult(pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList();

        return new PageImpl<>(resultList,pageable, total.size());
    }
}

這里直接使用EntityManager來(lái)查詢,總共分三步,1是創(chuàng)建RSQLVisitor,2是解析condition到Node,3是根據(jù)node創(chuàng)建CriteriaQuery,然后就可以根據(jù)CriteriaQuery來(lái)查詢了。

運(yùn)行

curl -i http://localhost:8080/rsql?condition=title==hello
curl -i http://localhost:8080/rsql?condition=totalNum%3E50
curl -i http://localhost:8080/rsql?condition=totalNum%3E50;title==hello

其中%3E是>的url轉(zhuǎn)義,如果有多個(gè)and條件,用;分隔

小結(jié)

RSQL是一種強(qiáng)大抽象的語(yǔ)言,可以用來(lái)做REST服務(wù)的通用查詢語(yǔ)言,spring-data-rest也提供了類(lèi)似的功能,功能更為強(qiáng)大。不過(guò)這種貌似不支持or查詢,另外數(shù)據(jù)量大的時(shí)候,直接走db查詢可能造成慢查詢,因?yàn)椴⒉皇撬凶侄味加兴饕贿^(guò)對(duì)于走elasticsearch來(lái)說(shuō),還是比較合適的。

doc

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容