SpringBoot | 第三十章:Spring-data-jpa的整合和使用
前言
在前面的 ofollow,noindex" target="_blank">第九章:Mybatis-plus的整合和使用 章節中,介紹了使用 ORM
框架 mybatis-plus
進行資料庫的訪問。今天,我們來簡單學習下如何使用 spring-data-jpa
進行資料庫的訪問。由於本人未使用過 jpa
,也是趁著寫博文的機會查閱了相關資料下,有錯誤的地方還望指出!
一點知識
何為JPA
JPA
是 Java Persistence API
的簡寫,是 Sun
官方提出的一種 ORM
規範!
對於 Sun
官網而言,
一是想 簡化現有 Java EE
和 Java SE
應用開發工作 。
二是想 整合ORM技術,實現天下歸一 。
對於 JPA
規範,都在包路徑: javax.persistence.*
下,像一些常用的如: @Entity
、 @Id
及 @Transient
都在此路徑下。這些也是一些現在市面上常用的 ORM
一些約定俗成的註解了。
簡單來說, JPA
是一套規範。所以使用Jpa的一個好處是,可以更換實現而不必改動太多程式碼。
何為Sping-data-jpa
Spring Data JPA
是 Spring
基於 Hibernate
開發的一個 JPA
框架。可以極大的簡化 JPA
的寫法,可以在幾乎不用寫具體程式碼的情況下,實現對資料的訪問和操作。除了 CRUD
外,還包括如 分頁
、 排序
等一些常用的功能。
Spring Data JPA提供的介面,也是Spring Data JPA的核心概念:
-
Repository
:最頂層的介面,是一個空的介面,目的是為了統一所有Repository的型別,且能讓元件掃描的時候自動識別。 -
CrudRepository
:是Repository的子介面,提供CRUD的功能 -
PagingAndSortingRepository
:是CrudRepository的子介面,新增分頁和排序的功能 -
JpaRepository
:是PagingAndSortingRepository的子介面,增加了一些實用的功能,比如:批量操3作等。 -
JpaSpecificationExecutor
:用來做負責查詢的介面 -
Specification
:是Spring Data JPA
提供的一個查詢規範,要做複雜的查詢,只需圍繞這個規範來設定查詢條件即可。
題外話:剛開始,其實我看 mybatis
提供的都差不多,最讓我覺得神奇的是:可以通過 方法命名規則
進行相關資料庫操作,這個確實可以減少很多程式碼的編寫。原本使用 Mybatis-plus
新增一個自定義方法,需要使用通用查詢模版 EntityWrapper
進行相應的操作的
其中,相關命名規範如下:
關鍵字 | 方法命名 | sql where字句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
這個確實,夠強大!但查詢新增一多,是不是這個方法名就也很長了,(┬_┬)
SpringBoot整合Spring-data-jpa
本示例,使用 druid(連線池)
+ mysql
進行演示。同時以 User
表舉例:
CREATE TABLE `user` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '唯一標示', `code` varchar(20) DEFAULT NULL COMMENT '編碼', `name` varchar(64) DEFAULT NULL COMMENT '名稱', `status` char(1) DEFAULT '1' COMMENT '狀態 1啟用 0 停用', `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
題外話:雖然也提供了自動根據實體建立表的功能,但一般上開發應該不會這麼建立吧。因為表結構一般都需要經過評審的,評審後就建立好了。。
0.引入pom依賴
<!-- 引入jpa依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
1.編寫 User
的實體類。
/** * 使用者實體 * @author oKong * */ @Entity @Data @Builder @NoArgsConstructor @AllArgsConstructor @EntityListeners(AuditingEntityListener.class) //@Table(name="CUSTOM_USER")//自定義表名 public class User implements Serializable{ /** * */ private static final long serialVersionUID = -3752294262021766827L; /** * 唯一標示 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * 編碼 */ private String code; /** * 名稱 */ private String name; /** * 建立時間 */ @CreatedDate //自動建立 private Date gmtCreate; /** * 修改時間 */ @LastModifiedDate //有修改時 會自動時間 private Date gmtModified; }
這裡需要注意,在使用 mybatis-plus
時,在 《Mybatis-Plus使用全解》 時,介紹過可如何設定公共欄位自動填充功能,比如建立時間和修改時間,建立人和修改人等等,都是可以統一進行賦值的。而在 spring-data-jap
中,是使用 @CreatedDate
和 @LastModifiedDate
標記的,同時,需要在實體類上,加入 @EntityListeners(AuditingEntityListener.class)
,然後在啟動類上加入註解 @EnableJpaAuditing
,這樣就實現了類似公共欄位自動填充功能了。
2.建立資源類,這裡習慣了命名為 dao
了,所以還是以 Dao
進行結尾。
/** * 資源類 * @author oKong * */ public interface UserDao extends PagingAndSortingRepository<User,Long>{ List<User> findById(Long id); //使用自動命名規則進行查詢服務 List<User> findByCodeAndName(String code,String name); //使用@Query進行 自定義sql編寫 //nativeQuery=true,正常的sql語法 //負責是hsql語法 @Query(value="select * from user where code = ?1",nativeQuery=true) List<User> queryByCode(String code); //分頁 Page<User> findByCode(String code,Pageable pageable); }
注意:這裡直接繼承了 PagingAndSortingRepository
,其本身實現了分頁功能,還可以按需要繼承 CrudRepository
或者 JpaRepository
等。而且,佔位符為: ?
+具體的引數索引值
3.建立控制層,引入資源類。示例了一些常用的操作,包括分頁,查詢、刪除、新增等等。
/** * 測試類 * @author oKong * */ @RestController @Slf4j public class DemoController { @Autowired UserDao userDao; @PostMapping("/add") public String addUser(User user) { log.info("新增使用者:{}", user); user = userDao.save(user); return "新增成功,返回使用者id為:" + user.getId(); } @GetMapping("/find/{id}") public User findUser(@PathVariable Long id) { log.info("查詢使用者ID:{}", id); return userDao.findOne(id); } @PostMapping("/del/{id}") public String delUser(Long id) { log.info("刪除使用者ID:{}", id); userDao.delete(id); return "使用者id為:" + id + ",已被刪除!"; } @GetMapping("/find/{code}/{name}") public List<User> findUserByCodeAndName(@PathVariable("code") String code, @PathVariable("name")String name) { log.info("命名規則方式,查詢使用者:編碼:{},名稱:{}", code, name); return userDao.findByCodeAndName(code, name); } @GetMapping("/find/paging/{code}") public Page<User> findUserByCodePagin(@PathVariable("code") String code){ log.info("分頁模式,查詢使用者:編碼:{}", code); //這裡注意 page是從0開始的 return userDao.findByCode(code, new PageRequest(0,10)); } @GetMapping("/find/sql/{code}") public List<User> findUserByQuerySql(@PathVariable("code") String code){ log.info("自定義sql方式,查詢使用者:編碼:{}", code); return userDao.queryByCode(code); } }
4.配置檔案新增相關資料來源及jpa相關資訊。這裡使用 druid
作為資料連線池。
#資料來源設定 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=123456 #以上為必須的 #選填 spring.datasource.druid.initial-size=5 # maxPoolSize spring.datasource.druid.max-active=20 # minPoolSize spring.datasource.druid.min-idle=5 #配置獲取連線等待超時的時間 spring.datasource.druid.max-wait=60000 # 校驗 spring.datasource.druid.validation-query=SELECT 'x' spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.test-while-idle=true #配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 spring.datasource.druid.time-between-eviction-runs-millis=60000 #配置一個連線在池中最小生存的時間,單位是毫秒 spring.datasource.druid.min-evictable-idle-time-millis=300000 #jpa相關配置 # 顯示sql 但不會顯示具體的操作值 可以替換成log4jdbc spring.jpa.show-sql=true
5.編寫啟動類。
/** * jpa整合 * * @author oKong * */ @SpringBootApplication @EnableJpaAuditing @Slf4j public class JpaApplication { public static void main(String[] args) throws Exception { SpringApplication.run(JpaApplication.class, args); log.info("spring-boot-jpa-chapter30啟動!"); } }
6.啟動服務。然後使用 postman
進行訪問(關於 postman
相關用法,可以檢視: 第十五章:基於Postman的RESTful介面測試 )。
- 新增:http://127.0.0.1:8080/add
- 查詢:http://127.0.0.1:8080/find/13
- 分頁查詢:http://127.0.0.1:8080/find/paging/okong
會返回相關資訊,如總記錄數,總頁碼數等等。
控制檯輸出:
Hibernate: select user0_.id as id1_0_, user0_.code as code2_0_, user0_.gmt_create as gmt_crea3_0_, user0_.gmt_modified as gmt_modi4_0_, user0_.name as name5_0_ from user user0_ where user0_.code=? limit ? Hibernate: select count(user0_.id) as col_0_0_ from user user0_ where user0_.code=?
- 自定義sql查詢:http://127.0.0.1:8080/find/sql/okong
控制檯輸出:
Hibernate: select * from user where code = ?
參考資料
總結
本章節主要介紹了 Spring-data-jpa
的整合和簡單的使用。並未深入瞭解,想了解更多細節,比如 排序 、 @Param使用 等等,可去官網查閱下。待有機會深入學習後,再寫一篇關於 JPA
的提高篇吧~使用起來其實也蠻簡單的,就是可能更開始接觸,不是很習慣到時真的,有機會一些小的專案或者demo專案,到時可以使用下,切身體驗下~
最後
目前網際網路上很多大佬都有 SpringBoot
系列教程,如有雷同,請多多包涵了。 原創不易,碼字不易 ,還希望大家多多支援。若文中有所錯誤之處,還望提出,謝謝。
老生常談
499452441 lqdevOps
個人部落格: http://blog.lqdev.cn
完整示例: https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-30