讓我們從可以構造的最簡單的東西開始。實際上,爲了使其儘可能簡單,我們甚至可以省略 REST 的概念。(稍後,我們將添加 REST 以瞭解兩者之間的區別。)
我們的示例爲管理公司員工的簡單工資服務建模。簡而言之,我們需要將員工對象存儲在 H2 內存數據庫中,並通過 JPA 訪問它們。這將被 Spring MVC 層包裝以進行遠程訪問。
nonrest/src/main/java/payroll/Employee.java
package payroll;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Data
@Entity
class Employee {
private @Id @GeneratedValue Long id;
private String name;
private String role;
Employee() {}
Employee(String name, String role) {
this.name = name;
this.role = role;
}
}
儘管很小,但該 Java 類包含許多內容:
@Data
是 Lombok 註解,用於基於字段插件所有 getter、setter、equals
、hash
和toString
方法;@Entity
是一個 JPA 註解,可以使該對象準備好存儲在基於 JPA 的數據存儲區中;id
、name
,和role
是域對象的屬性,第一個被標記了更多的 JPA 註解以指示它是主鍵,並由 JPA 提供程序自動填充;- 當我們需要創建新實例但還沒有 ID 時,就會創建一個自定義構造函數。
有了這個領域對象定義,我們現在可以轉向 Spring Data JPA 來處理繁瑣的數據庫交互。Spring Data 存儲庫是具有支持針對後端數據存儲讀取、更新、刪除和創建記錄的方法的接口。在適當的情況下,某些存儲庫還支持數據分頁和排序。Spring Data 根據在接口中的方法命名中找到的約定來綜合實現。
除了 JPA,還有多種存儲庫實現。我們可以使用 Spring Data MongoDB、Spring Data GemFire、Spring Data Cassandra 等。在該教程中,我們將一直使用 JPA。
nonrest/src/main/java/payroll/EmployeeRepository.java
package payroll;
import org.springframework.data.jpa.repository.JpaRepository;
interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
該接口擴展了 Spring Data JPA 的 JpaRepository
,將域類型指定爲 Employee
並將 ID 類型指定爲 Long
。該接口儘管表面上是空的,但只要它支持,它就會將其打包:
- 創建新實例;
- 更新現有的;
- 刪除中;
- 查找(一個、全部、通過簡單或複雜的屬性)
Spring Data 的存儲庫解決方案可以避開數據存儲的詳細信息,而可以使用特定於域的術語來解決大多數問題。
信不信由你,這足以啓動一個應用!Spring Boot 應用至少是一個 public static void main
入口點和 @SpringBootApplication
註解。這告訴 Spring Boot 儘可能地提供幫助。
nonrest/src/main/java/payroll/PayrollApplication.java
package payroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PayrollApplication {
public static void main(String... args) {
SpringApplication.run(PayrollApplication.class, args);
}
}
@SpringBootApplication
是一個元註解,可引入組件掃描、自動配置,和屬性支持。在該教程中,我們不會深入探討 Spring Boot 的細節,但從本質上講,它將啓動 servlet 容器並提供我們的服務。
不過,沒有數據的應用並不是很有趣,所以讓我們預加載它。其後的類將在 Spring 之前自動加載:
nonrest/src/main/java/payroll/LoadDatabase.java
package payroll;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
class LoadDatabase {
@Bean
CommandLineRunner initDatabase(EmployeeRepository repository) {
return args -> {
log.info("Preloading " + repository.save(new Employee("Bilbo Baggins", "burglar")));
log.info("Preloading " + repository.save(new Employee("Frodo Baggins", "thief")));
};
}
}
加載後會發生什麼?
- 一旦應用上下文被家在,Spring Boot 將運行所有
CommandLineRunner
的 bean; - 該運行器將請求我們剛剛創建的
EmployeeRepository
副本; - 使用它,它將創建兩個實體並將其存儲;
@Slf4j
是 Lombok 註解,用於自動創建基於 Slf4j 的LoggerFactory
作爲log
,從而使我們可以記錄這些新創建的 “員工”。
右鍵單擊並運行 PayRollApplication
,這是我們得到的:
控制檯輸出的片段,顯示數據的預加載
...
2018-08-09 11:36:26.169 INFO 74611 --- [main] payroll.LoadDatabase : Preloading Employee(id=1, name=Bilbo Baggins, role=burglar)
2018-08-09 11:36:26.174 INFO 74611 --- [main] payroll.LoadDatabase : Preloading Employee(id=2, name=Frodo Baggins, role=thief)
...
這不是完整的日誌,而只是預加載數據的關鍵部分。(的確,請查看整個控制檯。這很輝煌。)