採用Spring開發時,可透過Spring Data JPA進行資料存取,藉此不用撰寫繁瑣的SQL或直接操作資料庫。
JPA可參考先前寫的文章 誤會大了–JPA不是ORM框架
此篇介紹Spring Data JPA提供的Repository介面操作,可以直接使用內建方法完成基本的資料庫操作。在此之前先介紹Spring Boot的專案結構,有助於了解Repository在這之間扮演的角色。
Spring Boot的專案,建議可採分層架構,日後維護會比較容易,也能夠提高擴展性:
src/
└── main/
├── java/
│ └── com.example.project/
│ ├── controller/ # Controller層,處理HTTP請求並回應
│ ├── service/ # Service層,處理業務邏輯
│ ├── repository/ # Repository層,與資料庫互動
│ ├── model/ # Model層,像是Entity資料庫實體類別
│ └── Application.java # Spring Boot的應用程式入口
└── resources/
├── application.yml # Spring Boot的配置文件
└── templates/ # Thymeleaf模板,若未採前後端分離,可將模板放於此
public interface TaskRepository extends JpaRepository<Task, Long> {
}
// 繼承JpaRepository,並給予泛型:<實體對象類, ID類型>
CrudRepository<T, ID>:基本增刪查改功能
// 儲存或更新實體 save(S entity)
Task task = new Task();
taskRepository.save(task);
// 根據ID查詢實體 findById(ID id)
Task task = taskRepository.findById(1L).orElse(null);
if (task != null) {
System.out.println(task.getName());
}
// 查詢所有該實體 findAll()
taskRepository.findAll().forEach(task -> System.out.println(task.getName()));
// 根據ID刪除實體 deleteById(ID id)
taskRepository.deleteById(1L);
List<Task> findByStatus(String status);
// 上述會被映射為以下 SQL 查詢
SELECT * FROM task WHERE status = ?
上述命名規則可以使我們不用手動撰寫SQL查詢。
@Query("SELECT t FROM Task t WHERE t.assignedUser = ?1")
List<Task> findByAssignedUser(String username);
// 上述查詢將映射為以下SQL查詢
SELECT * FROM task WHERE assigned_user = ?1;
假設直接使用JDBC操作DB,程式碼會變得冗長,且還要在該程式內手動管理DB連線與處理結果:
private static final String URL = "jdbc:mysql://localhost:3306/yourdatabase";
private static final String USER = "root";
private static final String PASSWORD = "password";
// 根據ID查詢實體
public Task findById(Long id) {
Task task = null;
String query = "SELECT * FROM task WHERE id = ?";
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
task = new Task(rs.getLong("id"), rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return task;
}
// 查詢所有實體
public List<Task> findAll() {
List<Task> tasks = new ArrayList<>();
String query = "SELECT * FROM task";
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
tasks.add(new Task(rs.getLong("id"), rs.getString("name")));
}
} catch (SQLException e) {
e.printStackTrace();
}
return tasks;
}
由上述例子可清楚知道,Spring Data JPA的Repository介面簡化資料存取工作,不只提供基礎的資料庫操作功能,也能靈活查詢應用,可讀性及維護性大大的提升。我們只要專注於業務邏輯即可,不用花費額外時間撰寫繁瑣的資料存取操作。
同時補充,Spring Data JPA是Spring框架的功能,並非Spring Boot專有的,不過正如前幾篇所說,Spring Boot能整合大量配置使其自動化,因此,在Spring Boot專案中不需要手動做很多配置,若只是使用Spring框架,仍需額外配置像是EntityManager、資料庫連線、Transaction管理等。