springboot2.0 快速整合spring date jpa
這篇文章主要介紹如何使用spirng date jpa 稍帶腳的咱們在說說單元測試,學習新知識儘量先去看官方文件。在開說之前我們想宣告以springBoot 的版本 和spirng date jpa 的版本
springBoot:2.0.5.RELEASE
spring date jpa:2.0.10
jdk:1.8.0_144
下面就是檢視2.0.10 對應的官方文件來介紹我們的jpa
我是通過遊覽器的外掛進行翻譯的內容如下:
接下來我們進行版本文件閱讀
我們這裡不詳細介紹官方文件 只是 挑一些總要的進行介紹 。
1 搭建spirngboot jpa 基礎準備
1.1 引入spring data jpa 的start 依賴
首先我們先為我們先將spring date jpa 專案 依賴引入到springBoot 專案中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
1.2 新增springBoot 資料來源的配置
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/learn driver-class-name: com.mysql.jdbc.Driver username: root password: root # Ddl-auto : Create: 自動建立表 Update:自動修改表 Create-drop:應用停下來會把表刪除掉 None:什麼都不做 Validate:類和表明是否一致 jpa: show-sql: true hibernate: ddl-auto: update
1.3 根據jpa 規範的註解配置對映實體
新增對映實體通過jpa 規範的註解 這裡我們不做過多解釋 喜歡刨底的同學請自行搜尋相關資料
package cn.lijunkui.springbootlearn.test.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } private String sex; private String address; public User(){ } public User(Long id,String name,Integer age,String sex,String address){ this.id = id; this.name = name; this.age = age; this.address = address; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
接下來正式進行spring date jpa 程式碼編寫部分,編寫之前我們先去檢視一下文件。
2 spring data jpa 內建查詢介面
2.1 CrudRepository 使用介紹
編寫dao
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface UserCrudRepository extends CrudRepository<User,Long>{
}
你肯定會驚訝 這就完成啦,我可以確定的告訴我們的Dao 開發完畢 基本可以完成我們基本的增刪改查。
檢視原始碼我們發現他有的方法是:
<S extends T> S save(S entity);//新增
<S extends T> Iterable<S> saveAll(Iterable<S> entities);//批量新增
Optional<T> findById(ID id);//查詢通過id
boolean existsById(ID id);//id是否存在
Iterable<T> findAll();//查詢所有
Iterable<T> findAllById(Iterable<ID> ids);//查詢多個id的資料
long count();//資料的總數
void deleteById(ID id);//根據id進行刪除
void delete(T entity);//根據例項進行刪除
void deleteAll(Iterable<? extends T> entities);//批量刪除
void deleteAll();//刪除所有
SpringBoot 的單元測試 需要我們宣告@SpringBootTest 和@RunWith 註解
我們這裡只是簡單寫啦幾個測試 因為這個方法確實沒有幾個方法
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
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.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserCrudRepositoryTest {
@Autowired
private UserCrudRepository userCrudRepository;
/**
* 新增使用者 測試
*/
@Test
public void add(){
User user = new User();
user.setName("ljk2");
user.setSex("1");
user.setAge(18);
user.setAddress("beijing");
User result = userCrudRepository.save(user);
Assert.assertNotNull(result);
}
/**
* 修改使用者
*/
@Test
public void edit(){
User user = new User();
user.setId(1l);
user.setName("ljk2edit");
user.setSex("1");
user.setAge(18);
user.setAddress("beijing");
User result = userCrudRepository.save(user);
Assert.assertNotNull(result);
}
/**
* 通過id 進行查詢
*/
@Test
public void findById(){
Optional<User> userOptional = userCrudRepository.findById(1l);
User result = userOptional.get();
Assert.assertNotNull(result);
}
/**
* 查詢所有
*/
@Test
public void findAll(){
List<User> userList = (List<User>)userCrudRepository.findAll();
Assert.assertTrue(userList.size()>0);
}
@Test
public void count(){
long count = userCrudRepository.count();
System.out.println(count);
}
}
2.2 PagingAndSortRepository 使用介紹
根據文擋我們接著往下看 CrudRepository 只是具有增刪改查的一些基本功能 接下來 PagingAndSortingRepository 他是具有分頁和排序的功能 同時他繼承啦 CrudRepository
編寫測試用例:
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.hibernate.criterion.Order;
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.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserPageRepositoryTest {
@Autowired
private UserPageRepository userPageRepository;
@Test
public void findAllBySort(){
List<User> userList = (List<User>)userPageRepository.findAll(new Sort(Sort.Direction.ASC,"age"));
System.out.println(userList.size());
}
@Test
public void findAllByPageable(){
Page<User> userPage = userPageRepository.findAll(new PageRequest(0, 20));
userPage.getNumber();//頁數
userPage.getContent();//分頁的資料
userPage.getTotalPages();//總共的頁數
System.out.println("number:"+userPage.getNumber()
+"Countet"+userPage.getContent().size()
+"TotalPages"+userPage.getTotalPages());
}
}
計數查詢
我們可以定義查詢每個欄位的個數
測試通過
計數刪除
執行test 報錯 說是我們需要事物 那我們就加上事物
deleteByName 也需要我們宣告事物的註解 才能夠刪除
2.3 JpaRepository 使用介紹
JpaRepository 不僅繼承啦 PagingAndSortingRepository 同時繼承啦 QueryByExampleExecutor(示例匹配器)
通過我們的測試用例查詢期詳細的用法
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
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.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
/**
* 執行秒數:49422 49145
* 批量儲存資料
*/
@Test
public void BatchSave(){
long startTime = System.currentTimeMillis();
List<User> list = new ArrayList<User>();
for (int i = 0; i < 60000; i++) {
User user = new User();
user.setName("ljk"+i);
user.setAge(i);
user.setAddress("address"+i);
list.add(user);
if(i%100 == 0){
userJpaRepository.saveAll(list);
list.clear();
}
}
long endTime = System.currentTimeMillis();
System.out.println("執行秒數:"+ (endTime - startTime));
}
/**
* 執行秒數:48053 48394 執行速度比BatchSave 要快
* 批量儲存資料 (高效處理方式)減少大事物的提交
*/
@Test
public void BatchSaveBest(){
long startTime = System.currentTimeMillis();
List<User> list = new ArrayList<User>();
for (int i = 0; i < 60000; i++) {
User user = new User();
user.setName("ljk"+i);
list.add(user);
if(i%100 == 0){
userJpaRepository.saveAll(list);
userJpaRepository.flush();
list.clear();
}
}
long endTime = System.currentTimeMillis();
System.out.println("執行秒數:"+ (endTime - startTime));
}
/**
* 查詢所有資料
*/
@Test
public void findALL(){
List<User> userlists = userJpaRepository.findAll();
Assert.assertTrue(userlists.size() > 0);
}
/**
* 根據 age 排序查詢
*/
@Test
public void findALLSortAge(){
List<User> lists = userJpaRepository.findAll(Sort.by(Sort.Direction.ASC ,"age"));
for (User list : lists) {
System.out.println(list);
}
}
/**
* 分頁查詢
*/
@Test
public void findAllByPage(){
PageRequest pageRequest = new PageRequest(0,1);
Page<User> userPage = userJpaRepository.findAll(pageRequest);
Assert.assertTrue(userPage.getContent().size() == 1);
}
/**
* 分頁排序查詢
*/
@Test
public void findAllByPageAndSort(){
PageRequest pageRequest = new PageRequest(0,3,Sort.by(Sort.Direction.ASC ,"age"));
Page<User> userPage = userJpaRepository.findAll(pageRequest);
List<User> userList= userPage.getContent();
for (User user : userList) {
System.out.println(user);
}
}
/**
* 根據id 的集合獲取所有資料
*/
@Test
public void findAllByIds(){
List<Long> ids = new ArrayList<Long>();
ids.add(1l);
ids.add(2l);
ids.add(3l);
ids.add(4l);
List<User> userList = userJpaRepository.findAllById(ids);
Assert.assertTrue(userList.size()>0);
}
/**
* 批量刪除所有資料
*/
@Test
public void deleteAllInBatch(){
userJpaRepository.deleteAllInBatch();
}
/**
* 儲存資料並重新整理快取
*/
@Test
public void saveAndFlush(){
User user = new User();
user.setName("ljk");
user.setAge(18);
user.setAddress("beijing");
user.setSex("1");
User result = userJpaRepository.saveAndFlush(user);
Assert.assertNotNull(result);
}
/**
* 批量刪除
*/
@Test
public void deleteInBatch(){
List<User> userList = new ArrayList<User>();
User user = new User();
user.setId(1l);
userList.add(user);
User user2 = new User();
user2.setId(2l);
userList.add(user2);
User user3 = new User();
user3.setId(3l);
userList.add(user3);
User user4 = new User();
user4.setId(4l);
userList.add(user4);
userJpaRepository.deleteInBatch(userList);
}
/**
* 根據id 獲取資料 延遲載入
*/
@Test
public void getOne(){
User result = userJpaRepository.getOne(1l);
Long id = result.getId();
String name = result.getName();
System.out.println(id);
System.out.println(name);
Assert.assertNotNull(result);
}
/**
* 示例匹配器 ExampleMatcher
*/
@Test
public void findUserByExam(){
User user = new User();
user.setName("ljk");
List<User> list = userJpaRepository.findAll(Example.of(user));
System.out.println(list.size());
}
@Test
public void findUserByExamQuery(){
User user = new User();
user.setName("ljk");
user.setAddress("address8");
user.setAge(8);
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())//模糊查詢匹配開頭,即{username}%
.withMatcher("address" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查詢,即%{address}%
.withIgnorePaths("id");//忽略欄位,即不管id是什麼值都不加入查詢條件
Example<User> example = Example.of(user ,matcher);
List<User> userList = userJpaRepository.findAll(example);
Assert.assertTrue(userList.size() > 0);
}
}
3 方法名稱建立查詢
我們根據制定的規則編寫查詢方法 就像下圖所示 只需要定義個介面方法你就可以進行查詢你想要的資料
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
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.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
@Test
public void findByNameAndAge(){
List<User> userList = userJpaRepository.findByNameAndAge("ljk",18);
Assert.assertTrue( userList.size()>0 );
}
public void findByNameOrAge(){
List<User> userList = userJpaRepository.findByNameOrAge("ljk",18);
Assert.assertTrue( userList.size()>0 );
}
}
快速自定以查詢方法:示例如下
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 @Query註解查詢
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public interface UserJpaRepository extends JpaRepository<User,Long>{
/**
* 根據姓名查詢使用者
* @param name
* @return
*/
@Query("select u from User u where u.name = ?1")
public List<User> findUserByNameByQuery(String name);
/**
* 根據姓名(like)和年齡查詢使用者
* @param name
* @param age
* @return
*/
@Query("select u from User u where u.name like CONCAT('%',?1,'%') and u.age = ?2" )
public List<User> findUserByLikeNameByQuery(String name,Integer age);
/**
* 根據姓名(like)和年齡查詢使用者
* 命名引數 進行查詢
*/
@Query("select u from User u where u.name like CONCAT('%',:name,'%') and u.age = :age")
public User findUserByNameAndAgeWithQery(@Param("name") String name,@Param("age") Integer age);
/**
* 根據姓名(like)和年齡查詢使用者
* 命名引數 原生方式進行查詢
*/
@Query(value = "select * from user u where u.name like CONCAT('%',:name,'%') and u.age = :age",nativeQuery = true)
public List<User> findUserByNameAndAgeWithQeryNative(@Param("name") String name,@Param("age") Integer age);
/**
* 查詢每個地區的人的個數
* @return
*/
@Query("select new cn.lijunkui.springbootlearn.test.model.ResultDTO(u.address,count(u.id)) from User u group by u.address")
public List<ResultDTO> findCountGroupByAddress();
}
測試用例:
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
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.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
@Test
public void findUserByNameByQuery(){
List<User> userList = userJpaRepository.findUserByNameByQuery("ljk");
Assert.assertNotNull(userList.size()>0);
}
@Test
public void findUserByLikeNameByQuery(){
List<User> userList = userJpaRepository.findUserByLikeNameByQuery("jk",18);
Assert.assertNotNull(userList.size()>0);
}
@Test
public void findUserByNameAndAgeWithQery(){
User user = userJpaRepository.findUserByNameAndAgeWithQery("jk",18);
Assert.assertNotNull(user);
}
@Test
public void findUserByNameAndAgeWithQeryNative(){
List<User> userList = userJpaRepository.findUserByNameAndAgeWithQeryNative("jk",18);
Assert.assertNotNull(userList.size()>0);
}
/**
* 零散引數的接收
*/
@Test
public void findCountGroupByAddress(){
List<ResultDTO> results = userJpaRepository.findCountGroupByAddress();
System.out.println(results);
}
}