Spring Data JPA 進行持久層(即Dao)開發通常分三個步驟:html
@NoRepositoryBean public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); //保存 <S extends T> Iterable<S> save(Iterable<S> entities);//批量保存 T findOne(ID id); //根據id查詢一個對象 boolean exists(ID id); //判斷對象是否存在 Iterable<T> findAll(); //查詢全部的對象 Iterable<T> findAll(Iterable<ID> ids);//根據id列表查詢全部的對象 long count(); //計算對象的總個數 void delete(ID id); //根據id刪除 void delete(T entity); //刪除對象 void delete(Iterable<? extends T> entities);//批量刪除 void deleteAll(); //刪除全部 }
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity); //保存
<S extends T> Iterable<S> save(Iterable<S> entities);//批量保存
T findOne(ID id); //根據id查詢一個對象
boolean exists(ID id); //判斷對象是否存在
Iterable<T> findAll(); //查詢全部的對象
Iterable<T> findAll(Iterable<ID> ids);//根據id列表查詢全部的對象
long count(); //計算對象的總個數
void delete(ID id); //根據id刪除
void delete(T entity); //刪除對象
void delete(Iterable<? extends T> entities);//批量刪除
void deleteAll(); //刪除全部
}
/** 測試CrudRepository的批量save方法 */ @Test public void testCrudRepositorySaveMethod(){ UserDao dao = ctx.getBean(UserDao.class); List<User> list = new ArrayList<>(); for (int i = 'A'; i <= 'Z'; i++) { User u = new User(); u.setName((char)i + "" + (char)i); // AA,BB這種 u.setGender(true); u.setAge(i + 1); u.setEmail(u.getName() + "@163.com"); list.add(u); } // 調用dao的批量保存 dao.save(list); } /** 測試CrudRepository的save */ @Test public void testCrudRepositoryUpdate(){ UserDao dao = ctx.getBean(UserDao.class); // 從數據庫查出來 User user = dao.findOne(1); // 修更名字 user.setName("Aa"); dao.save(user); // 通過測試發現,有id時是更新,但不是絕對的;相似jpa的merge方法 }
/** 測試CrudRepository的批量save方法 */
public void testCrudRepositorySaveMethod(){
UserDao dao = ctx.getBean(UserDao.class);
List<User> list = new ArrayList<>();
for (int i = 'A'; i <= 'Z'; i++) {
User u = new User();
u.setName((char)i + "" + (char)i); // AA,BB這種
u.setGender(true);
u.setAge(i + 1);
u.setEmail(u.getName() + "@163.com");
list.add(u);
}
// 調用dao的批量保存
dao.save(list);
}
/** 測試CrudRepository的save */
public void testCrudRepositoryUpdate(){
UserDao dao = ctx.getBean(UserDao.class);
// 從數據庫查出來
User user = dao.findOne(1);
// 修更名字
user.setName("Aa");
dao.save(user); // 通過測試發現,有id時是更新,但不是絕對的;相似jpa的merge方法
}
@NoRepositoryBean public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); // 不帶分頁的排序 Page<T> findAll(Pageable pageable); // 帶分頁的排序 }
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort); // 不帶分頁的排序
Page<T> findAll(Pageable pageable); // 帶分頁的排序
}
/** 測試PagingAndSortingRepositoryd的分頁且排序方法 */ @Test public void testPagingAndSortingRepository() { UserDao userDao = ctx.getBean(UserDao.class); /* 需求:查詢第3頁的數據,每頁5條 */ int page = 3 - 1; //因爲springdata默認的page是從0開始,因此減1 int size = 5; //Pageable 接口一般使用的其 PageRequest 實現類. 其中封裝了須要分頁的信息 //排序相關的. Sort 封裝了排序的信息 //Order 是具體針對於某一個屬性進行升序仍是降序. Order order1 = new Order(Direction.DESC, "id");//按id降序 Order order2 = new Order(Direction.ASC, "age");//按age升序 Sort sort = new Sort(order1,order2); Pageable pageable = new PageRequest(page, size,sort); Page<User> result = userDao.findAll(pageable); System.out.println("總記錄數: " + result.getTotalElements()); System.out.println("當前第幾頁: " + (result.getNumber() + 1)); System.out.println("總頁數: " + result.getTotalPages()); System.out.println("當前頁面的 List: " + result.getContent()); System.out.println("當前頁面的記錄數: " + result.getNumberOfElements()); System.out.println("當前的user對象的結果以下:"); for (User user : result.getContent()) { System.out.println(user.getId() + " == " + user.getAge()); } }
/** 測試PagingAndSortingRepositoryd的分頁且排序方法 */
public void testPagingAndSortingRepository() {
UserDao userDao = ctx.getBean(UserDao.class);
/* 需求:查詢第3頁的數據,每頁5條 */
int page = 3 - 1; //因爲springdata默認的page是從0開始,因此減1
int size = 5;
//Pageable 接口一般使用的其 PageRequest 實現類. 其中封裝了須要分頁的信息
//排序相關的. Sort 封裝了排序的信息
//Order 是具體針對於某一個屬性進行升序仍是降序.
Order order1 = new Order(Direction.DESC, "id");//按id降序
Order order2 = new Order(Direction.ASC, "age");//按age升序
Sort sort = new Sort(order1,order2);
Pageable pageable = new PageRequest(page, size,sort);
Page<User> result = userDao.findAll(pageable);
System.out.println("總記錄數: " + result.getTotalElements());
System.out.println("當前第幾頁: " + (result.getNumber() + 1));
System.out.println("總頁數: " + result.getTotalPages());
System.out.println("當前頁面的 List: " + result.getContent());
System.out.println("當前頁面的記錄數: " + result.getNumberOfElements());
System.out.println("當前的user對象的結果以下:");
for (User user : result.getContent()) {
System.out.println(user.getId() + " == " + user.getAge());
}
}
@NoRepositoryBean public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { List<T> findAll(); //查詢方法 List<T> findAll(Sort sort); //查詢方法,帶排序 List<T> findAll(Iterable<ID> ids); //查詢方法,參數爲id集合 <S extends T> List<S> save(Iterable<S> entities); //批量保存 void flush(); //刷新 <S extends T> S saveAndFlush(S entity); //保存並刷新,相似merge方法 void deleteInBatch(Iterable<T> entities); void deleteAllInBatch(); T getOne(ID id); <S extends T> List<S> findAll(Example<S> example); //根據「example」查找,參考:http://www.cnblogs.com/rulian/p/6533109.html <S extends T> List<S> findAll(Example<S> example, Sort sort); // 根據「example」查找並排序 }
public interface JpaRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll(); //查詢方法
List<T> findAll(Sort sort); //查詢方法,帶排序
List<T> findAll(Iterable<ID> ids); //查詢方法,參數爲id集合
<S extends T> List<S> save(Iterable<S> entities); //批量保存
void flush(); //刷新
<S extends T> S saveAndFlush(S entity); //保存並刷新,相似merge方法
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
<S extends T> List<S> findAll(Example<S> example); //根據「example」查找,參考:http://www.cnblogs.com/rulian/p/6533109.html
<S extends T> List<S> findAll(Example<S> example, Sort sort); // 根據「example」查找並排序
}
/** 測試JpaRepository的SaveAndFlush */ @Test public void testJpaRepositorySaveAndFlush() { UserDao userDao = ctx.getBean(UserDao.class); User user = new User(); user.setId(30); // id爲30的話,不在數據庫中。若是在數據庫中,下面則是更新 user.setAge(27); user.setName("testSaveAndFlush"); User user2 = userDao.saveAndFlush(user); System.out.println("user==user2:" + (user == user2)); System.out.println("user.id=" + user.getId()); System.out.println("user2.id=" + user2.getId()); }
/** 測試JpaRepository的SaveAndFlush */
public void testJpaRepositorySaveAndFlush() {
UserDao userDao = ctx.getBean(UserDao.class);
User user = new User();
user.setId(30); // id爲30的話,不在數據庫中。若是在數據庫中,下面則是更新
user.setAge(27);
user.setName("testSaveAndFlush");
User user2 = userDao.saveAndFlush(user);
System.out.println("user==user2:" + (user == user2));
System.out.println("user.id=" + user.getId());
System.out.println("user2.id=" + user2.getId());
}
public interface JpaSpecificationExecutor<T> { T findOne(Specification<T> spec); List<T> findAll(Specification<T> spec); Page<T> findAll(Specification<T> spec, Pageable pageable); //條件查詢,且支持分頁 List<T> findAll(Specification<T> spec, Sort sort); long count(Specification<T> spec); }
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> spec);
List<T> findAll(Specification<T> spec);
Page<T> findAll(Specification<T> spec, Pageable pageable); //條件查詢,且支持分頁
List<T> findAll(Specification<T> spec, Sort sort);
long count(Specification<T> spec);
}
/** * 目標: 實現帶查詢條件的分頁. id > 3 的條件 * 調用 JpaSpecificationExecutor 的 Page<T> findAll(Specification<T> spec, Pageable pageable); * Specification: 封裝了 JPA Criteria 查詢的查詢條件 * Pageable: 封裝了請求分頁的信息: 例如 pageNo, pageSize, Sort */ @Test public void testJapSpecificationExecutor() { // 目標:查詢id>3 的第3頁的數據,頁大小爲5 UserDao userDao = ctx.getBean(UserDao.class); Pageable pageable = new PageRequest(3 - 1, 5); //一般使用 Specification 的匿名內部類 Specification<User> spec = new Specification<User>() { /** * @param root: 表明查詢的實體類. * @param query: 能夠從中可到 Root 對象, 即告知 JPA Criteria 查詢要查詢哪個實體類. 還能夠 * 來添加查詢條件, 還能夠結合 EntityManager 對象獲得最終查詢的 TypedQuery 對象. * @param cb: CriteriaBuilder 對象. 用於建立 Criteria 相關對象的工廠. 固然能夠從中獲取到 Predicate 對象 * @return: Predicate 類型, 表明一個查詢條件. */ @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { // 通常用root和cb就ok了 return cb.gt(root.get("id"), 3); // 多條件查詢的案例 /*List<Predicate> predicates = new ArrayList<>(); Predicate p1 = cb.notEqual(root.get("id"), 15); Predicate p2 = cb.like(root.get("email"),"%163.com"); predicates.add(p1); predicates.add(p2); // 即便predicates集合裏面沒元素,也能查詢,就變成了查所有 return cb.and(predicates.toArray(new Predicate[predicates.size()]));*/ } }; Page<User> list = userDao.findAll(spec, pageable); for (User user : list) { System.out.println(user); } }
/**
* 目標: 實現帶查詢條件的分頁. id > 3 的條件
* 調用 JpaSpecificationExecutor 的 Page<T> findAll(Specification<T> spec, Pageable pageable);
* Specification: 封裝了 JPA Criteria 查詢的查詢條件
* Pageable: 封裝了請求分頁的信息: 例如 pageNo, pageSize, Sort
*/
public void testJapSpecificationExecutor() {
// 目標:查詢id>3 的第3頁的數據,頁大小爲5
UserDao userDao = ctx.getBean(UserDao.class);
Pageable pageable = new PageRequest(3 - 1, 5);
//一般使用 Specification 的匿名內部類
Specification<User> spec = new Specification<User>() {
/**
* @param root: 表明查詢的實體類.
* @param query: 能夠從中可到 Root 對象, 即告知 JPA Criteria 查詢要查詢哪個實體類. 還能夠
* 來添加查詢條件, 還能夠結合 EntityManager 對象獲得最終查詢的 TypedQuery 對象.
* @param cb: CriteriaBuilder 對象. 用於建立 Criteria 相關對象的工廠. 固然能夠從中獲取到 Predicate 對象
* @return: Predicate 類型, 表明一個查詢條件.
*/
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// 通常用root和cb就ok了
return cb.gt(root.get("id"), 3);
// 多條件查詢的案例
/*List<Predicate> predicates = new ArrayList<>();
Predicate p1 = cb.notEqual(root.get("id"), 15);
Predicate p2 = cb.like(root.get("email"),"%163.com");
predicates.add(p1);
predicates.add(p2);
// 即便predicates集合裏面沒元素,也能查詢,就變成了查所有
return cb.and(predicates.toArray(new Predicate[predicates.size()]));*/
}
};
Page<User> list = userDao.findAll(spec, pageable);
for (User user : list) {
System.out.println(user);
}
}