日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

[JAVA EE] JPA 查询用法:自定义查询,分页查询

發布時間:2023/11/27 生活经验 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [JAVA EE] JPA 查询用法:自定义查询,分页查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目已上傳:https://codechina.csdn.net/qq_36286039/javaee

自定義查詢

問題:內置的crud功能不滿足需求時如何添加自定義查詢?

幾種自定義查詢方法

  1. 方法命名規則查詢
  • 按照 JPA 定義的規則,查詢方法以 find|read|get 開頭(比如 find、findBy、read、readBy、get、getBy),涉及條件查詢時,條件的屬性用條件關鍵字連接,
  • 注意:條件屬性首字母需大寫。
  • JPA 框架在進行方法名解析時,會先把方法名多余的前綴截取掉,然后對
    剩下部分進行解析,最后會自動創建查詢。
  • 示例:
  • findByUsernameAndPassword(String name, String pwd)
  • findByUsernameLike(String name)

詳細的方法命名規則


  1. JPQL 查詢 – JPA Query Language
  • JPQL和SQL很像,查詢關鍵字都是一樣的,主要區別是:JPQL 是面向對象的,是針對實體類進行的操作,即將數據庫表名、列名等信息替換為實體類對象及其屬性(區分大小寫)。
  • JPQL 語句可以是 select 語句、update 語句或 delete 語句。
  • 常用 @Query 注解。

JPQL 示例

@Transactional 是聲明式事務管理編程中使用的注解.
涉及到數據修改操作,可以使用 @Modifying 注解, @Query 與 @Modifying 這兩個 annotation一起聲明,可定義個性化更新操作

  • 示例1:查詢所有
@Query("select u from User u")
public List<User> findAllUser();
  • 示例2:條件查詢
@Query("select u from User u where u.id = ?1")
//或 
@Query("select u from User u where u.id = :id")
public User getUserById(long id);
  • 示例3:update操作
@Transactional
@Modifying
@Query("update User u set u.username = ?1 where u.id = ?2")
int updateUsernameById(String username, Long id);

  1. 原生 SQL 查詢
  • 使用 @Query 注解,value參數寫SQL語句,nativeQuery參數為 true。
  • 示例1:
@Query(value = "select * from user where id = ?1", nativeQuery = true)
public User getUserById2(Long id);
  • 示例2:
@Transactional
@Modifying
@Query(value="update user set username = ?1 where id = ?2", nativeQuery = true)
int updateUsernameById2(String username, Long id);

實操演練:

方法命名規則查詢示例

UserRepository.java里添加

	// 只需按JPA指定規則寫出方法名即可,JPA會自動生成 SQL (太強大了)// 方法名常見規則:findByXX, countByXX XX為屬性名,例如:public User findByUsername(String username); //根據username精確查找public List<User> findByUsernameLike(String s); //查詢username中包含s串的user,需要手工加%public List<User> findByUsernameContaining(String s); //查詢username中包含s串的user,無需加%public List<User> findByRegdateAfter(Date mydate); //查詢在mydate日期之后注冊的userpublic Long countByUsernameContaining(String s); //count是統計查詢結果的總數public List<User> findByIdLessThanEqualOrderByUsernameDesc(Long id);//查詢id值小于等于某個值,且按username降序排序

新建一個TestController.java

說明:
3L其實就是3。
java中經常會碰到“long c = 1L”的寫法,L表示long ,long占用8個字節,表示范圍:-9223372036854775808 ~ 9223372036854775807
常量后面跟這個一般是指類型,1L表示1是長整型,如果是1f 表示是float型

package com.example.jpademo2.controller;import com.example.jpademo2.entity.User;
import com.example.jpademo2.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;@RestController
public class TestController {@Autowiredprivate UserRepository userRepository;@RequestMapping("/testuser1")public User test1() {User user = userRepository.findByUsername("admin");return user;}//查找username包含"m"串的用戶@RequestMapping("/testuser2")public List<User> test2() {//需要手動添加“%”List<User> users = userRepository.findByUsernameLike("%m%");return users;}//查找username包含"m"串的用戶@RequestMapping("/testuser3")public List<User> test3() {List<User> users = userRepository.findByUsernameContaining("m");return users;}//查詢在mydate日期之后注冊的user@RequestMapping("/testuser4")public List<User> test4() throws ParseException {SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date myDate = df.parse("2020-10-1 23:59:59");List<User> users = userRepository.findByRegdateAfter(myDate);return users;}//統計username包含"m"的用戶個數@RequestMapping("/testuser5")public Long test5() {return userRepository.countByUsernameContaining("m");}//查詢id值小于等于3L,且按username降序排序@RequestMapping("/testuser6")public List<User> test6() {List<User> users = userRepository.findByIdLessThanEqualOrderByUsernameDesc(3L);return users;}
}

用postman測試一下
當前數據庫:

http://localhost:8080/testuser1:找admin

http://localhost:8080/testuser2:找用戶名包含m的用戶
http://localhost:8080/testuser3:找用戶名包含m的用戶


http://localhost:8080/testuser4:找Mydate之后注冊的用戶

http://localhost:8080/testuser5:統計username包含"m"的用戶個數(2個)

http://localhost:8080/testuser6:查詢id值小于等于3L,且按username降序排序


JPQL 查詢示例

在UserRepository.java 中添加

//JPQL 查詢示例@Transactional@Modifying@Query("update User u set u.username = ?1 where u.id = ?2")int updateUsernameById(String username, Long id);@Query(value = "select * from user where id = ?1", nativeQuery = true)public User getUserById2(long id);@Transactional@Modifying@Query(value="update user set username = ?1 where id = ?2", nativeQuery = true)int updateUsernameById2(String username, Long id);

在TestController.java中添加

	//找所有@RequestMapping("/testuser7")public List<User> test7() {List<User> users = userRepository.findAllUser();return users;}//找id為2的User@RequestMapping("/testuser8")public User test8() {User user = userRepository.getUserById(2L);return user;}//更新Id為2的username@RequestMapping("/testuser9")public int test9() {int count= userRepository.updateUsernameById("dustId2",2L);return count;}

使用postman測試:


username被修改了之后在試試

原生 SQL 查詢示例

UserRepository.java 中添加

	//原生SQL查詢示例@Query(value = "select * from user where id = ?1", nativeQuery = true)public User getUserById2(long id);@Transactional@Modifying@Query(value="update user set username = ?1 where id = ?2", nativeQuery = true)int updateUsernameById2(String username, Integer id);

TestController里添加

	//找id為2的User@RequestMapping("/testuser10")public User test10() {return userRepository.getUserById2(2L);}//更新Id為2的username@RequestMapping("/testuser11")public int test11() {int count= userRepository.updateUsernameById2("dust@qq.com",2);return count;}

使用postman測試:



分頁查詢

  • JPA 在查詢的方法中傳入參數 Pageable 對象 來實現分頁功能,通過該參數可得到和分頁相關的所有信息。
  • 有多個參數時,Pageable 作為最后一個參數

page:第幾頁,從0開始,默認為第0頁
size:每一頁的大小,默認為20
sort:排序方式

  • Pageable 對象創建方法 :
    • Pageable pageable = PageRequest.of( page, size, sort );
    • sort定義示例:按 id 升序排序
      Sort sort = Sort.by(Sort.Direction.ASC, "id");
  • 查詢方法返回 Page ,可以得到數據的總體信息(如數據總數、總頁數
    等)以及當前頁數據的信息(當前數據的集合、當前頁數等):
  • Page 對象相關方法
方法名功能
List getContent();將所有數據返回為List
boolean hasContent();返回數據是否有內容。
int getNumber()當前第幾頁(從0開始),總是非負的
int getTotalPages()返回分頁總數
long getTotalElements()返回元素總數
boolean hasPreviousPage()如果有上一頁。
boolean hasNextPage()如果有下一頁
boolean isFirstPage()當前頁是否為第一頁。
boolean isLastPage()當前頁是否為最后一頁。
int getSize()返回當前頁面的大小。
Sort getSort()返回頁的排序參數。
int getNumberOfElements()返回當前頁上的元素數。

分頁查詢示例:

UserRepository.java中添加:

	//自定義分頁查詢//import org.springframework.data.domain.Page;//import org.springframework.data.domain.Pageable;//這里很容易引入錯誤的包public Page<User> findAllBy(Pageable pageable);//在查詢的方法中傳入 Pageable 參數public Page<User> findByUsernameContaining(String username,Pageable pageable);//有多個參數時,Pageable 作為最后一個參數

TestController.java中添加:

	@RequestMapping("/testuser12")public Page<User> test12() {Sort sort = Sort.by(Sort.Direction.ASC, "id"); //id升序排序Pageable pageable = PageRequest.of( 0, 10, sort ); // 第0頁,每一頁10個Page<User> page = userRepository.findAll( pageable );return page; //返回結果見下頁}@RequestMapping("/testuser13")public List<User> test13() {Sort sort = Sort.by(Sort.Direction.DESC, "username"); //username降序排序Pageable pageable = PageRequest.of( 0, 10, sort ); // 第0頁,每一頁10個Page<User> page = userRepository.findAll( pageable );List<User> list = page.getContent(); //得到 List 數據return list; //返回List<User>}

分頁查詢示例2:

服務層:UserService 接口層

package com.example.jpademo2.service;import com.example.jpademo2.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;import java.util.List;//服務層接口
public interface UserService {//根據也無需要定義業務功能接口方法public List<User> getUserList();public User findUserById(Long id);public void save(User user);public void edit(User user);public void delete(Long id);// 添加兩個分頁業務功能接口public Page<User> getUserList(Pageable pageable);public Page<User> getUserListByUsername(String username,Pageable pageable);
}

服務層:UserServiceImp 實現

package com.example.jpademo2.service;import com.example.jpademo2.entity.User;
import com.example.jpademo2.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;import java.util.List;//實現服務層接口
@Service
public class UserServiceImp implements UserService{@Autowiredprivate UserRepository userRepository;@Overridepublic List<User> getUserList(){return userRepository.findAll();//直接調用Repository內置的CURD方法}@Overridepublic User findUserById(Long id){return userRepository.findById(id).get();//直接調用Repository內置的CURD方法//findById(id)返回的是Optional類(一個可以為null的容器對象)//如果Optional容器中存在對象,則調用get()方法返回該對象}@Overridepublic void edit(User user){userRepository.save(user);//直接調用Repository內置的CURD方法}@Overridepublic void save(User user){userRepository.save(user);//直接調用Repository內置的CURD方法}@Overridepublic void delete(Long id){userRepository.deleteById(id);//直接調用Repository內置的CURD方法}// 實現兩個分頁業務@Overridepublic Page<User> getUserList(Pageable pageable) {return userRepository.findAll(pageable);}@Overridepublic Page<User> getUserListByUsername(String username,Pageable pageable) {return userRepository.findByUsernameContaining(username,pageable);}}

控制器層:修改的 list 方法

參數說明:實際傳遞的只有 page,size這兩個參數。model和request為系統參數
用了 session 存儲"return_url"

@RequestMapping("/list")public String list(Model model, HttpServletRequest request, @RequestParam(value="page",defaultValue="0")Integer page, @RequestParam(value="size", defaultValue="5")Integer size) {if (page==null || page<=0) { page = 1; } // 將第0頁轉換為習慣的第1頁if (size==null || size<=0) { size = 5; }Sort sort = Sort.by(Sort.Direction.ASC, "id"); // 排序字段是實體類的屬性Pageable pageable = PageRequest.of(page - 1, size, sort); // (當前頁,每頁記錄數,排序方式)Page<User> users = userService.getUserList(pageable);model.addAttribute("users", users);model.addAttribute("size", size);request.getSession().setAttribute("return_url", request.getServletPath()+"?"+request.getQueryString());//新建編輯刪除中返回的urlreturn "user/list";}

視圖層:修改 list.html

說明:后臺傳來的 users 是 Page<User>通過 getContent() 可得到 List<User>

<tr th:each="user : ${ users.getContent() }">
<!--添加分頁,放在 table 標簽后-->
<div th:replace="/common/page :: page1"></div>

修改 add.html、edit.html、delete.html 的所有 “返回” 鏈接

將原來的 th:href = "@{/list}" 全部修改為th:href = "@{${session.return_url}}"

<a th:href = "@{${session.return_url}}">返回</a>

fragement布局視圖:page.html

在 templates 中新建 common 目錄,并創建 page.html。

page.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Page</title>
</head>
<body>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="container" th:fragment="page1"><div style="text-align: right;"><div>當前第<span th:text="${users.getNumber()} + 1"></span>頁 /總<span th:text="${users.getTotalPages()}"></span>頁共<span th:text="${users.getTotalElements()}"></span>條記錄<a class="btn btn-info" th:href="@{/list(page=1,size=${size})}">首頁</a><a class="btn btn-info"th:href="@{/list(page = ${users.hasPrevious()} ? ${users.getNumber()} : 1,size=${size})}">上一頁</a><a class="btn btn-info"th:href="@{/list(page = ${users.hasNext()} ? ${users.getNumber()} + 2 : ${users.getTotalPages()},size=${size})}">下一頁</a><a class="btn btn-info" th:href="@{/list(page = ${users.getTotalPages()},size=${size})}">尾頁</a></div></div>
</div>
</body>
</html>
</body>
</html>

運行結果:

總結

以上是生活随笔為你收集整理的[JAVA EE] JPA 查询用法:自定义查询,分页查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。