轉載:http://www.tuicool.com/articles/auaAru
iBatis 架構的主要優勢:
1、iBatis 封裝了絕大多數的 JDBC 樣闆代碼,使得開發者隻需關注 SQL 本身,而不需要花費精力去處理例如注冊驅動,建立 Connection,以及確定關閉 Connection 這樣繁雜的代碼。
2、從 iBatis 到 MyBatis,不隻是名稱上的變化,MyBatis 提供了更為強大的功能,同時并沒有損失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性進行了簡化
常用的 Java EE 架構,應該都知道這些架構需要提供一個全局配置檔案,用于指定程式正常運作所需的設定和參數資訊。而針對常用的持久層架構而言(Hibernate、JPA、iBatis 等),則通常需要配置兩類檔案:
一類用于指定資料源、事務屬性以及其他一些參數配置資訊(通常是一個獨立的檔案,可以稱之為全局配置檔案);
另一類則用于指定資料庫表和程式之間的映射資訊(可能不止一個檔案,我們稱之為映射檔案)。
MyBatis 也不例外,雖然其中的一部分可以通過注解的形式進行,但是這兩部分内容本身仍是必不可少的
MyBatis 全局配置檔案中可以配置的資訊主要包括如下幾個方面:
properties — 用于提供一系列的鍵值對組成的屬性資訊,該屬性資訊可以用于整個配置檔案中。
settings — 用于設定 MyBatis 的運作時方式,比如是否啟用延遲加載等。
typeAliases — 為 Java 類型指定别名,可以在 XML 檔案中用别名取代 Java 類的全限定名。
typeHandlers — 在 MyBatis 通過 PreparedStatement 為占位符設定值,或者從 ResultSet 取出值時,特定類型的類型處理器會被執行。
objectFactory — MyBatis 通過 ObjectFactory 來建立結果對象。可以通過繼承 DefaultObjectFactory 來實作自己的 ObjectFactory 類。
plugins — 用于配置一系列攔截器,用于攔截映射 SQL 語句的執行。可以通過實作 Interceptor 接口來實作自己的攔截器。
environments — 用于配置資料源資訊,包括連接配接池、事務屬性等。
mappers — 程式中所有用到的 SQL 映射檔案都在這裡列出,這些映射 SQL 都被 MyBatis 管理。
上面提及的大多數元素都不是必需的,通常 MyBatis 會為沒有顯式設定的元素提供預設值。
iBatis 2.x 和 MyBatis 3.0.x 的差別
1、 全局配置檔案命名
iBatis 通常把為 sqlMapConfig.xml,檔案名本身并沒有要求,在 MyBatis 中經常會将該檔案命名為 Configuration.xml
2、 全局配置檔案
<?xml version=”1.0″ encoding=”UTF-8″ ?> iBatis 和 MyBatis 的全局配置檔案使用不同的 DTD 限制,在将應用由 iBatis 更新至 MyBatis 時需要注意(兩者的映射檔案 DTD 限制也不相同)
<!DOCTYPE configuration PUBLIC “-//mybatis.org//DTD Config 3.0//EN” “http://mybatis.org/dtd/mybatis-3-config.dtd”>
<configuration>
<!– 配置資料源相關的資訊 –>
<environments default=”demo”>
<environment id=”demo”>
<transactionManager type=”JDBC”/>
<dataSource type=”POOLED”>
<property name=”driver” value= … />
<property name=”url” value= … />
<property name=”username” value=”root”/>
<property name=”password” value=”root”/>
</dataSource>
</environment>
</environments>
<!– 列出映射檔案 –>
<mappers>
<mapper resource=”footmark/mybatis/demo/UserInfoMapper.xml”/>
</mappers>
</configuration>
有了這些資訊,MyBatis 便能夠和資料庫建立連接配接,并應用給定的連接配接池資訊和事務屬性。
MyBatis 封裝了這些操作,最終暴露一個 SqlSessionFactory 執行個體供開發者使用,從名字可以看出來,
這是一個建立 SqlSession 的工廠類,通過 SqlSession 執行個體,開發者能夠直接進行業務邏輯的操作,
而不需要重複編寫 JDBC 相關的樣闆代碼。根據全局配置檔案生成 SqlSession 的代碼如下:
Reader reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
上面的三行代碼看做是 MyBatis 建立 SqlSession 的樣闆代碼。
其中第一行代碼在類路徑上加載配置檔案,Resources 是 MyBatis 提供的一個工具類,它用于簡化資源檔案的加載,它可以通路各種路徑的檔案,不過最常用的還是示例中這種基于類路徑的表示方式
在完成全局配置檔案,并通過 MyBatis 獲得 SqlSession 對象之後,便可以執行資料通路操作了
— 設定屬性的差別
iBatis :<settings props1=”value1″ props2=”value2″… />
MyBatis :<settings> <setting name=”props1″ value=”value1″/> <setting name=”props2″ value=”value2″/> …… </settings>
—配置事務管理器和資料源的差別
iBatis :
<transactionManager type=”JDBC” >
<dataSource type=”SIMPLE”>
<property name=”JDBC.Driver” value=”${driver}”/>
</dataSource>
</transactionManager>
MyBatis :
<environments default=”demo”>
<environment id=”demo”>
<transactionManager type=”JDBC”/>
<dataSource type=”POOLED”>
<property name=”JDBC.Driver” value=”${driver}”/>
</dataSource>
</environment>
</environments>
通過 <environments> 來進行資料源管理,主要是為了簡化在多套資料源配置之間的切換,比如開發和釋出使用不同的配置。
3、 在映射檔案中配置 SQL 語句
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE mapper PUBLIC “-//mybatis.org//DTD Mapper 3.0//EN” “http://mybatis.org/dtd/mybatis-3-mapper.dtd”>
<mapper namespace=”mybatis.demo.UserInfoMapper”>
<select id=”selectUser” parameterType=”int” resultType=”mybatis.demo.UserInfo”>
select * from UserInfo where userid =#{userid}
</select>
</mapper>
在 iBatis 中,namespace 不是必需的,且它的存在沒有實際的意義。在 MyBatis 中,namespace 終于派上用場了,它使得映射檔案與接口綁定變得非常自然
—指定映射檔案的方式的差別
iBatis:<sqlMap resource=… /> <sqlMap resource=… /> <sqlMap resource=… />
MyBatis :<mappers> <mapper resource=… /> <mapper resource=… /> </mappers>
4、 使用 SqlSession 執行映射檔案中配置的 SQL 語句
try {
UserInfo userinfo = (UserInfo) sqlSession.selectOne (“mybatis.demo.UserInfoMapper.getUser”, 2);
System.out.println(userinfo);
} finally {
sqlSession.close();
}
需要注意的是,SqlSession 的使用必需遵守上面的格式,即在 finally 塊中将其關閉。以保證資源得到釋放,防止出現記憶體洩露!
5、 在 MyBatis 中使用代碼進行配置
DataSource ds = …… // 擷取一個 DataSource
TransactionFactory txFactory = new JdbcTransactionFactory();
Environment env = new Environment(“demo”, txFactory, ds);
Configuration cfg = new Configuration(env);
cfg.addMapper(UserInfoMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);
結合前面的配置檔案,很容易了解這段代碼的意思,故不再贅述。不過,需要注意的是 Configuration 的 addMapper() 方法,該方法的參數通常是一個接口,可以在接口裡面定義若幹方法,在方法上使用注解來指定映射的 SQL 語句。一個典型的接口定義以及對應的資料通路方法如下:
6、 将映射的 SQL 語句與接口中的方法綁定
// 映射 SQL 綁定接口
public interface UserInfoMapper {
@Select(“select * from userinfo where userid = #{userid}”)
public UserInfo getUserInfo(int userid);
}
// 接口綁定對應的資料通路方法
try {
//UserInfo userinfo = (UserInfo) sqlSession.selectOne (“mybatis.demo.UserInfoMapper.selectUser”, 2);
UserInfoMapper userinfoMapper = sqlSession.getMapper(UserInfoMapper.class);
UserInfo userinfo = userinfoMapper.getUserInfo(1);
System.out.println(userinfo);
} finally {
sqlSession.close();
}
7、 MyBatis 映射檔案的改變 (僅僅是名稱的改變,用法和含義并沒有發生變化)
和全局配置檔案一樣,由于 DTD 限制發生變化,根元素也由原來的 <sqlMap> 調整為 <mapper>。
<select> 等元素的 parameterClass 屬性改為了 parameterType 屬性。
<select> 等元素的 resultClasss 屬性改為了 resultType 屬性。
<parameterMap> 等元素的 class 屬性改為了 type 屬性。
<result> 元素的 columnIndex 屬性被移除了。
嵌套參數由 #value# 改為了 #{value}。
<parameter> 等元素的 jdbcType 屬性取值中,原來的 “ORACLECURSOR” 取值改為了現在的 “CURSOR”,”NUMBER” 取值改為了 “NUMERIC”。
iBatis/MyBatis 對存儲過程的支援一直是值得稱道的。之前通過使用 <procedure> 元素進行存儲過程的定義,示例如下:
— 存儲過程的差別
iBatis:
<procedure id=”getValues” parameterMap=”getValuesPM”>
{ ? = call pkgExample.getValues(p_id => ?) }
</procedure>
MyBatis :
<select id=”getValues” parameterMap=”getValuesPM” statementType=”CALLABLE”>
{ ? = call pkgExample.getValues(p_id => ?)}
</select>
通過 statementType 屬性将該語句辨別為存儲過程而非普通 SQL 語句
8、代碼層面的改變
MyBatis 在編碼中的最大的改變就是将一個最常用的 API 由 SqlMapClient 改為了 SqlSessionFactory。
另外,類型處理器接口也由原來的 TypeHandlerCallback 改為了 TypeHandler。
最後 DataSourceFactory 也進行了調整,移動到 org.apache.ibatis.datasource 包下,其中的方法也作了微調。總之,代碼層面公開的部分改動較少,不會給開發者造成較大的移植成本