久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Hibernate和MyBatis有哪些區別

128次閱讀
沒有評論

共計 7697 個字符,預計需要花費 20 分鐘才能閱讀完成。

這篇文章主要介紹“Hibernate 和 MyBatis 有哪些區別”,在日常操作中,相信很多人在 Hibernate 和 MyBatis 有哪些區別問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Hibernate 和 MyBatis 有哪些區別”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

測試目標

以下測試需要確定幾點內容:

性能差異的場景;

性能不在同場景下差異比;

找出各架框優劣,各種情況下的表現,適用場景。

測試思路

測試總體分成:單表插入,關聯插入,單表查詢,多表查詢。

測試分兩輪,同場景下默認參數做一輪,調優做強一輪,橫縱對比分析了。

測試中盡保證輸入輸出的一致性。

樣本量盡可能大, 達到 10 萬級別以上,減少統計誤差。

測試提綱

具體的場景情況下

插入測試 1:10 萬條記錄插入。

查詢測試 1:100 萬數據中單表通過 id 查詢 100000 次, 無關聯字段。

查詢測試 2:100 萬數據中單表通過 id 查詢 100000 次, 輸出關聯對象字段。

查詢測試 3:100 萬 *50 萬關聯數據中查詢 100000 次, 兩者輸出相同字段。

準備

數據庫:mysql 5.6

表格設計:

twitter: 推特

CREATE TABLE `twitter` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `add_date` datetime DEFAULT NULL, `modify_date` datetime DEFAULT NULL, `ctx` varchar(255) NOT NULL, `add_user_id` bigint(20) DEFAULT NULL, `modify_user_id` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `UPDATE_USER_FORI` (`modify_user_id`), KEY `ADD_USER_FORI` (`add_user_id`), CONSTRAINT `ADD_USER_FORI` FOREIGN KEY (`add_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL, CONSTRAINT `UPDATE_USER_FORI` FOREIGN KEY (`modify_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL ) ENGINE=InnoDB AUTO_INCREMENT=1048561 DEFAULT CHARSET=utf8

user: 用戶

CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=524281 DEFAULT CHARSET=utf8

測試數據準備:

表一:twitter

無數據。

表二:user

50 萬個隨機的用戶名。

隨機內容推特表(material_twitter)

無 id,僅有隨機字符串內容,共 10 萬條。

用于插入控推特表。

生成數據代碼, 關聯 100 個用戶:

insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date) SELECT name,ROUND(RAND()*100)+1,ROUND(RAND()*100)+1, 2016-12-31 , 2016-12-31  from MATERIAL

生成數據代碼, 關聯 500000 個用戶:

insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date) SELECT name,ROUND(RAND()*500000)+1,ROUND(RAND()*500000)+1, 2016-12-31 , 2016-12-31  from MATERIAL

實體代碼

@Entity @Table(name =  twitter) public class Twitter implements java.io.Serializable{ private Long id; private Date add_date; private Date modify_date; private String ctx; private User add_user; private User modify_user; private String createUserName; @Id @GeneratedValue(strategy = IDENTITY) @Column(name =  id , unique = true, nullable = false) public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Temporal(TemporalType.DATE) @Column(name =  add_date) public Date getAddDate() { return add_date; } public void setAddDate(Date add_date) { this.add_date = add_date; } @Temporal(TemporalType.DATE) @Column(name =  modify_date) public Date getModifyDate() { return modify_date; } public void setModifyDate(Date modify_date) { this.modify_date = modify_date; } @Column(name =  ctx) public String getCtx() { return ctx; } public void setCtx(String ctx) { this.ctx = ctx; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name =  add_user_id) public User getAddUser() { return add_user; } public void setAddUser(User add_user) { this.add_user = add_user; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name =  modify_user_id) public User getModifyUser() { return modify_user; } public void setModifyUser(User modify_user) { this.modify_user = modify_user; } @Transient public String getCreateUserName() { return createUserName; } public void setCreateUserName(String createUserName) { this.createUserName = createUserName; } }

開始

插入測試 1

代碼操作:

將隨機內容推特表的數據加載到內存中, 然后一條條加入到推特表中, 共 10 萬條。

關鍵代碼:

hibernate:

Session session = factory.openSession(); session.beginTransaction(); Twitter t = null; Date now = new Date(); for(String materialTwitter : materialTwitters){ // System.out.println( materialTwitter= +materialTwitter); t = new Twitter(); t.setCtx(materialTwitter); t.setAddDate(now); t.setModifyDate(now); t.setAddUser(null); t.setModifyUser(null); session.save(t); } session.getTransaction().commit();

mybatis:

Twitter t = null; Date now = new Date(); for(String materialTwitter : materialTwitters){ // System.out.println( materialTwitter= +materialTwitter); t = new Twitter(); t.setCtx(materialTwitter); t.setAddDate(now); t.setModifyDate(now); t.setAddUser(null); t.setModifyUser(null); msession.insert(insertTwitter , t); } msession.commit();

TwitterMapper.xml, 插入代碼片段:

insert id= insertTwitter  keyProperty= id  parameterType= org.pushio.test.show1.entity.Twitter  useGeneratedKeys= true  insert into twitter(ctx, add_date,modify_date) values (#{ctx},#{add_date},#{modify_date})  /insert

查詢測試 1

通過 id 從 1 遞增到 10 萬依次進行查詢推特內容,僅輸出微博內容。

關鍵代碼:

hibernate:

long cnt = 100000; for(long i = 1; i  = cnt; ++i){ Twitter t = (Twitter)session.get(Twitter.class, i); //System.out.println(t.getCtx= + t.getCtx() +   t.getUser.getName=  + t.getAddUser().getName()); }

mybatis:

long cnt = 100000; for(long i = 1; i  = cnt; ++i){ Twitter t = (Twitter)msession.selectOne(getTwitter , i); //System.out.println(t.getCtx= + t.getCtx() +   t.getUser.getName=  + t.getAddUser().getName()); }

查詢測試 2

與查詢測試 1 總體一樣,增加微博的創建人名稱字段, 此處需要關聯。

其中微博對應有 10 萬個用戶。可能一部份用戶重復。這里對應的用戶數可能與 hibernate 配懶加載的情況有影響。

此處體現了 hibernate 的一個方便處,可以直接通過 getAddUser()可以取得 user 相關的字段。

然而 myBatis 則需要編寫新的 vo,因此在測試 batis 時則直接在 Twitter 實體中增加創建人員名字成員(createUserName)。

此處 hibernate 則會分別測試有懶加載,無懶加載。

mybatis 會測有默認與有緩存兩者情況。

其中 mybatis 的緩存機制比較難有效配置,不適用于真實業務(可能會有臟數據),在此僅供參考。

測試時,對推特關聯的用戶數做了兩種情況,一種是推特共關聯了 100 個用戶,也就是不同的推特也就是在 100 個用戶內,這里的關聯關系隨機生成。

另外一種是推特共關聯了 50 萬個用戶,基本上 50 個用戶的信息都會被查詢出來。

在上文“準備”中可以看到關聯數據生成方式。

關鍵代碼:

hibernate:

long cnt = 100000; for(long i = 1; i  = cnt; ++i){ Twitter t = (Twitter)session.get(Twitter.class, i); t.getAddUser().getName();// 加載相應字段  //System.out.println(t.getCtx= + t.getCtx() +   t.getUser.getName=  + t.getAddUser().getName()); }

急懶加載配置更改處,Twitter.java:

@ManyToOne(fetch = FetchType.EAGER)// 急加載  //@ManyToOne(fetch = FetchType.LAZY)// 懶加載  @JoinColumn(name =  add_user_id) public User getAddUser() { return add_user; }

mybatis:

for(long i = 1; i  = cnt; ++i){ Twitter t = (Twitter)msession.selectOne(getTwitterHasUser , i); //System.out.println(t.getCtx= + t.getCtx() +   t.getUser.getName=  + t.getCreateUserName()); }

TwitterMapper.xml 配置:

select id= getTwitterHasUser  parameterType= long  resultType= org.pushio.test.show1.entity.Twitter  select twitter.*,user.name as creteUserName from twitter,user where twitter.id=#{id} AND twitter.add_user_id=user.id  /select

測試結果

測試分析

測試分成了插入,單表查詢,關聯查詢。關聯查詢中 hibernate 分成三種情況進行配置。其中在關聯字段查詢中,hibernate 在兩種情況下,性能差異比較大。都是在懶加載的情況下,如果推特對應的用戶比較多時,則性能會比僅映射 100 個用戶的情況要差很多。

換而言之,如果用戶數量少 (關聯的總用戶數) 時,也就是會重復查詢同一個用戶的情況下,則不需要對用戶表做太多的查詢。其中通過查詢文檔后,證明使用懶加載時,對象會以 id 為 key 做緩存,也就是查詢了 100 個用戶后,后續的用戶信息使用了緩存,使性能有根本性的提高。甚至要比 myBatis 更高。

如果是關聯 50 萬用戶的情況下, 則 hibernate 需要去查詢 50 萬次用戶信息, 并組裝這 50 萬個用戶,此時性能要比 myBatis 性能要差,不過差異不算大,小于 1ms,表示可以接受。其中 hibernate 非懶加載情況下與 myBatis 性能差異也是相對其他測試較大,平均值小于 1ms。

這個差異的原因主要在于,myBatis 加載的字段很干凈,沒有太多多余的字段,直接映身入關聯中。反觀 hibernate 則將整個表的字都會加載到對象中,其中還包括關聯的 user 字段。

hibernate 這種情況下有好有壞,要看具體的場景,對于管理平臺,需要展現的信息較多,并發要求不高時,hibernate 比較有優勢。

然而在一些小活動,互聯網網站,高并發情況下,hibernate 的方案太不太適合,myBatis+VO 則是首選。

測試總結

總體初觀,myBatis 在所有情況下,特別是插入與單表查詢,都會微微優于 hibernate。不過差異情況并不明顯,可以基本忽略差異。差異比較大的是關聯查詢時,hibernate 為了保證 POJO 的數據完整性,需要將關聯的數據加載,需要額外地查詢更多的數據。這里 hibernate 并沒有提供相應的靈活性。

關聯時一個差異比較大的地方則是懶加載特性。其中 hibernate 可以特別地利用 POJO 完整性來進行緩存,可以在一級與二級緩存上保存對象,如果對單一個對象查詢比較多的話,會有很明顯的性能效益。以后關于單對象關聯時,可以通過懶加載加二級緩存的方式來提升性能。

最后,數據查詢的性能與 orm 框架關無太大的關系,因為 orm 主要幫助開發人員將關系數據轉化成對象型數據模型,對代碼的深析上來看,hibernate 設計得比較重量級,對開發來說可以算是重新開發了一個數據庫,不讓開發去過多關心數據庫的特性,直接在 hibernate 基礎上進行開發,執行上分為了 sql 生成,數據封裝等過程,這里花了大量的時間。

然而 myBatis 則比直接,主要是做關聯與輸出字段之間的一個映射。其中 sql 基本是已經寫好,直接做替換則可,不需要像 hibernate 那樣去動態生成整條 sql 語句。

好在 hibernate 在這階段已經優化得比較好,沒有比 myBatis 在性能上差異太多,但是在開發效率上,可擴展性上相對 myBatis 來說好太多。最后的最后,關于 myBatis 緩存,hibernate 查詢緩等,后續會再專門做一篇測試。

關于緩存配置

myBatis 相對 Hibernate 等封裝較為嚴密的 ORM 實現而言, 因為 hibernate 對數據對象的操作實現了較為嚴密的封裝,可以保證其作用范圍內的緩存同步,而 ibatis 提供的是半封閉的封裝實現,因此對緩存的操作難以做到完全的自動化同步。以上的緩存配置測試僅為性能上的分析,沒有加入可用性上的情況,因為 myBatis 直接配置緩存的話,可能會出現臟數據。

在關聯查詢數據的情況下,hiberntae 的懶加載配二級緩存是個比較好的方案(無臟數據),也是與 myBatis 相比有比較明顯的優勢。此情景下,性能與 myBatis 持平。

在真實情況下,myBatis 可能不會在這個地方上配置緩存, 會出現臟數據的情況,因而很有可能在此 hibernate 性能會更好。

到此,關于“Hibernate 和 MyBatis 有哪些區別”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-27發表,共計7697字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 师宗县| 会昌县| 饶平县| 娄烦县| 卢龙县| 股票| 称多县| 高碑店市| 黎川县| 庆安县| 藁城市| 巴青县| 郑州市| 安塞县| 梁平县| 兰溪市| 剑阁县| 象山县| 尉犁县| 万年县| 确山县| 班玛县| 侯马市| 泰州市| 龙门县| 定兴县| 正镶白旗| 郧西县| 伊川县| 信阳市| 宜城市| 建宁县| 金坛市| 探索| 安龙县| 黑山县| 银川市| 泸溪县| 大田县| 呈贡县| 登封市|