一 JDBC的規範操作及問題回顧
假設數據庫test中有一張表account
直接使用JDBC,dao層的實現類可能會是如下的寫法:
public class AccountDaoImpl implements AccountDao {
//問題1:數據庫配置信息,存在硬編碼問題,修改信息就要重新編譯
private String driver = "com.mysql.jdbc.driver";
private String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf-8";
private String username = "root";
private String password = "root";
public List<Account> findAll() throws Exception{
//註冊mysql驅動
Class.forName(driver);
//問題2:頻繁獲取/釋放數據庫連接
Connection connection = DriverManager.getConnection(url, username, password);
//問題3:sql語句存在硬編碼,改動sql語句需要改動,另外拼接不同條件的sql語句,填充參數都比較繁瑣。
String sql = "select * from account";
//String sql = "select * from account where cardNo=?"
//獲取操作數據庫的預處理對象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
//preparedStatement.setInt(1,2);
List<Account> accountList = new ArrayList<Account>();
//問題4:需要手動解析結果集,如果表中的列很多會很繁瑣
while (resultSet.next()) {
Account account = new Account();
account.setCardNo(resultSet.getString("cardNo"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getInt("money"));
accountList.add(account);
}
resultSet.close();
preparedStatement.close();
connection.close();
return accountList;
}
}
從中可以分析出一些問題,並且我們也可以發現已有的對應解決方案:
-
數據庫配置信息,存在硬編碼問題。
解決:將配置信息寫入配置文件中,而Mybatis就有配置解析的功能,可以在運行時解析配置文件。
-
每次調用dao層方法都要建立和關閉數據庫連接,影響數據庫和應用的性能。
解決:利用數據庫連接池。
-
與sql語句有關的問題:
(1) sql語句硬編碼。
解決:Mybatis提供了sql解析的功能,允許調用方使用映射配置文件或者註解來編寫sql語句。
(2) 使用?佔位符進行參數的填充方式較爲繁瑣。
解決:Mybatis提供了參數映射的功能,允許調用方使用#{}或${}佔位符,直接在{}中寫要傳入的參數。
(3) 在實際業務中,對同一數據集的查詢條件可能是動態變化的,根據不同那個條件拼接SQL語句是一件非常麻煩的事情。
解決:Mybatis提供了動態sql功能,使拼接sql變得更加輕鬆。
-
需要手動解析結果集,如果表中的列很多會很繁瑣。
解決:基於ORM,Mybatis提供了結果集映射的功能,調用方不需要手動解析結果集。
ORM(Object Relational Mapping,對象-關係映射),包含對象->關係數據和關係數據->對象兩方面映射。Mybatis實際上只完成了關係數據->對象,也就是結果集映射的功能,並沒有完成對象->關係數據映射,不能像Hibernate一樣通過操縱java對象實現操縱數據庫表的目的,依然要編寫sql語句,因此Mybatis也被認爲是半自動的ORM框架。
Mybatis本質上也就是對jdbc進行了封裝,但是它作爲一個框架而非工具類,必定有它的強大之處。jdbc的這些解決方案中提到的Mybatis功能,會在之後章節的源碼分析中分別提及,接下來先對Mybatis的整體架構做一個概覽。
二 Mybatis整體架構概覽
Mybatis的設計也遵循了模塊化和分層的思想,整體架構分爲三層,如下圖所示:
接口層:核心是SqlSession接口,是上層應用和Mybatis交互的橋樑。SqlSession的創建過程還涉及SqlSessionFactoryBuilder和SqlSessionFactory,前者利用建造者模式創建後者,而後者是“單個數據庫映射關係經過編譯後的內存鏡像”。SqlSession接收調用請求後,會調用核心處理層的相應模塊進行具體的數據庫操作。
核心處理層:這一層基本上包含了上一節中提到了mybatis的功能,體現了完成一次數據庫操作所涉及的全部流程。
基礎支持層:這一層包含了Mybatis的基礎模塊,爲核心處理層的功能提供了良好的支持。
參考資料
徐郡明.mybatis技術內幕[m].北京:電子工業出版社,2017.