Spring Data Jpa 簡介
JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化規范(JSR 338,這些介面所在包為javax.persistence,詳細內容可參考https://github.com/javaee/jpa-spec)
JPA的出現主要是為了簡化持久層開發以及整合ORM技術,結束Hibernate、TopLink、JDO等ORM框架各自為營的局面,JPA是在吸收現有ORM框架的基礎上發展而來,易于使用,伸縮性強,總的來說,JPA包括以下3方面的技術:
- ORM映射元資料: 支持XML和注解兩種元資料的形式,元資料描述物件和表之間的映射關系
- API: 操作物體物件來執行CRUD操作
- 查詢語言: 通過面向物件而非面向資料庫的查詢語言(
JPQL)查詢資料,避免程式的SQL陳述句緊密耦合
Spring Data Jpa官方解釋
連接:https://spring.io/projects/spring-data-jpa#overview
Spring Data JPA是Spring Data家族的一部分,可以輕松實作基于JPA的存盤庫, 此模塊處理對基于JPA的資料訪問層的增強支持, 它使構建使用資料訪問技術的Spring驅動應用程式變得更加容易,
在相當長的一段時間內,實作應用程式的資料訪問層一直很麻煩, 必須撰寫太多樣板代碼來執行簡單查詢以及執行分頁和審計, Spring Data JPA旨在通過減少實際需要的作業量來顯著改善資料訪問層的實作, 作為開發人員,您撰寫repository介面,包括自定義查找器方法,Spring將自動提供實作,
Hibernate、Jpa、Spring Data Jpa三者之間的關系
Hibernate
Hibernate是一個開放源代碼的物件關系映射框架,它對JDBC進行了非常輕量級的物件封裝,它將POJO與資料庫表建立映射關系,是一個全自動的orm框架,hibernate可以自動生成SQL陳述句,自動執行,使得Java程式員可以隨心所欲的使用物件編程思維來操縱資料庫,
JPA
JPA全稱是Java Persistence API,即java持久化API,是sun公司推出的一套基于ORM的規范,內部由一系列的介面和抽象類構成

JPA與Hibetnate的關系
JPA和Hibernate的關系就像JDBC和JDBC驅動的關系,JPA是規范,Hibernate除了作為ORM框架之外,它也是一種JPA實作,JPA怎么取代Hibernate呢?JDBC規范可以驅動底層資料庫嗎?答案是否定的,也就是說,如果使用JPA規范進行資料庫操作,底層需要hibernate作為其實作類完成資料持久化作業,
Spring Data jpa
Spring Data JPA 讓我們解脫了DAO層的操作,基本上所有CRUD都可以依賴于它來實作,在實際的作業工程中,推薦使用Spring Data JPA + ORM(如:hibernate)完成操作,這樣在切換不同的ORM框架時提供了極大的方便,同時也使資料庫層操作更加簡單,方便解耦
總結:
JPA是一種規范,Hibernate實作了JPA規范,即Hibernate為JPA的一種實作;而Spring Data JPA是對JPA進行更高級的封裝,讓其dao編碼變得更簡單,Spring Boot整合Spring Data Jpa
匯入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
相關配置
server: port: 9001 spring: application: name: service-product datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/practice?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 123456 jpa: database: mysql show-sql: true open-in-view: true hibernate: ddl-auto: update
ddl-auto
create:每次運行程式時,都會重新創建表,故而資料會丟失create-drop:每次運行程式時會先創建表結構,然后待程式結束時清空表upadte:每次運行程式,沒有表時會創建表,如果物件發生改變會更新表結構,原有資料不會清空,只會更新(推薦使用)validate:運行程式會校驗資料與資料庫的欄位型別是否相同,欄位不同會報錯none: 禁用DDL處理
Spring Data Jpa的使用
Spring Data Jpa UML類圖
簡單的REST CRUD示例
物體類package com.jpa.product.entity; import lombok.Data; import javax.persistence.*; import java.math.BigDecimal; /** * @author: MR.LIU * @description: * @date: 2020/5/29 * @time: 22:17 */ @Data @Entity @Table(name = "product") public class Product { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @Column(name = "product_name") private String productName; @Column(name = "price") private BigDecimal price; @Column(name = "description") private String description; @Column(name = "status") private Integer status; @Column(name = "caption") private String caption; @Column(name = "stock") private Integer stock; }
一般簡單的Demo示例中只會使用@GeneratedValue(strategy = GenerationType.IDENTITY)這種主鍵自增的策略,而實際資料庫中表欄位主鍵型別很少是int型的
JPA自帶的幾種主鍵生成策略
- TABLE: 使用一個特定的資料庫表格來保存主鍵
- SEQUENCE: 根據底層資料庫的序列來生成主鍵,條件是資料庫支持序列,這個值要與generator一起使用,generator 指定生成主鍵使用的生成器(可能是orcale中自己撰寫的序列)
- IDENTITY: 主鍵由資料庫自動生成(主要是支持自動增長的資料庫,如mysql)
- AUTO: 主鍵由程式控制,也是GenerationType的默認值
dao層
package com.jpa.product.dao; import com.jpa.product.entity.Product; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * @author: MR.LIU * @description: 資料層 * @date: 2020/5/29 * @time: 22:34 */ public interface ProductDao extends JpaRepository<Product,Long>, JpaSpecificationExecutor<Product> { }
service層
package com.jpa.product.service; import com.jpa.product.entity.Product; /** * @author: MR.LIU * @description: 介面層 * @date: 2020/5/29 * @time: 22:37 */ public interface ProductService { /** * 根據id查詢 * @param id * @return */ Product findById(Long id); /** * 保存 * @param product * @return */ void save(Product product); /*** * 修改 * @param product * @return */ void update(Product product); /** * 洗掉 * @param id * @return */ void delete(Long id); }
impl層
package com.jpa.product.service.impl; import com.jpa.product.dao.ProductDao; import com.jpa.product.entity.Product; import com.jpa.product.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author: MR.LIU * @description: * @date: 2020/5/29 * @time: 22:41 */ @Service public class ProductServiceImpl implements ProductService { @Autowired private ProductDao productDao; @Override public Product findById(Long id) { return productDao.findById(id).get(); } @Override public void save(Product product) { productDao.save(product); } @Override public void update(Product product) { productDao.save(product); } @Override public void delete(Long id) { productDao.deleteById(id); } }
controller層
package com.jpa.product.controller; import com.jpa.product.entity.Product; import com.jpa.product.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @author: MR.LIU * @description: * @date: 2020/5/29 * @time: 22:47 */ @RestController @RequestMapping(value = "/product") public class ProductController { @Autowired private ProductService productService; @GetMapping(value = "/{id}") public Product getProduct(@PathVariable Long id) { return productService.findById(id); } @PostMapping(value = "/save") public String saveProduct(@RequestBody Product product){ productService.save(product); return "保存成功"; } }
測驗
http://localhost:9001/product/1
成功查詢
模糊查詢
自定義DAO介面
@Query(value = "https://www.cnblogs.com/topshark/p/select * from product where product_name like concat('%',:name,'%')",nativeQuery = true)
List<Product> findByNameMatch(@Param("name") String name);
上的SQL陳述句一定要按照Query的格式來,以上都是寫在DAO層(respository層里面)
@Query注解的用法(Spring Data JPA) 這里參考:http://www.cnblogs.com/zj0208/p/6008627.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/6637.html
標籤:其他
上一篇:推薦幾個比較好用的遠程除錯工具
