我們昨天已經快速地介紹了基本的三層式架構,(Controller、Service與Repository),但我今天想要再詳細一點地介紹當中的Repository。Repository掌管與資料庫之間互動的細節。
Spring與資料庫溝通的方式有很多種,你也許聽過JDBC、Spring JPA、Hibernate ORM等等,今天就會一一介紹他們。
JDBC是Java提供的API,它允許Java使用SQL查詢與更新資料庫,簡言之就是在Java裡面下SQL。而Spring Framework 本身提供了jdbcTemplate讓開發者可以以執行SQL的形式向資料庫溝通,要使用前,首先你會需要引入相關的依賴。
// 如果是maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
// 如果是gradle
implementation 'org.springframework:spring-jdbc:6.1.12'
引入之後,就可以開始開發JDBC的應用程式。另外,除了引入依賴外,SpringBoot的application.properties也必須要添加對應的設定,比方說如下
spring.datasource.url=jdbc:mysql://localhost:3306/school
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
從上到下分別是,資料庫的位址、資料庫的帳號與密碼、以及資料庫的datasource驅動程式。實際上,根據你使用的資料庫資訊會有些微差異
jdbcTemplate封裝了JDBC,並提供了一系列的實作,假設我想要建立一筆學生資料,JDBC大約是這樣寫的。
String sql = "INSERT INTO students (name, age, gender, class) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(sql, student.getName(), student.getAge(), student.getGender(), student.getStudentClass());
那假設我們想要查詢學生的資料、或是單一個值
String sql = "SELECT * FROM students WHERE id = ?";
Student student = jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) -> {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
student.setGender(rs.getString("gender"));
student.setStudentClass(rs.getString("class"));
return student;
});
這樣的用法其實並不是很好用,而且接收到物件必須要被重新處理(預設回傳的物件是ResultSet這個類型。),因此後面介紹的ORM就很好地克服了這一點。
ORM──全名為ObjectRelatedModel,就是以Java的物件(Object)直接對應至資料庫的表格(Model),省去繁複的物件比對功能。Java來說,Hibernate是最常見的ORM應用。主要有以下好處
● 生產力提升(Productivity):減少撰寫資料存取元件程式碼,聚焦在商業邏輯。
● 容易維護(Maintainability):程式碼較少,語法上來說比純SQL更容易維護。
● 效能調校(Performance):節省SQL語法除錯時間,多花時間調校SQL邏輯效能。
● 資料庫廠商的獨立性(Vendor independence):免除受限於特定廠商,開發者可於輕量資料庫上開發程式,部署時再安裝至正式的大型資料庫。
在Hibernate的定義中,與資料庫的一次對話被定義為一個Session,在一個Session中可以執行多個CRUD等等操作,舉例來說,一段Hibernate的程式碼會像這樣:
Student student = new Stduent();
student.setName("Johnson");
student.setAge(18);
// 開啟Session,相當於開啟JDBC的Connection
Session session = HibernateUtil.getSessionFactory().openSession();
// Transaction表示一個交易
Transaction tx= session.beginTransaction();
// 將物件映射至資料庫表格中儲存
session.save(user);
tx.commit();
session.close();
所以,Hibernate中一個與資料庫的溝通基本流程是這樣的:
Hibernate成功實現了以Java物件操作資料庫物件的可能性,後續的應用也都基於Hibernate之上開發的,比方說Spring Data JPA。
Spring Data JPA 封裝了 JDBC 與 Hibernate ORM,並使用方法名稱來Mapping資料庫。所以讓程式碼更加的簡單。舉例來說。
@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {
Student findByName(String name);
}
在這個方法中,你完全不必要撰寫SQL語法,就能夠透過方法名稱去取得資料庫中對應的資料,比方說用姓名找出學生資料等等。
以上就是今天的介紹,那我們明天見。