javascript
Spring-Data-JPA尝鲜:快速搭建CRUD+分页后台实例
戳藍字“CSDN云計算”關注我們哦!
簡書ID:@我沒有三顆心臟 ?
github:wmyskxz ?
歡迎關注公眾微信號:wmyskxz
前言:由于之前沒有接觸過Hibernate框架,但是最近看一些博客深深被它的“效率”所吸引,所以這就來跟大家一起就著一個簡單的例子來嘗嘗Spring全家桶里自帶的JPA的鮮
Spring-DATA-JPA 簡介
JPA(Java Persistence API)是Sun官方提出的Java持久化規范。它為Java開發人員提供了一種對象/關聯映射工具來管理Java應用中的關系數據。他的出現主要是為了簡化現有的持久化開發工作和整合ORM技術,結束現在Hibernate,TopLink,JDO等ORM框架各自為營的局面。值得注意的是,JPA是在充分吸收了現有Hibernate,TopLink,JDO等ORM框架的基礎上發展而來的,具有易于使用,伸縮性強等優點。從目前的開發社區的反應上看,JPA受到了極大的支持和贊揚,其中就包括了Spring與EJB3.0的開發團隊。
注意:JPA是一套規范,不是一套產品,那么像Hibernate,TopLink,JDO他們是一套產品,如果說這些產品實現了這個JPA規范,那么我們就可以叫他們為JPA的實現產品。
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 規范的基礎上封裝的一套JPA應用框架,可使開發者用極簡的代碼即可實現對數據的訪問和操作。它提供了包括增刪改查等在內的常用功能,且易于擴展!學習并使用 Spring Data JPA 可以極大提高開發效率!(spring data jpa讓我們解脫了DAO層的操作,基本上所有CRUD都可以依賴于它來實現)
摘自:springboot(五):spring data jpa的使用——純潔的微笑
Hibernate 和 MyBatis 簡單對比
由于JPA底層干活的仍然是Hibernate框架,而我們之前學習的只有MyBatis相關的東西,所以在嘗鮮之前還是有必要簡單了解一下兩者的區別:
Hibernate的優勢:
Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。
Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
Hibernate數據庫移植性很好,MyBatis的數據庫移植性不好,不同的數據庫需要寫不同SQL。
Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。
MyBatis的優勢:
MyBatis可以進行更為細致的SQL優化,可以減少查詢字段。
MyBatis容易掌握,而Hibernate門檻較高。
簡單總結:
MyBatis:小巧、方便、高效、簡單、直接、半自動化
Hibernate:強大、方便、高效、復雜、間接、全自動化
引用自:【持久化框架】Mybatis與Hibernate的詳細對比——高亮
CRUD + 分頁后臺實例
下面我們來快速搭建一個使用Spring-DATA-JPA的CRUD+分頁后臺實例,并且我們會直接使用到RESTful API(不熟悉的同學[戳這里]())
第一步:新建SpringBoot項目
打開IDEA新建一個SpringBoot項目,不熟悉SpringBoot的同學請右轉:【傳送門】,然后在pom.xml中添加以下依賴:
<!--?mysql--><dependency>
????<groupId>mysql</groupId>
????<artifactId>mysql-connector-java</artifactId>
????<version>5.1.21</version>
</dependency>
<!--?jpa-->
<dependency>
????<groupId>org.springframework.boot</groupId>
????<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
然后把application.properties弄成這個樣子:
#數據庫spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
#顯示SQL語句
spring.jpa.show-sql=true
#不加下面這句則默認創建MyISAM引擎的數據庫
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
#自己重寫的配置類,默認使用utf8編碼
spring.jpa.properties.hibernate.dialect=com.wmyskxz.demo.config.MySQLConfig
spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置屬性,其主要作用是:自動創建、更新、驗證數據庫表結構。該參數的幾種配置如下:
create:每次加載hibernate時都會刪除上一次的生成的表,然后根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。
create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。
update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以后加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器后,表結構是不會被馬上建立起來的,是要等應用第一次運行起來后才會。
validate:每次加載hibernate時,驗證創建數據庫表結構,只會和數據庫中的表進行比較,不會創建新表,但是會插入新值。
然后新建一個【config】包,創建一個【MySQLConfig】類(上面的spring.jpa.properties.hibernate.dialect屬性就要配置這里的類全路徑):
package?com.wmyskxz.demo.config;import?org.hibernate.dialect.MySQL5InnoDBDialect;
public?class?MySQLConfig?extends?MySQL5InnoDBDialect?{
????@Override
????public?String?getTableTypeString()?{
????????return?"ENGINE=InnoDB?DEFAULT?CHARSET=utf8";
????}
}
第二步:創建好需要的數據庫
打開SQL服務,建表語句也很簡單啦:
create?database?testdb;第三步:創建實體類
實體類映射的實際上是數據庫表的結構,在適當的包目錄下(例如【entity】)下創建好實體類:
package?com.wmyskxz.demo.entity;import?javax.persistence.Column;
import?javax.persistence.Entity;
import?javax.persistence.GeneratedValue;
import?javax.persistence.Id;
@Entity?//?表明這是個實體類
public?class?User?{
????@Id?//?表明這個屬性是主鍵
????@GeneratedValue?//?自增長
????private?long?id;
????@Column(nullable?=?false,?unique?=?true)????//?不允許為空,屬性唯一
????private?String?username;
????@Column(nullable?=?false)???//?不允許為空
????private?String?password;
????//?getter?and?setter
}
第四步:DAO層
新建一個【repository】包,然后新建一個【UserRepository】接口,并繼承JpaRepository類:
package?com.wmyskxz.demo.repository;import?com.wmyskxz.demo.entity.User;
import?org.springframework.data.jpa.repository.JpaRepository;
public?interface?UserRepository?extends?JpaRepository<User,?Long>?{
}
繼承JpaRepository需要傳入兩個參數,一個是實體類User一個是主鍵的類型Long,而凡是繼承了JpaRepository類的就會自動實現很多內置的方法,包括增刪改查,以及使用默認支持的Pageable對象來進行分頁,默認的方法大致如下:
public?interface?JpaRepository<T,?ID>?extends?PagingAndSortingRepository<T,?ID>,?QueryByExampleExecutor<T>?{????List<T>?findAll();
????List<T>?findAll(Sort?var1);
????List<T>?findAllById(Iterable<ID>?var1);
????<S?extends?T>?List<S>?saveAll(Iterable<S>?var1);
????void?flush();
????<S?extends?T>?S?saveAndFlush(S?var1);
????void?deleteInBatch(Iterable<T>?var1);
????void?deleteAllInBatch();
????T?getOne(ID?var1);
????<S?extends?T>?List<S>?findAll(Example<S>?var1);
????<S?extends?T>?List<S>?findAll(Example<S>?var1,?Sort?var2);
}
第五步:Controller層
新建【controller】包,新建一個【UserController】類,編寫簡單的增刪改查代碼:
package?com.wmyskxz.demo.controoler;import?com.wmyskxz.demo.entity.User;
import?com.wmyskxz.demo.repository.UserRepository;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.data.domain.PageRequest;
import?org.springframework.data.domain.Sort;
import?org.springframework.web.bind.annotation.*;
import?java.util.Optional;
@RestController?//?表明這是一個Controller并返回JSON格式
public?class?UserController?{
????@Autowired
????private?UserRepository?userRepository;
????@GetMapping("/getOne")
????public?Optional<User>?getOneUserById(@RequestParam?long?id)?{
????????return?userRepository.findById(id);
????}
????@GetMapping("/all")
????public?Iterable<User>?getAllUsers(@RequestParam(value?=?"page",?defaultValue?=?"0")?int?page,
??????????????????????????????????????@RequestParam(value?=?"size",?defaultValue?=?"5")?int?size)?{
????????page?=?page?<?0???0?:?page;//?如果page為負數則修改為0,防止在首頁點擊上一頁發生錯誤
????????Sort?sort?=?new?Sort(Sort.Direction.DESC,?"id");//?按id倒敘排列
????????return?userRepository.findAll(new?PageRequest(page,?size,?sort));
????}
????@PostMapping("/add")
????public?String?addUser(@RequestParam?String?username,
??????????????????????????@RequestParam?String?password)?{
????????User?user?=?new?User();
????????user.setUsername(username);
????????user.setPassword(password);
????????userRepository.save(user);//?注意這里是save
????????return?"Saved";
????}
????@DeleteMapping("/delete")
????public?String?deleteUserById(@RequestParam?long?id)?{
????????userRepository.deleteById(id);
????????return?"Deleted";
????}
????@PutMapping("/update")
????public?String?updateUser(User?user)?{
//????????User?user?=?new?User();
//????????user.setId(id);
//????????user.setUsername(username);
//????????user.setPassword(password);
????????userRepository.save(user);
????????return?"Updated";
????}
}
上面就直接使用@Autowired自動引入了繼承了JpaRepository的UserRepository接口,我們使用它默認的方法已經足夠完成我們的基礎功能了,值得一提的是我們的getAllUsers(...)方法,它往findAll()方法里傳入了一個Pageable對象,這是Spring Data庫中定義的一個接口,是所有分頁相關信息的一個抽象,通過該接口,我們可以得到和分頁相關的所有信息(例如pageNumber、pageSize等),這樣Jpa就能夠通過Pageable參數來得到一個帶分頁信息的Sql語句。
當然上面我們是通過自己創建了一個Pageable對象,Spring也支持直接獲取Pageable對象,可以把上面的getAllUsers(...)方法改寫成下面這樣:
@GetMapping("/all")public?Iterable<User>?getAllUsers(@PageableDefault(value?=?5,?sort?=?{"id"},?direction?=?Sort.Direction.DESC)?
??????????????????????????????????????????????Pageable?pageable)?{
????return?userRepository.findAll(pageable);
}
默認從第0頁開始,也可以自己傳入一個page參數,跟上面的是一樣的。
第六步:運行項目
上面我們就快速搭建起來了一個基于Spring Boot和JPA的REST風格的后臺增刪改查實例,我們把項目跑起來,可以看到數據庫自動創建了一些表:
JPA幫我們創建的user表的創建SQL如下:
CREATE?TABLE?`user`?(??`id`?bigint(20)?NOT?NULL,
??`password`?varchar(255)?NOT?NULL,
??`username`?varchar(255)?NOT?NULL,
??PRIMARY?KEY?(`id`),
??UNIQUE?KEY?`UK_sb8bbouer5wak8vyiiy4pf2bx`?(`username`)
)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;
使用REST測試工具測試
完全符合我們的要求,然后我們使用一些REST的測試工具,來測試上面的功能是否都能正確運行,比如我這里使用的【Restlet Client】,在Chrome商店就可以下載到。
`/all`地址測試:
首先先來測試一下http://localhost:8080/all地址,由于現在數據庫還是空的,所以可以看到返回如下:
{????"content":?[
????],
????"pageable":?{
????????"sort":?{
????????????"sorted":?true,
????????????"unsorted":?false,
????????????"empty":?false
????????},
????????"offset":?0,
????????"pageNumber":?0,
????????"pageSize":?5,
????????"unpaged":?false,
????????"paged":?true
????},
????"totalElements":?0,
????"last":?true,
????"totalPages":?0,
????"number":?0,
????"size":?5,
????"sort":?{
????????"sorted":?true,
????????"unsorted":?false,
????????"empty":?false
????},
????"numberOfElements":?0,
????"first":?true,
????"empty":?true
}
添加用戶測試:
然后我們使用http://localhost:8080/add?username=wmyskxz&password=123地址,添加幾個類似的用戶信息:
可以看到返回正確的Saved信息:
`/getOne`地址測試:
我們就直接使用http://localhost:8080/getOne?id=1來獲取剛才添加的用戶,可以看到返回正確的數據:
{????"id":?1,
????"username":?"wmyskxz",
????"password":?"123"
}
修改用戶測試:
然后我們使用http://localhost:8080/update?id=1&username=wmyskxz&password=123456來模擬進行用戶密碼的修改:
可以看到正確的更新信息Updated,再次查詢用戶,也能看到正確的數據:
{????"id":?1,
????"username":?"wmyskxz",
????"password":?"123456"
}
分頁測試:
我們使用添加功能為數據庫添加5條以上的數據,然后進行一次查詢/all,可以看到能夠按照id倒敘排列后返回5條數據:
數據庫的情況返回的JSON數據如下:
{????"content":?[
????????{
????????????"id":?10,
????????????"username":?"wmyskxz8",
????????????"password":?"123"
????????},
????????{
????????????"id":?9,
????????????"username":?"wmyskxz7",
????????????"password":?"123"
????????},
????????{
????????????"id":?8,
????????????"username":?"wmyskxz6",
????????????"password":?"123"
????????},
????????{
????????????"id":?7,
????????????"username":?"wmyskxz5",
????????????"password":?"123"
????????},
????????{
????????????"id":?6,
????????????"username":?"wmyskxz4",
????????????"password":?"123"
????????}
????],
????"pageable":?{
????????"sort":?{
????????????"sorted":?true,
????????????"unsorted":?false,
????????????"empty":?false
????????},
????????"offset":?0,
????????"pageNumber":?0,
????????"pageSize":?5,
????????"unpaged":?false,
????????"paged":?true
????},
????"totalElements":?9,
????"last":?false,
????"totalPages":?2,
????"number":?0,
????"size":?5,
????"sort":?{
????????"sorted":?true,
????????"unsorted":?false,
????????"empty":?false
????},
????"numberOfElements":?5,
????"first":?true,
????"empty":?false
}
刪除用戶測試:
使用地址http://localhost:8080/delete?id=1來刪除ID為1的用戶:
能正確看到Deleted信息,并查看數據能夠看到數據已經被刪除了。
以上,我們就快速搭建好了一個CRUD+分頁的后臺實例,還用了比較流行的RESTful風格,粗略的感受了一下JPA的方便,還是挺爽的..沒有復雜的Mapper文件,不用自動生成實體,甚至不用管SQL,只需要專注在邏輯上就行了,其實簡單使用的話以上的東西也能應付一些常見的場景了,后期再深入了解了解吧!
參考資料:
springboot(五):spring data jpa的使用——純潔的微笑
springboot(十五):springboot+jpa+thymeleaf增刪改查示例——純潔的微笑
Spring Boot中使用Spring-data-jpa讓數據訪問更簡單、更優雅——程序猿DD
推薦閱讀
5G大規模商用來臨之前,你必須知道的幾個知識點
“離開360時,它只給了我一塊錢”
AI找Bug,一鍵快速預測
原子互換:一統公鏈江湖的神來之筆
春晚鬼畜 B 站日排行最高,趙本山:我的時代還沒有結束!
PDF翻譯神器,再也不擔心讀不懂英文Paper了
新聞聯播也可以拿來做數據分析?
高曉松侃5G!2019開年大講揭示運營商的秘密
1.微信群:
添加小編微信:color_ld,備注“進群+姓名+公司職位”即可,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
2.征稿:
投稿郵箱:liudan@csdn.net;微信號:color_ld。請備注投稿+姓名+公司職位。
喜歡就點擊“好看”吧! 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring-Data-JPA尝鲜:快速搭建CRUD+分页后台实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 养老保险个人怎么交 有以下3点要搞清楚
- 下一篇: gradle idea java ssm