一切的管教,當時固然不覺得喜樂,反覺得愁苦;後來卻給那藉此受過操練的人,結出平安的義果。
在上面文章中,我們介紹 JDBC,JPA/Hibernat兩種方式來實作存取資料庫,在這一回中,我們介紹 MyBatis,MyBatis 與 Hibernat 各有千秋,其比較,就請讀者自行爬文,在 Hibernet 中,自行發展了 HQL 語言來取代 SQL,而且支援不同的資料庫系統,如 MySQL, Oracle, DB2... 這些不同的資料庫系統,SQL語言會有那麼一丁點的不同,這個不同,就會導致不能執行,而Hibernate 可以透過設定來解決這些問題,對於要界接不同資料庫系統的應用而言,可以省許多事;而在 Mybatis 中,還沿用 SQL (在 Hibernet 中,當然,還可以用 SQL,這就有點像…種族融合了,總是比較複雜一些),看起來簡單一些。
因為差異主要是在 Repository 這個部分,在這個領域裡,我們習慣稱作 Dao,所以我們將 UserRepository 改名 UserDao,Dao 習慣稱呼界面(interface), 如果讀者有強迫症,屬於要求完美整齊那一型,亦可命名 IUserDao。
@Mapper
public interface UserDao {
@Update("INSERT INTO USERS(name,email) VALUES(#{user.name}, #{user.email})")
void userAdd(@Param("user") User user);
@Select("SELECT * FROM users")
List<User> findAll();
}
直接把 SQL 指令放在函式前面,留意這是界面(interface), 而函式實際執行的編碼由 Spring Boot自動完成了, 注意,貼的符是 @Mapper,表示對應關係。這是假設資料庫中的欄位名稱與模型中User類別的資料成員名稱相同,若是名稱不相同時,也可以採用如 JDBC 中的 Mapper 的作法:
@Select("SELECT * FROM users")
@Results({
@Result(property = "class_name", column = "db_name", javaType = User.class),
@Result(property = "class_email", column = "db_email")
})
List<User> findAll();
column 指定在資料庫中的欄位名稱,在property 指定在類中定義的名稱,在第二個 Result 設定中,若與前面相同就可以省略。當然,這也可以寫成XML,在此就省略了。
也可以使用近似 JDBC的寫法:
int id=10
String sqlSelectUser = "SELECT * FROM USER WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(sqlSelectUser);
ps.setInt(1,id);
也可以將 SQL 指令放在 XML中,假設將 XML檔案放在 src/main/resources/mapper/ 之內。
則增加設定(src/main/resources/application.properties)
mybatis.mapper-locations=classpath:mapper/*.xml
以下是一個範例
src/main/resources/mapper/UserMapper.xml
也可以寫成