舊調重彈Hibernate與Ibatis區別——深入架構設計
對於一個粗學者而言一言概況就是:ibatis非常簡單易學,hibernate相對較復雜,門檻較高。
但是,hibernate對數據庫結構提供了較為完整的封裝,hibernate的o/r mapping實現了pojo 和數據庫表之間的映射,以及sql 的自動生成和執行。程序員往往只需定義好了pojo 到數據庫表的映射關系,即可通過hibernate 提供的方法完成持久層操作。程序員甚至不需要對sql 的熟練掌握, hibernate/ojb 會根據制定的存儲邏輯,自動生成對應的sql 並調用jdbc 接口加以執行。 hibernate把數據庫和你隔離了,你不需要關註數據庫是mysql還是oracle,hibernate來幫你生成查詢的sql。但問題也來了,如果你就要用某種數據庫特有的功能,或者你就要讓查詢的sql完全符合你的心意,這就難了。
因為hibernate則基本上可以自動生成,偶爾會寫一些hql。同樣的需求,ibatis的工作量比hibernate要大很多。類似的,如果涉及到數據庫字段的修改,hibernate修改的地方很少,而ibatis要把那些sql mapping的地方一一修改。而且,從文檔的豐富性,產品的完善性,版本的開發速度都要強於ibatis。
眾所周知,web開發,性能瓶頸在數據庫。比如12306,我覺得瓶頸還是在數據庫。
系統數據處理量巨大,性能要求極為苛刻,這往往意味著我們必須通過經過高度優化的sql語句(或存儲過程)才能達到系統性能設計指標。在這種情況下ibatis會有更好的可控性和表現。 具體參考《Hibernate與Ibatis比較》——ibatis原理淺析
-
iBATIS沒有對你的數據庫模型和對象模型的設計做任何假設。不論你的應用中這兩個模型之間是多麽不匹配,iBATIS都能適用。更進一步,iBATIS沒有對你的企業級應用的架構做出任何假設。不論你對數據庫是根據業務功能縱向劃分,還是按照技術橫向劃分,iBATIS都允許你高效地處理數據並將它們整合到你的面向對象的應用中去。
-
iBATIS的某些特性使得它能夠非常高效地處理大型數據集。iBATIS支持的行處理器(row handler)使得它能夠批處理超大型記錄集,一次一條記錄。iBATIS也支持只獲取某個範圍內的結果,這就使得你可以只獲取那些你當前亟需的數據。例如,假設你獲取了10,000條記錄,而你其實只需要其中的第500至600條,那你就可以簡單的僅獲取這些記錄。iBATIS支持驅動提示使得執行這樣的操作非常高效。
-
iBATIS允許你用多種方式建立從對象到數據庫的映射關系。一個企業級系統只以一種模式工作的情況是非常少見的。許多企業級系統需要在白天執行事務性的工作,而在晚上執行批處理工作。iBATIS允許你將同一個類以多種方式映射,以保證每一種工作都能以最高效的方式執行。iBATIS同樣支持多種數據獲取策略。例如,你可以選擇對某些數據進行懶加載,也可以將一個復雜的對象圖只用一條聯合查詢SQL語句就同時加載完畢,從而避免嚴重的性能問題。
對於我個人來說,我首選ibatis。比如之前寫jsp,我就堅決不屑於JSTL,你可以用intelliJ idea 智能提示快速開發。至於hql,shift……
二者配置都差不多!無非就是:
-
編寫配置文檔 hibernate.cfg.xml或SqlMapConfig.xml:
-
穿件對象—關系映射文件,
-
編寫實體類(每一個實體類都是和數據庫中的一張表是一一對應的的,設計遵循:javabean規範)
-
生成對應實體類的映射文件並添加到1中的配置文檔
這裏科普下IBatis的詳細配置及使用情況!節選自趙四的:iBatis開發的一個應用
下面是ibatis全局的文件:SqlMapConfig.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- 配置數據庫連接 --> <transactionManager type="JDBC" commitRequired="false"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/> <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/> <property name="JDBC.Username" value="root"/> <property name="JDBC.Password" value="jiangwei"/> <property name="Pool.MaximumActiveConnections" value="10" /> <property name="Pool.MaximumIdleConnections" value="5" /> <property name="Pool.MaximumCheckoutTime" value="120000" /> <property name="Pool.TimeToWait" value="500" /> <property name="Pool.PingQuery" value="select 1 from account" /> <property name="Pool.PingEnabled" value="false" /> <property name="Pool.PingConnectionsOlderThan" value="1" /> <property name="Pool.PingConnectionsNotUsedFor" value="1" /> </dataSource> </transactionManager> <!-- 配置SQL查詢的配置文件的Account.xml --> <sqlMap resource="/Account.xml"/> </sqlMapConfig>
對於上面的數據源配置的參數說明:
-
transactionManager節點定義了iBatis的事務管理器,提供三種方式
JDBC、jta:分布式數據庫、EXTERNAL:itbatis本身不做事務處理由外部進行處理
-
dataSource節點:從屬於transactionManager節點,用於設定ibatis運行期使用的DataSource屬性;
-
type屬性:type屬性指定了dataSource的實現模式,共三種模式,
1、simple:ibatis提供的較小的連接池
2、dbcp:是apache實現的連接池
3、jndi:tomcate或weblogic提供的服務
-
JDBC.Driver:JDBC驅動;
-
JDBC.ConnectionURL:數據庫連接URL,如果用的是SQLServer JDBC Driver,需要在url後追加SelectMethod=Cursor以獲得JDBC事務的多Statement支持;
-
JDBC.Username:數據庫用戶名;
-
JDBC.Password:數據庫用戶密碼;
-
Pool.MaximumActiveConnections:數據庫連接池可維持的最大容量;
-
Pool.MaximumIdleConnections:數據庫連接池中允許的掛起(idle)連接數;
-
Pool.MaximumCheckoutTime數據庫連接池中,連接被某個任務所允許占用的最大時間,如果超過這個時間限定,連接將被強制收回,(毫秒);
-
Pool.TimeToWait:當線程試圖從連接池中獲取連接時,連接池中無可用連接可供使用,此時線程將進入等待狀態,直到池中出現空閑連接。此參數設定了線程所允許等待的最長時間,(毫秒);
-
Pool.PingQuery:數據庫連接狀態檢測語句。某些數據庫在某段時間持續處於空閑狀態時會將其斷開。而連接池管理器將通過此語句檢測池中連接是否可用,
-
檢測語句應該是一個最簡化的無邏輯SQL。如“select 1 from user”,如果執行此語句成功,連接池管理器將認為此連接處於可用狀態;
-
Pool.PingEnabled:是否允許檢測連接狀態;
-
Pool.PingConnectionsOlderThan:對持續連接時間超過設定值(毫秒)的連接進行檢測;
-
Pool.PingConnectionsNotUsedFor:對空閑超過設定值(毫秒)的連接進行檢測;
再看看Hibernate配置文件
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="foo"> <!-- 1. 配置數據庫信息 --> <!-- 方言(連接的數據庫類型) --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.url">jdbc:mysql:///hibernate_20160926</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="connection.password">yezi</property> <!-- 2. 其他配置 --> <!-- 顯示生成的SQL語句 --> <property name="hibernate.show_sql">true</property> <!-- 3. 導入映射文件 --> <mapping resource="cn/itcast/a_helloworld/User.hbm.xml" /> </session-factory> </hibernate-configuration>
這裏只是參考對比下而已,沒有必要較真!
第二步,配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Account">//命名空間 <!-- 給Account實體類起一個別名 --> <typeAlias alias="Account" type="com.ibatis.demo.domain.Account"/> <!-- 將Account實體類中的屬性和mysql中的account表中的字段對應起來 --> <resultMap id="AccountResult" class="Account"> <result property="id" column="_id"/> <result property="firstName" column="first_name"/> <result property="lastName" column="last_name"/> <result property="emailAddress" column="emall"/> </resultMap> <!-- 查詢account表中所有數據,其中id是這條查詢語句的id號,在代碼中用到,具有唯一性 --> <select id="selectAllAccounts" resultMap="AccountResult"> select * from account </select> <!-- 通過id來查詢account表中的數據 --> <select id="selectAccountById" parameterClass="int" resultClass="Account"> select id as _id, first_name as firstName, last_name as lastName, emall as emailAddress from account where _id = #id# </select> <!--插入語句--> <insert id="insertAccount" parameterClass="Account"> insert into accout ( _id, first_name, last_name, emall values ( #id#, #firstName#, #lastName#, #emailAddress# ) </insert> <!-- 更新語句 --> <update id="updateAccount" parameterClass="Account"> update account set first_name = #firstName#, last_name = #lastName#, emall = #emailAddress# where _id = #id# </update> <!-- 刪除語句 --> <delete id="deleteAccountById" parameterClass="int"> delete from account where _id = #id# </delete> </sqlMap>
hibernate的:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.a_helloworld"> <class name="account" table="account"> <id name="id" type="int" column="id"> <generator class="native"/> </id> <property name="firstName" type="string" column="first_name" /> <property name="lastName" type="string" column="last_name" /> <property name="emailAddress" type="string" column="emall" /> </class> </hibernate-mapping>
創建實體類,其實就是javaBean,沒有什麽好說的。
再看看iBatis訪問數據的類:
package com.ibatis.demo.data; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; import com.ibatis.common.resources.Resources; import com.ibatis.demo.domain.Account; import java.io.Reader; import java.io.IOException; import java.util.List; import java.sql.SQLException; public class IbaitsData { private static SqlMapClient sqlMapper; static { try { //讀取iBatis的配置文件:SqlMapConfig.xml Reader reader = Resources.getResourceAsReader("/SqlMapConfig.xml"); sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e); } } //查詢account表中的所有記錄 @SuppressWarnings("unchecked") public static List selectAllAccounts () throws SQLException { return sqlMapper.queryForList("selectAllAccounts"); } //查詢account表中_id為id的記錄 public static Account selectAccountById (int id) throws SQLException { return (Account) sqlMapper.queryForObject("selectAccountById", id); } //插入一條記錄 public static void insertAccount (Account account) throws SQLException { sqlMapper.insert("insertAccount", account); } //更新一條記錄 public static void updateAccount (Account account) throws SQLException { sqlMapper.update("updateAccount", account); } //刪除一條記錄 public static void deleteAccount (int id) throws SQLException { sqlMapper.delete("deleteAccount", id); } }
但是,到這裏就不想再對比了。個人覺得ibatis比hibernate簡單。畢竟寫slq就可以了。
下面是Ibatis項目結構圖!
參考文章:
Hibernate與Ibatis比較
【SSH進階之路】Hibernate基本原理(一)
【SSH進階之路】Hibernate搭建開發環境+簡單實例(二)
iBatis開發的一個應用
Hibernate框架基礎——Hibernate入門
文章內容如有侵權,請告知以悉刪除,謝謝!
舊調重彈Hibernate與Ibatis區別--深入架構設計 - java連接數據庫 - 周陸軍的個人網站
轉載註明來源。
舊調重彈Hibernate與Ibatis區別——深入架構設計