SpringBoot整合Spring Data JPA


本篇要點

  • 簡單介紹JPA。

  • 介紹快速SpringBoot快速整合JPA

JPA是啥?

The Java Persistence API is a standard technology that lets you “map” objects to relational databases. The spring-boot-starter-data-jpa POM provides a quick way to get started.

  • JPA是The Java Persistence API標准,Java持久層API,是一種能讓對象能夠快速映射到關系型數據庫的技術規范。
  • JPA只是一種規范,它需要第三方自行實現其功能,在眾多框架中Hibernate是最為強大的一個。

Spring Data JPA

Spring Data JPA 是采用基於JPA規范的Hibernate框架基礎下提供了Repository層的實現。Spring Data Repository極大地簡化了實現各種持久層的數據庫訪問而寫的樣板代碼量,同時CrudRepository提供了豐富的CRUD功能去管理實體類。SpringBoot框架為Spring Data JPA提供了整合,spring-boot-starter-data-jpa能夠讓你快速使用這門技術,它提供了以下依賴。

  • Hibernate:最流行的JPA實現之一。
  • Spring Data JPA:幫助你去實現JPA-based repositories。
  • Spring ORM:Spring Framework提供的核心ORM支持。

快速SpringBoot快速整合JPA

引入依賴

        <!--SpringBoot對jpa的封裝-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--mysql驅動,8.x版本-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

配置yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jpa?serverTimezone=GMT%2B8
    username: root
    password: 123456
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
  jpa:
    #在建表的時候,將默認的存儲引擎切換為 InnoDB
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    # 配置在日志中打印出執行的 SQL 語句信息。
    show-sql: true
    # 配置指明在程序啟動的時候要刪除並且創建實體類對應的表。
    hibernate:
      ddl-auto: create #update

值得注意的是:spring.jpa.hibernate.ddl-auto第一建表的時候可以create,指明在程序啟動的時候要刪除並且創建實體類對應的表。后續使用就需要改為update。

ddl-auto的幾種屬性值

  • create:每次加載hibernate時都會刪除上一次的生成的表,再重新根據model生成表,因此可能會導致數據丟失。
  • create-drop :每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除
  • update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以后加載hibernate時根據 model類自動更新表結構,原有數據不會清空,只會更新。
  • validate :每次加載hibernate時,會校驗數據與數據庫的字段類型是否相同,字段不同會報錯

實體類

JPA規范定義在javax.persistence包下,注意導包的時候不要導錯。

@Entity(name = "t_user")
@Data
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;


    @Transient
    private String email;

}
  • @Entity標注保證實體能夠被SpringBoot掃描到,對應表名為t_user

  • @Id表明id。

  • @GeneratedValue中標注主鍵生成策略。

  • @Transient表示不需要映射的字段。

常見的主鍵生成策略

  • TABLE: 使用一個特定的數據庫表格來保存主鍵
  • SEQUENCE: 根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。這個值要與generator一起使用,generator 指定生成主鍵使用的生成器(可能是orcale中自己編寫的序列)。
  • IDENTITY: 主鍵由數據庫自動生成(主要是支持自動增長的數據庫,如mysql)
  • AUTO: 主鍵由程序控制,也是GenerationType的默認值。

啟動項目,生成表

首先在數據庫中創建jpa庫,庫名無所謂,和配置對應上就可以。

啟動項目,你會發現控制台輸出日志如下:

Hibernate: drop table if exists t_user
Hibernate: create table t_user 
    (id bigint not null auto_increment, password varchar(255), username varchar(255), primary key (id)) engine=InnoDB

此時我們配置的create效果已經顯現,我們之后將它改為update,不然每次啟動程序,數據表又得重建咯。

數據訪問層

Working with Spring Data Repositories

Spring Data JPA repositories是你可以定義訪問數據的接口,JPA查詢是根據你的方法名稱自動創建的。

這里我們編寫一個接口,繼承JpaRepository即可。User是對象名,不是表名,Long為主鍵的類型。

public interface UserDao extends JpaRepository<User, Long> {

    /**
     * 根據用戶名和密碼查詢用戶
     */
    User findByUsernameAndPassword(String username, String password);
}

JPA默認支持常見的增刪改查,也支持findByUsernameAndPassword這種以字段命名的方法,對於更復雜的查詢,您可以使用Spring Data的Query注解對方法進行注解。

命名規范與對應SQL

Keyword Sample JPQL snippet
Distinct findDistinctByLastnameAndFirstname select distinct … where x.lastname = ?1 and x.firstname = ?2
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull, Null findByAge(Is)Null … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstname) = UPPER(?1)

測試JPA

@SpringBootTest
class SpringBootJpaApplicationTests {

    @Resource
    UserDao userDao;

    @Test
    void testJPA() {
        User user = userDao.save(new User(null, "summerday", "123456", "hangzhou"));
        System.out.println("添加用戶: " + user);
        User u = userDao.findByUsernameAndPassword("summerday", "123456");
        System.out.println("根據用戶名和密碼查詢用戶: " + u);
        long count = userDao.count();
        System.out.println("當前用戶數量: " + count);
        PageRequest page = PageRequest.of(0, 5, Sort.by(Sort.Order.desc("id")));
        Page<User> all = userDao.findAll(page);
        System.out.println("分頁 + 根據id逆序 查詢結果: " + all.getContent());
        if(userDao.existsById(u.getId())) {
            userDao.deleteById(u.getId());
            System.out.println("刪除id為" + u.getId()+ "的用戶成功");
        }
        long c = userDao.count();
        System.out.println("剩余用戶數為: " + c);
    }
}

控制台輸出如下:

源碼下載

本文內容均為對優秀博客及官方文檔總結而得,原文地址均已在文中參考閱讀處標注。最后,文中的代碼樣例已經全部上傳至Gitee:https://gitee.com/tqbx/springboot-samples-learn,另有其他SpringBoot的整合哦。

參考閱讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM