国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

深入淺析Mybatis的缺陷問題

2019-11-26 13:38:33
字體:
供稿:網(wǎng)友

Mybatis是業(yè)界非常流行的持久層框架,輕量級、易用,在金融IT領域完全是領軍地位,比Hibernate更受歡迎,優(yōu)勢非常多,也是非常值得我們學習的。但Mybatis并不盡善盡美,其自身的設計、編碼也還有許多不足,甚至是缺陷,這篇文章來簡要討論一下這些缺陷:

1.Mybatis使用DTD作為XML配置文件的校驗文件,但是很明顯,DTD差不多是快被淘汰的技術了,功能非常有限,擴展性非常差,擴展性非常差,擴展性非常差,可讀性也不好,Spring能夠從DTD到XSD華麗轉(zhuǎn)身,但Mybatis始終沒這個魄力。

2.版本兼容性做的不好,就拿3.3.0―>3.4.0來說,按業(yè)界通用規(guī)范,第2級版本號升級,可以添加功能,但是要保證向下兼容性,然而Mybatis的做法并不完全是這樣的,看一下關鍵接口StatementHandler的關鍵方法prepare:

// 3.3.0Statement prepare(Connection connection)throws SQLException;// 3.4.0Statement prepare(Connection connection, Integer transactionTimeout)throws SQLException;

這里沒有添加一個方法,而是直接在原方法中添加了一個參數(shù)!類似例子還有不少,就不一一列舉了。

3.Mybatis的插件,采用一個通用的Interceptor接口,配以@Intercepts、@Signature等注解,實現(xiàn)對多個組件的多種方法的攔截,看似非常靈活,在我看來其實是結(jié)構(gòu)不夠清晰,實際開發(fā)時,你會把對StatementHandler和ResultSetHandler的攔截增強放在一個類里面嗎?不會是吧(會?你當單一職責原則、開閉原則都是狗屎嗎),那有什么必要強制使用同一個接口呢?

另外,使用@Signature注解來設別需要被攔截的組件方法,如果注解有錯,編譯也是不會報錯的,而只能等到運行時才能發(fā)現(xiàn),再看上面的例子:

假設我針對3.3.0版本實現(xiàn)了一個插件:

@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class })})public class StatementHandlerInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {return invocation.proceed();}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}}

然后,升級為3.4.0,結(jié)果呢,編譯一直正常,但是等到運行,卻拋出異常了。

4.Mybatis的緩存簡直就是雞肋,而且不管有沒有配置需要使用緩存、是否更新緩存,都要去計算CacheKey,不使用緩存、也不更新緩存的情況下,這種計算完全是浪費。

5.Mybatis的批量執(zhí)行,看下面的一個JDBC例子:

public void testJdbcBatch(Connection conn) throws Exception {try{conn.setAutoCommit(false);batchUpdate(conn);clearTestData(conn);conn.commit();conn.setAutoCommit(true);}catch(Exception e){conn.rollback();throw e;}}private void clearTestData(Connection conn) throws SQLException {PreparedStatement ps = null;try{ps = conn.prepareStatement("delete TABLE_NAME1 where FIELD_NAME1 = ? ");ps.setString(1, "TEST");int d = ps.executeUpdate();System.out.println("delete counts : " + d);}finally{try{ps.close();}catch(Exception e){}}}private void batchUpdate(Connection conn) throws SQLException {PreparedStatement ps = null;try{String sql = "INSERT INTO TABLE_NAME2(FIELD_NAME1, FIELD_NAME2, FIELD_NAME2)VALUES(?,?,?)";ps = conn.prepareStatement(sql);for(int i = 0; i < 10; i++){String random = RandomStringUtils.randomAlphabetic(8);ps.setString(1, "TEST");//FIELD_NAME1ps.setString(2, "數(shù)據(jù)" + random);//FIELD_NAME2ps.setString(3, "參數(shù)" + random);//FIELD_NAME3ps.addBatch();}int[] rs = ps.executeBatch();}finally{try{ps.close();}catch(Exception e){}}}

代碼沒有什么違和感,能夠執(zhí)行正常,也可以按預期的回滾,也就是說同一個事務中的同一個connection,可以同時運行普通sql和batch,但是你在同一個事務的SqlSession中試試,反饋給你的是――不能在同一個事務中切換執(zhí)行方式!

6、數(shù)據(jù)庫產(chǎn)品的兼容性:Mybatis把SQL的控制權交給了開發(fā)人員,于是從道德上占據(jù)了制高點――你寫的不兼容,那是你自己的水平不行!但,這是一個真正的優(yōu)秀框架的正確姿勢嗎?為什么就不能提供一些輔助性的兼容實施?比如說在Oracle中被奉為神明的DECODE函數(shù),是否可以在SqlMapper中提供一個<decode>標簽,在后面默默的修改成CASE WHEN?或者說,官方不提供沒有關系,但你得提供擴展方式啊,于是又回到了:擴展性非常差,擴展性非常差,擴展性非常差。重要的事說三遍,但,我已經(jīng)說六遍了。

以上所述是小編給大家介紹的Mybatis的缺陷問題,希望對大家有所幫助!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 西丰县| 会昌县| 屏东县| 兴安盟| 吉首市| 凭祥市| 吴桥县| 阳原县| 华容县| 昔阳县| 芷江| 谢通门县| 固镇县| 塔河县| 酒泉市| 九龙坡区| 嘉禾县| 运城市| 兴文县| 镇江市| 东山县| 兴化市| 湖南省| 体育| 全椒县| 合江县| 东兰县| 合阳县| 曲阳县| 灵寿县| 凤庆县| 托克托县| 闵行区| 恭城| 金秀| 云梦县| 濮阳市| 易门县| 荆州市| 黄山市| 贵港市|