使用Spring Data JPA的Spring Boot

在本教程中,優銳課小U將帶大家看到Spring Data JPA如何在DAO層上提供完整的抽象。我們不再需要爲DAO層編寫實現; Spring Data自動生成實現DAO實現。


依賴配置

在本教程中,我將MySQL數據庫與Spring Data一起使用。 這是build.gradle文件:

buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.amitph.spring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('mysql:mysql-connector-java:8.0.13')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}

 

數據源配置

現在,我們已經配置了依賴項。現在還不該告訴要連接到哪個數據源。這是我的帶有Spring Boot數據源條目的application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:33099/dogs
    password: <ENTER _ PASSWORD _ HERE >
    username: root
    driver-class-name: "com.mysql.jdbc.Driver"
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate:
      ddl-auto: update

 

在這裏,我們具有指定的JDBC URL,用戶名,密碼和驅動程序類名稱(MySQL)


除此之外,還有JPA特定的配置。首先是數據庫平臺,它告訴我們在MySQL查詢方言下要考慮的基礎Hibernate功能。這樣,所有數據庫操作將以MySQL特定的語法處理。第二個JPA配置是ddl-auto,它告訴Hibernate創建各自的數據庫和表結構(如果尚未存在的話)。


啓用此選項後,Hibernate將基於實體Bean和數據源創建數據庫結構。


Entity Bean

我們將要做的第一級代碼是編寫一個Entity Bean。這是Oracle文檔關於實體Bean的內容。


使用JPA,你可以將任何POJO類指定爲JPA實體——使用從JPA持久性提供程序(在Java EE EJB容器內或外部)獲得的實體管理器的服務,其非瞬態字段應持久保存到關係數據庫的Java對象。Java SE應用程序中的EJB容器)。


用簡單的話來說,JPA實體是任何Java POJO,都可以表示基礎表結構。由於我們的服務基於“Dog”表,因此我們將創建一個“Dog 實體對象。

package com.amitph.spring.dogs.repo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Dog {
    @Id
    @GeneratedValue
    private long id;
    private String name;
    private int age;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

 

上面的POJO@Entity註釋,表示這是表名Dog的實體對象。


然後,有三個字段代表數據表列。字段ID是我們的主鍵,因此被標記爲@Id


字段ID也用@GeneratedValue標記,表示這是一個自動增量列,Hibernate將負責輸入下一個值。Hibernate首先將查詢基礎表以瞭解該列的最大值,並在下一次插入時對其進行遞增。這也意味着我們不需要爲Id列指定任何值,可以將其留空。


倉庫接口


存儲庫代表DAO層,通常執行所有數據庫操作。感謝Spring Data,他提供了這些方法的實現。讓我們看看我們的DogsRepoisitory,它擴展了CrudRepository

package com.amitph.spring.dogs.repo;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface DogsRepository extends CrudRepository<Dog, Long> {}

 

DogsRepository中這裏沒有方法聲明。這是因爲Spring DataCrudInterface 已經聲明瞭基本的CRUD方法。


在這裏,我們完成了JPASpring數據工作——換句話說,就是DAO層。現在,讓我們編寫一個簡單的服務層和一個控制器。


控制器和服務層

完成數據訪問層後,我們將編寫控制器和服務層。請注意,DogsRepository帶有@Repository註釋,這也將其添加到Spring Context中。現在,我們可以在Service中自動連線存儲庫。

Dogs Service

此類具有簡單的CRUD方法。還將Entity Bean轉換爲DTO(數據傳輸對象)。DTO還是一個簡單的Java POJO,用於在系統之間傳輸數據。在這裏,我們從REST端點返回DTO

package com.amitph.spring.dogs.service;

import com.amitph.spring.dogs.model.DogDto;
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.repo.DogsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
public class DogsService {
    @Autowired DogsRepository repository;
    public void add(DogDto dto) {
        repository.save(toEntity(dto));
    }
    public void delete(long id) {
        repository.deleteById(id);
    }
    public List<Dog> getDogs() {
        return (List<Dog>) repository.findAll();
    }
    public Dog getDogById(long id) {
        Optional<Dog> optionalDog = repository.findById(id);
        return optionalDog.orElseThrow(() -> new DogNotFoundException("Couldn't find a Dog with id: " + id));
    }
    private Dog toEntity(DogDto dto) {
        Dog entity = new Dog();
        entity.setName(dto.getName());
        entity.setAge(dto.getAge());
        return entity;
    }
}

 

Dogs控制器

Dogs Controller是具有簡單CRUD端點的標準REST控制器。控制器的工作是處理HTTP請求並調用Service類方法。

package com.amitph.spring.dogs.web;
import com.amitph.spring.dogs.model.DogDto;
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.service.DogsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/dogs")
public class DogsController {
    @Autowired DogsService service;
    @GetMapping
    public List<Dog> getDogs() {
        return service.getDogs();
    }
    @PostMapping
    public void postDogs(@RequestBody DogDto dto) {
        service.add(dto);
    }
    @GetMapping("/{id}")
    public Dog getById(@PathVariable(required = true) long id) {
        return service.getDogById(id);
    }
    @DeleteMapping("/{id}")
    public void delete(@PathVariable(required = true) long id) {
        service.delete(id);
    }
}

 

現在,Dogs Service已準備好運行。啓動應用程序並執行HTTP端點。


結論

Spring數據和JPA教程的Spring Boot到此結束。我們看到了如何將Spring Data的抽象用於數據訪問層。我們看到了如何以Entity Bean的形式表示數據庫表,以及如何使用Spring Data的自動生成的存儲庫實現。此外,我們還看到了如何使用Spring Boot進行自動數據源配置。


Spring Boot Rest Service帖子中,我們已經看到了使用Spring Boot創建RESTful Web服務。在當前文章中,我們不關心異常處理。訪問Spring Rest Service異常處理以瞭解有關處理異常的信息。我們還跳過了這裏的單元測試部分,這將在以後的文章中介紹。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章