使用Spring Data JPA開發基於JPA的資料訪問層
阿新 • • 發佈:2020-08-01
Spring Data JPA 環境搭建
參考https://www.cnblogs.com/wumingoo1/p/13414718.html
基本 CRUD
滿足基本 CRUD 的介面
- 只要讓 DAO 層介面 繼承 JpaRepository,JpaSpecificationExecutor 介面,就自動具有了很多方法,並且不用實現
- JpaRepository<操作的實體類型別,實體類中主鍵屬性的型別>:封裝了基本CRUD操作
- JpaSpecificationExecutor<操作的實體類型別>:封裝了複雜查詢(分頁)
- 注意將 介面寫在 applicationContext.xml 配置檔案中指定的包下
-
CustomerDao.java原始碼如下:
package cn.wm.dao; import cn.wm.domain.Customer; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> { }
基本 CRUD 操作測試
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class CRUDTest { @Autowired private CustomerDao customerDao; // 儲存 @Test @Transactional @Rollback(false) public void test01() { Customer c = new Customer(); c.setCustName("慕課網"); c.setCustIndustry("IT教育"); Customer save = customerDao.save(c); System.out.println(save == c); // true,且處於 Managed 狀態 save.setCustName("學堂線上"); } // 更新 【注】:find + setter 也可以實現更新 @Test @Transactional @Rollback(false) public void test02() { Customer c = new Customer(); c.setCustId(1L); c.setCustName("中國大學MOOC"); Customer save = customerDao.save(c); // save 處於 Managed 狀態,c 不處於 Managed 狀態 save.setCustName("網易雲課堂"); } // 刪除 @Test @Transactional @Rollback(false) public void test03() { customerDao.delete(15L); } // 立即查詢一個 @Test @Transactional @Rollback(false) public void test04() { Customer c1 = customerDao.findOne(1L); System.out.println("---"); System.out.println(c1); /* Hibernate: select ... --- Customer{...} */ Customer c2 = customerDao.findOne(9999L); System.out.println("---"); System.out.println(c2); /* Hibernate: select ... --- null */ } // 延遲查詢一個 @Test @Transactional @Rollback(false) public void test05() { Customer c1 = customerDao.getOne(1L); System.out.println("---"); System.out.println(c1); /* --- Hibernate: select ... Customer{...} */ Customer c2 = customerDao.getOne(9999L); System.out.println("---"); try { System.out.println(c2); } catch (EntityNotFoundException e) { System.out.println("沒查到"); } /* --- Hibernate: select ... 沒查到 */ } // 查詢所有 @Test @Transactional @Rollback(false) public void test06() { List<Customer> list = customerDao.findAll(); for (Customer c : list) { c.setCustLevel("vip"); } } // 統計查詢 @Test public void test07() { long count = customerDao.count(); System.out.println("count = " + count); } // 是否存在 @Test public void test08() { boolean exists1 = customerDao.exists(1L); System.out.println("id 為 1 的記錄存在:" + exists1); boolean exists2 = customerDao.exists(9999L); System.out.println("id 為 9999 的記錄存在:" + exists2); } }
多欄位多方式查詢
給介面新增查詢方法
基本 CRUD 裡的方法只能根據 id 欄位精確查詢,要想根據多個欄位多種查詢方式,就需要自定義介面方法。但是隻要這些介面方法的方法名和引數的型別和順序滿足要求,就可以不寫實現直接使用這些方法。
- 單一欄位精確查詢: findBy + 屬性名(首字母大寫,後面的屬性名首字母也要大寫,省略)
- 單一欄位模糊查詢: findBy + 屬性名 + Like
- 單一欄位 IsNull 查詢:findBy + 屬性名 + IsNull
- 多欄位多方式查詢:findBy + 屬性名 + 查詢方式 + 條件連線符(And | Or)屬性名 + 查詢方式... (引數順序要與屬性順序一致)
- 底層使用 JPQL 實現
-
新增的介面方法如下:
public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> { Customer findByCustName(String custName); List<Customer> findByCustNameLike(String custName); List<Customer> findByCustLevelIsNull(); List<Customer> findByCustNameLikeAndCustLevel(String custName, String custLevel); }
findBy 方法測試
@Test
@Transactional
@Rollback(false)
public void test01() {
Customer c = customerDao.findByCustName("學堂線上");
c.setCustLevel("vip");
}
@Test
@Transactional
@Rollback(false)
public void test02() {
List<Customer> list = customerDao.findByCustNameLike("網易%");
for (Customer c : list) {
c.setCustAddress("廣州");
}
}
@Test
@Transactional
@Rollback(false)
public void test03() {
List<Customer> list = customerDao.findByCustLevelIsNull();
for (Customer c : list) {
c.setCustLevel("normal");
}
}
@Test
@Transactional
@Rollback(false)
public void test04() {
List<Customer> list = customerDao.findByCustNameLikeAndCustLevel("網易%", "vip");
for (Customer c : list) {
c.setCustLevel(null);
}
}
JPQL 查詢
給介面新增查詢方法
通過 @Query 註解指定 JPQL 語句可以實現更自由的查詢、更新操作。在 CustomerDao 介面中新增如下方法:
@Query("from Customer where custName like ? and custLevel = ?")
List<Customer> findJpql(String custName, String custLevel);
@Query("update Customer set custName=?2 where custId=?1")
@Modifying
void updateCustomer(Long custId, String custName);
JPQL 方法測試
@Test
@Transactional
@Rollback(false)
public void test01() {
List<Customer> list = customerDao.findJpql("網易%", "vip");
for (Customer c : list) {
c.setCustLevel("svip");
}
}
@Test
@Transactional
@Rollback(false)
public void test02() {
customerDao.updateCustomer(1L,"中國大學MOOC");
}
SQL 查詢
給介面新增查詢方法
@Query 註解除了可以指定 JPQL 語句,還可以通過 指定 SQL 語句可以實現查詢操作,只需要讓 @Query 註解的 nativeQuery 屬性設定為 true 即可。在 CustomerDao 介面中新增如下方法:
@Query(value = "select * from cst_customer where cust_name like ? and cust_level = ?", nativeQuery = true)
List<Customer> findSql(String custName, String custLevel);
SQL 方法測試
@Test
@Transactional
@Rollback(false)
public void test01() {
List<Customer> list = customerDao.findSql("網易%", "svip");
for (Customer c : list) {
c.setCustLevel("vip");
}
}