前言:因爲以前沒有接觸過Hibernate框架,可是最近看一些博客深深被它的「效率」所吸引,因此這就來跟你們一塊兒就着一個簡單的例子來嚐嚐Spring全家桶裏自帶的JPA的鮮html
JPA(Java Persistence API)是Sun官方提出的Java持久化規範。它爲Java開發人員提供了一種對象/關聯映射工具來管理Java應用中的關係數據。他的出現主要是爲了簡化現有的持久化開發工做和整合ORM技術,結束如今Hibernate,TopLink,JDO等ORM框架各自爲營的局面。值得注意的是,JPA是在充分吸取了現有Hibernate,TopLink,JDO等ORM框架的基礎上發展而來的,具備易於使用,伸縮性強等優勢。從目前的開發社區的反應上看,JPA受到了極大的支持和讚賞,其中就包括了Spring與EJB3.0的開發團隊。java
注意:JPA是一套規範,不是一套產品,那麼像Hibernate,TopLink,JDO他們是一套產品,若是說這些產品實現了這個JPA規範,那麼咱們就能夠叫他們爲JPA的實現產品。mysql
Spring Data JPA 是 Spring 基於 ORM 框架、JPA 規範的基礎上封裝的一套JPA應用框架,可以使開發者用極簡的代碼便可實現對數據的訪問和操做。它提供了包括增刪改查等在內的經常使用功能,且易於擴展!學習並使用 Spring Data JPA 能夠極大提升開發效率!(spring data jpa讓咱們解脫了DAO層的操做,基本上全部CRUD均可以依賴於它來實現)git
因爲JPA底層幹活的仍然是Hibernate框架,而咱們以前學習的只有MyBatis相關的東西,因此在嚐鮮以前仍是有必要簡單瞭解一下二者的區別:web
Hibernate的優點:spring
MyBatis的優點:sql
簡單總結:數據庫
下面咱們來快速搭建一個使用Spring-DATA-JPA的CRUD+分頁後臺實例,而且咱們會直接使用到RESTful API(不熟悉的同窗戳這裏)
打開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的配置屬性,其主要做用是:自動建立、更新、驗證數據庫表結構。該參數的幾種配置以下:
而後新建一個【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 }
新建一個【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】包,新建一個【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的測試工具,來測試上面的功能是否都能正確運行,好比我這裏使用的【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
歡迎轉載,轉載請註明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz 歡迎關注公衆微信號:wmyskxz 分享本身的學習 & 學習資料 & 生活 想要交流的朋友也能夠加qq羣:3382693