您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Spring data jpa @query使用原生SQl時(shí)需要注意的問(wèn)題”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
Spring data jpa @Query 使用原生Sql的坑
根據(jù)代碼來(lái)解說(shuō):
需要注意的方法有以下幾點(diǎn)
SpringData JPA @Query動(dòng)態(tài)SQL語(yǔ)句
思路
實(shí)現(xiàn)
@Query(value = "select bill.id_ as id, bill.created_date as date, bill.no, lawyer_case .case_no as caseNo, " + "lawyer_case .case_name as caseName, customer.no as customerNo, customer.cn_name as customerName, " + "bill.total_expense_after_tax, bill.collected_money, bill.book_ticket_amount, bill.version " + "e1.name as creator, bill.status" + "from bill " + "left join lawyer_case on lawyer_case .case_no=bill.case_no " + "left join customer on customer.no=bill.customer_no " + "left join employee e1 on e1.id_=bill.creator " + "where IF (?1!='', customer_no=?1, 1=1) " + "and IF (?2!='', case_no=?2, 1=1) " + "and IF (?3!='', status=?3, 1=1) " + "and IF (?4!='', creator'%',?4,'%')), 1=1) " + "and create_by=?5 " + "ORDER BY ?#{#pageable} ", countQuery = "select count(*) " + "from bill " + "left join lawyer_case on lawyer_case .case_no=bill.case_no " + "left join customer on customer.no=bill.customer_no " + "left join employee e1 on e1.id_=bill.creator " + "where IF (?1!='', customer_no=?1, 1=1) " + "and IF (?2!='', case_no=?2, 1=1) " + "and IF (?3!='', status=?3, 1=1) " + "and IF (?4!='', creator'%',?4,'%')), 1=1) " + "and create_by=?5 "+ "ORDER BY ?#{#pageable} ", nativeQuery = true) Page<Object[]> findAllBill(String customerNo, String caseNo, Integer status, String creator, String createBy, Pageable pageable);
1、From 不支持重命名.
2、返回的是一個(gè)page<Object[]>,數(shù)組中只保存了數(shù)據(jù),沒(méi)有對(duì)應(yīng)的key,只能根據(jù)返回?cái)?shù)據(jù)的順序,依次注入到DTO中。
3、對(duì)于使用分頁(yè),需要:“ORDER BY ?#{#pageable}”,可以直接傳入一個(gè)pageable對(duì)象,會(huì)自動(dòng)解析。
4、注意格式問(wèn)題,很多時(shí)候就是換行的時(shí)候,沒(méi)有空格。
5、仔細(xì)對(duì)應(yīng)數(shù)據(jù)庫(kù)中表字段,很多時(shí)候報(bào)某個(gè)字段找不到,就是因?yàn)樽侄蚊麑?xiě)錯(cuò),和數(shù)據(jù)庫(kù)中對(duì)應(yīng)不上。
6、這是解決使用微服務(wù),大量的數(shù)據(jù)都需要遠(yuǎn)程調(diào)用,會(huì)降低程序的性能。
7、使用Pageabel作為參數(shù)的時(shí)候,去進(jìn)行分頁(yè)。剛開(kāi)始的時(shí)候,覺(jué)得還是一個(gè)可行的辦法,但是得注意的時(shí)候,當(dāng)需要排序的時(shí)候,是無(wú)法加入sort字段的。 會(huì)一直報(bào)錯(cuò)left*。
8、針對(duì)7的解決方案,把原生SQL的數(shù)據(jù)查詢(xún)和countQuery分成兩個(gè)查詢(xún)方法。得到count,然后進(jìn)行判斷,若是等于0,則直接返回空集合;反之,則取獲取數(shù)據(jù)。 需要自己進(jìn)行分頁(yè)計(jì)算,傳入正確的pageNumber和pageSize。
大部分系統(tǒng)都是按照修改時(shí)間進(jìn)行降序排序。 所以,order by可以寫(xiě)死。然后pageNumber和pageSize動(dòng)態(tài)傳入。
pageNumber的算法= (pageNumber - 1) * pageSize, 前提是PageNumber是從1開(kāi)始,若0,則pageNumber=pageNumber * PageSize; 這樣就可以保證數(shù)據(jù)的正確。
/** * pageInfos: 轉(zhuǎn)換之后的數(shù)據(jù)。 * pageable:傳入的pageable. * totalPage: 第一條SQL算好的返回值。 * 這樣就可以統(tǒng)一的返回各種pageDTO。 */ private Page<T> convertForPage(List<T> pageInfos, Pageable pageable, Integer totalPage) { return new PageImpl<>(pageInfos, pageable, totalPage); }
這次有個(gè)需求,需要?jiǎng)討B(tài)的sql語(yǔ)句去查詢(xún),但是@Query正常情況下SQL語(yǔ)句是寫(xiě)死的,在查找了很多資料后,想到了一個(gè)好的解決辦法
利用MYSQL的判斷來(lái)拼接SQL語(yǔ)句
先上代碼
@Query(value = "select * from project_demand where project_id=?1 and if(?2!='',demand_id in (select demand_id from demand_user where user_id=?2),1=1)",nativeQuery = true) List<ProjectDemand> getListByUser(String projectId,String userId);
紅色部分,就是生成動(dòng)態(tài)SQL的方法,利用MYSQL的if函數(shù)和我們傳遞的參數(shù)去進(jìn)行判斷,然后獲取SQL語(yǔ)句。
“Spring data jpa @query使用原生SQl時(shí)需要注意的問(wèn)題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。