天天看點

Spring Boot 之Spring data JPA簡介

文章目錄

    • 添加依賴
    • 添加entity bean
    • 建立 Dao
    • Spring Data Configuration
    • 測試

Spring Boot 之Spring data JPA簡介

JPA的全稱是Java Persistence API (JPA),他是一個存儲API的标準,而Spring data JPA就是對JPA的一種實作,可以讓我們友善的對資料進行存取。按照約定好的方法命名規則寫dao層接口,進而在不實作接口的情況下,實作對資料庫的通路和操作。同時提供了很多除了CRUD之外的功能,如分頁、排序、複雜查詢等等。

Spring data JPA可以看做是對Hibernate的二次封裝。本文将會以一個具體的例子來講解,怎麼在Spring Boot中使用Spring data JPA。

我們要添加如下的Spring data JPA依賴,為了友善測試,我們添加一個h2的記憶體資料庫:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
           

我們來建立一個entity bean:

@Entity
@Data
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(nullable = false, unique = true)
    private String title;

    @Column(nullable = false)
    private String author;
}
           

public interface BookRepository extends JpaRepository<Book, Long> {
    List<Book> findByTitle(String title);

    @Query("SELECT b FROM Book b WHERE LOWER(b.title) = LOWER(:title)")
    Book retrieveByTitle(@Param("title") String title);
}
           

所有的Dao都需要繼承Repository接口,Repository是一個空的接口:

@Indexed
public interface Repository<T, ID> {

}
           

如果要使用預設的通用的一些實作,則可以繼承CrudRepository, PagingAndSortingRepository和JpaRepository。

上面的例子中我們繼承了JpaRepository。

上面的例子中我們建立了一個按Title查找的方法:

List<Book> findByTitle(String title);
           

這個方法我們是不需要自己去實作的,Spring Data JPA會幫我們去實作。我們可以使用find…By, read…By, query…By, count…By,和 get…By的格式定義查詢語句,By後面接的就是Entity的屬性。除了And,我們還可以使用Or來拼接方法,下面我們再舉個例子:

interface PersonRepository extends Repository<Person, Long> {

  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query
  List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property
  List<Person> findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query
  List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}
           

當然,處理方法拼接外,我們還可以自定義sql查詢語句:

@Query("SELECT b FROM Book b WHERE LOWER(b.title) = LOWER(:title)")
    Book retrieveByTitle(@Param("title") String title);
           

自定義查詢語句給Spring data JPA提供了更大的想象空間。

要使用Spring Data JPA, 我們還需要在配置檔案中指定要掃描的目錄,使用@EnableJpaRepositories注解來實作:

@Configuration
@EnableJpaRepositories(basePackages = "com.flydean.repository")
public class PersistenceConfig {
}
           

我們還需要在配置檔案中指定資料源的屬性:

spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
           

有了上面的一切,我們就可以測試我們的資料源了:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {JpaApp.class})
public class BookRepositoryTest {

    @Autowired
    private BookRepository bookRepository;

    @Test
    @Transactional(readOnly=false)
    public void testBookRepository(){
        Book book = new Book();
        book.setTitle(randomAlphabetic(10));
        book.setAuthor(randomAlphabetic(15));

        bookRepository.save(book);

       bookRepository.findByTitle(book.getTitle()).forEach(e -> log.info(e.toString()));
       log.info(bookRepository.retrieveByTitle(book.getTitle()).toString());
    }
}
           

本文的例子可以參考:https://github.com/ddean2009/learn-springboot2/tree/master/springboot-jpa

更多教程請參考 flydean的部落格

繼續閱讀