springDataJpa入門教程(4)-Example單表動態條件查詢+分頁

springDataJpa入門教程(4)-Example單表動態條件查詢+分頁

這節來講下怎麼使用springDataJpa實現簡單的單表動態條件查詢+分頁,下面以springDataJpa提供的Example來講解單表動態條件查詢+分頁。源碼地址:源碼下載地址。java學習交流羣:184998348,歡迎大家一起交流學習。

  1. 用到的實體類是User類,下面這個類的代碼:
package com.thizgroup.jpa.study.model;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "tb_user")
@Data//使用lombok生成getter、setter
@NoArgsConstructor//生成無參構造方法
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(name = "name",columnDefinition = "varchar(64)")
  private String name;

  @Column(name = "mobile",columnDefinition = "varchar(64)")
  private String mobile;

  @Column(name = "email",columnDefinition = "varchar(64)")
  private String email;

  @Column(name = "age",columnDefinition = "smallint(64)")
  private Integer age;

  @Column(name = "birthday",columnDefinition = "timestamp")
  private Date birthday;

  //地址
  @Column(name = "address_id",columnDefinition = "bigint(20)")
  private Long addressId;

  @Column(name = "create_date",columnDefinition = "timestamp")
  private Date createDate;

  @Column(name = "modify_date",columnDefinition = "timestamp")
  private Date modifyDate;

  @Builder(toBuilder = true)
  public User(Long id,String name, String mobile, String email, Integer age, Date birthday,
      Long addressId) {
    this.id = id;
    this.name = name;
    this.mobile = mobile;
    this.email = email;
    this.age = age;
    this.birthday = birthday;
    this.addressId = addressId;
  }
}

下面,在IUserService中添加一個查詢方法,

package com.thizgroup.jpa.study.service;

import com.thizgroup.jpa.study.model.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

/**
 * 用戶服務
 */
public interface IUserService {
  /**
   * example單表動態條件分頁查詢
   */
  Page<User> findUserListByPage(User user,Pageable pageable);
}

然後在UserServiceImpl類中實現這個方法,

package com.thizgroup.jpa.study.service.impl;

import com.thizgroup.jpa.study.dao.UserDao;
import com.thizgroup.jpa.study.dao.UserRepository;
import com.thizgroup.jpa.study.dto.AddressDTO;
import com.thizgroup.jpa.study.dto.PageRecord;
import com.thizgroup.jpa.study.dto.UserDTO;
import com.thizgroup.jpa.study.dto.UserProjection;
import com.thizgroup.jpa.study.model.User;
import com.thizgroup.jpa.study.service.IUserService;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

@Service
@Transactional(readOnly = false,propagation = Propagation.REQUIRED)
public class UserServiceImpl implements IUserService {

  @Autowired
  private UserRepository userRepository;

   @Override
  public Page<User> findUserListByPage(User user, Pageable pageable) {

    Example<User> example = Example.of(user,
        ////模糊查詢匹配開頭,即{name}%
        ExampleMatcher.matching().withMatcher("name",ExampleMatcher.GenericPropertyMatchers.startsWith())
            //是否包含某個字符串 email like ‘%’ + ?0 + ‘%’
        .withMatcher("email",ExampleMatcher.GenericPropertyMatchers.contains())
            //按照年齡精確查詢
        .withMatcher("age",ExampleMatcher.GenericPropertyMatchers.exact()));
    return userRepository.findAll(example,pageable);
  }
}

此外,ExampleMatcher.GenericPropertyMatcher還提供了其他的查詢條件,整理如下:

方法 描述
ignoreCase 忽略大小寫
caseSensitive 大小寫敏感
endsWith 以什麼結尾
exact 精確查詢
contains 是否包含某個字符串
startsWith 以什麼開始
regex 使用正則表達式匹配

不幸的是,即使開發人員最初認爲支持正則表達式(因爲存在上述枚舉常量),Spring實際上目前不支持它們——並且根據相關JILA問題的討論,它永遠不會:HTTPS://JIRA.SpRIP.IO/BROSESE/DATAJPA-944

下面寫個單元測試驗證上面的代碼:

package com.thizgroup.jpa.study.service;

import com.thizgroup.jpa.study.JpaApplication;
import com.thizgroup.jpa.study.model.User;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@SpringBootTest(classes={JpaApplication.class})
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional(readOnly = false,propagation = Propagation.REQUIRED)
public class UserServiceImplTest {

  @Autowired
  private IUserService userService;
  
  @Test
  public void findUserListByPage3Test() throws Exception{
    User u = new User();
    u.setName("張");
    u.setEmail("@qq.com");
    u.setAge(35);
    //注意:jpa的分頁是從0開始的
    Page<User> pageList = userService.findUserListByPage(u, PageRequest.of(0, 15));
    System.out.println("分頁信息:");
    System.out.println("總記錄數:"+pageList.getTotalElements()+",總頁數:"+pageList.getTotalPages());
    System.out.println("頁碼:"+(pageList.getNumber()+1)+",每頁條數:"+pageList.getSize());
    List<User> content = pageList.getContent();
    content = null == content? new ArrayList<>() : content;
    content.forEach(user->System.out.println(user));
  }
}

運行上面的單元測試,結果如下:

分頁信息:
總記錄數:1,總頁數:1
頁碼:1,每頁條數:15
User(id=1, name=張三, mobile=156989989, email=hu@qq.com, age=35, birthday=2008-09-16 08:00:00.0, addressId=11, createDate=2019-08-06 05:50:01.0, modifyDate=2019-08-08 05:46:11.0)

如果需要詳細瞭解Example查詢,推薦這篇文章:Spring Data JPA 實例查詢.

至此,springDataJpa Example單表動態條件查詢+分頁就介紹完了,有需要源碼的朋友,請到git上下載源碼,源碼地址:https://github.com/hgq0916/springdatajpa-study.git。java學習交流羣:184998348,歡迎大家一起交流學習。

上一篇:springDataJpa入門教程(3)-基於EntityManager原生sql多表聯合查詢+動態條件查詢+分頁
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章