Spring boot Jpa高階查詢
阿新 • • 發佈:2018-11-10
前言
上一篇文章主要講了Jpa的簡單使用,而在實際專案中並不能滿足我們的需求。如對多張表的關聯查詢,以及查詢時需要的各種條件,這個時候你可以使用自定義SQL語句,但是Jpa並不希望我們這麼做,於是就有了一個擴充套件:使用 Specification 進行查詢
修改相應程式碼
1、修改User.class
程式碼用的上一章的,這裡在User類中進行擴充套件,待會查詢時會用到
@Entity
@Table(name = "user")
public class User {
//部分程式碼略
/**
* 加上該註解,在儲存該實體時,Jpa將為我們自動設定上建立時間
*/
@CreationTimestamp
private Timestamp createTime;
/**
* 加上該註解,在儲存或者修改該實體時,Jpa將為我們自動建立時間或更新日期
*/
@UpdateTimestamp
private Timestamp updateTime;
/**
* 關聯角色,測試多表查詢
*/
@ManyToOne
@JoinColumn(name = "role_id")
private Role role;
//部分程式碼略
}
2、新增Role.class
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true,nullable = false)
private String name;
//get set略
}
3、修改UserRepository
要使用Specification,需要繼承JpaSpecificationExecutor介面,修改後的程式碼如下
public interface UserRepo extends JpaRepository<User,Long>, JpaSpecificationExecutor {
}
4、檢視JpaSpecificationExecutor原始碼
Specification是Spring Data JPA提供的一個查詢規範,這裡所有的操作都是圍繞Specification來進行
public interface JpaSpecificationExecutor<T> {
Optional<T> findOne(@Nullable Specification<T> var1);
List<T> findAll(@Nullable Specification<T> var1);
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
List<T> findAll(@Nullable Specification<T> var1, Sort var2);
long count(@Nullable Specification<T> var1);
}
封裝查詢Service
我這裡簡單做了下簡單封裝,編寫UserQueryService.class
@Service
public class UserQueryService {
@Autowired
private UserRepo userRepo;
/**
* 分頁加高階查詢
*/
public Page queryAll(User user, Pageable pageable , String roleName){
return userRepo.findAll(new UserSpec(user,roleName),pageable);
}
/**
* 不分頁
*/
public List queryAll(User user){
return userRepo.findAll(new UserSpec(user));
}
class UserSpec implements Specification<User>{
private User user;
private String roleName;
public UserSpec(User user){
this.user = user;
}
public UserSpec(User user,String roleName){
this.user = user;
this.roleName = roleName;
}
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
/**
* 左連線,關聯查詢
*/
Join<Role,User> join = root.join("role",JoinType.LEFT);
if(!StringUtils.isEmpty(user.getId())){
/**
* 相等
*/
list.add(cb.equal(root.get("id").as(Long.class),user.getId()));
}
if(!StringUtils.isEmpty(user.getUsername())){
/**
* 模糊
*/
list.add(cb.like(root.get("username").as(String.class),"%"+user.getUsername()+"%"));
}
if(!StringUtils.isEmpty(roleName)){
/**
* 這裡的join.get("name"),就是對應的Role.class裡面的name
*/
list.add(cb.like(join.get("name").as(String.class),"%"+roleName+"%"));
}
if(!StringUtils.isEmpty(user.getCreateTime())){
/**
* 大於等於
*/
list.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Timestamp.class),user.getCreateTime()));
}
if(!StringUtils.isEmpty(user.getUpdateTime())){
/**
* 小於等於
*/
list.add(cb.lessThanOrEqualTo(root.get("createTime").as(Timestamp.class),user.getUpdateTime()));
}
Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p));
}
}
}
查詢測試
1、新增測試資料
@Test
public void test3() {
/**
* 新增角色
*/
Role role = new Role();
role.setName("測試角色");
role = roleRepo.save(role);
/**
* 新增並繫結角色
*/
User user = new User("小李",20,"男",role);
User user1 = new User("小花",21,"女",role);
userRepo.save(user);
userRepo.save(user1);
}
檢視資料都已經新增成功了,並且createTime和updateTime也幫我們加上了
2、簡單查詢
@Test
public void Test4(){
/**
* 新增查詢資料,模糊查詢使用者名稱
*/
User user = new User();
user.setUsername("花");
List<User> users = userQueryService.queryAll(user);
users.forEach(user1 -> {
System.out.println(user1.toString());
});
}
執行結果如下
3、分頁+關聯查詢
@Test
public void test5() {
//頁碼,Pageable中預設是從0頁開始
int page = 0;
//每頁的個數
int size = 10;
Sort sort = new Sort(Sort.Direction.DESC,"id");
Pageable pageable = PageRequest.of(page,size,sort);
Page<User> users = userQueryService.queryAll(new User(),pageable,"測試角色");
System.out.println("總資料條數:"+users.getTotalElements());
System.out.println("總頁數:"+users.getTotalPages());
System.out.println("當前頁數:"+users.getNumber());
users.forEach(user1 -> {
System.out.println(user1.toString());
});
}
}
通過角色的名稱查詢使用者,執行結果如下
專案原始碼
github:https://github.com/dqjdda/SpringBoot_All
碼雲:https://gitee.com/hgpt/SpringBoot_All
開源後臺管理系統:
歡迎體驗Aurora
github: https://github.com/dqjdda/Aurora