一、首先讓我們需要清楚原始JDBC存在哪些問題:
1、數據庫連接創建、釋放頻繁造成系統資源浪費,從而影響系統性能。如果使用數據庫連接池可解決此問題。
2、Sql語句在代碼中硬編碼,造成代碼不易維護,實際應用中sql變化的可能較大,sql變動需要改變java代碼。
3、使用preparedStatement向佔有位符號傳參數存在硬編碼,因爲sql語句的where條件不一定,可能多也可能少,修改sql還要修改代碼,系統不易維護。
4、對結果集解析存在硬編碼(查詢列名),sql變化導致解析代碼變化,系統不易維護,如果能將數據庫記錄封裝成POJO對象解析比較方便。
二、Mybatis架構:
關於Mybatis中,SqlMapConfig.xml是一個全局的配置,它的下面有很多的Mapper.xml,我們需要配置完Mapper.xml之後,配置加載到SqlMapConfig.xml中,之後能夠根據配置生成SqlSessionFactory會話工廠,由會話工廠可以創建會話SqlSession,在會話下面有executor執行器(基本執行器和緩衝執行器),執行器下面有mappedStatement,它是用來接收輸入參數的映射的,然後執行器根據輸入的java對象映射到SQL中,關於輸出參數的時候,是在執行完SQL之後將輸出結果映射到java對象中;
在瞭解到Mybatis的整體的架構之後,下面讓我們來搭建一個簡單的項目
首先,官網上下載Mybatis:
解壓之後:
我們在Eclipse中new一個工程,命名爲MybatisDemo,在lib下導入jar包:
接下來我們創建一個數據庫Mybatis,創建兩個表User和orders:
根據數據庫中各個屬性書寫User.java和Order.java並利用IDE生成get和set方法;
在src下面創建SqlMapConfig.xml:用於全局配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 和spring整合後 environments配置將廢除,學習Mybatis才用的 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理 --> <transactionManager type="JDBC" /> <!-- 數據庫連接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="" /> </dataSource> </environment> </environments> </configuration> |
在src下面創建log4j.properties;用於打印日誌;
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n |
在src下面建立一個com.xmlfolder包,裏面放入UserMapper.xml,配置完成後將其引入到SqlMapConfig.xml下;
寫一個簡單的功能,根據用戶ID查詢用戶的信息:
關於UserMaper.xml中的配置如下:
根據用戶名進行模糊查詢:使用like以及連接符;
關於佔位符和連接符:
插入數據:
更新數據:
根據用戶ID刪除數據:
關於Mybatis解決JDBC的問題如下:
Mybatis和Hibernate的不同:
Mybatis不完全是一個ORM框架,因爲Mybatis需要自己編寫SQL語句,Mybatis可以通過xml或者註解的方式靈活使用SQL語句,並將java對象和SQL語句映射生成最終的SQL語句,最後將SQL執行的結果再映射生成java對象;Mybatis更容易學習,支持程序員書寫原生SQL,靈活性比較好,適合對關係數據模型要求不高的軟件開發,Mybatis無法做到數據庫無關性;
Hibernate對象/關係映射能力強,數據無關性比較好,對於關係模型要求比較高的軟件,如果使用hibernate開發可以節省更多的代碼,提高效率;但是Hibernate的學習門檻高,要精通門檻更高,而且怎麼設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力纔行。
總之,按照用戶的需求在有限的資源環境下只要能做出維護性、擴展性良好的軟件架構都是好架構,所以框架只有適合纔是最好;
使用Mybatis開發Dao,通常有兩個方法,原始Dao開發和Mapper動態代理開發方法;
原始開發Dao;定義一個接口UserDao,如下:
書寫接口的實現方法
注入到service層中:(用一個簡單的Junit代替)
Dao方法體存在重複代碼:通過SqlSessionFactory創建SqlSession,調用SqlSession的數據庫操作方法
調用sqlSession的數據庫操作方法需要指定statement的id,這裏存在硬編碼,不得於開發維護。
SQLSession的使用範圍:
SQLSession中封裝了對數據庫的操作,如增刪改查;
SQLSession是通過SQLSessionFactory來創建的;
SQLSessionFactory是通過SqlSessionFactoryBuilder創建的;
SqlSessionFactoryBuilder用於創建一個SQLSessionFactory,SQLSessionFactory一旦創建就不需要SqlSessionFactoryBuilder了,因爲SQLsession是通過SQLSessionFactory創建的,因此可以把SqlSessionFactoryBuilder當成一個工具類進行使用,最佳使用範圍即方法體內使用局部變量;
Mapper動態代理方式:遵守四個原則
當在定義接口的過程中滿足上面的四個要求(namespace的名稱和接口綁定,id名稱等於方法名稱,入參類型以及出參類型和Xml中保持一致的時候),Mapper的動態代理就會自動生成代理對象,不需要在去new實現類;
SqlMapConfig.xml配置文件中,兩個常見屬性:properties和typeAliases
mappers(映射器):
<mapper resource="com/xmlfolder/UserMapper.xml">使用相對於類路徑的資源
<mapper class=" " />接口類路徑,此方法要求mapper接口和mapper映射文件名稱相同,且放在同一路徑下;