深入浅析Mybatis的缺陷问题

作者:mrr 时间:2023-07-19 19:39:46 

Mybatis是业界非常流行的持久层框架,轻量级、易用,在金融IT领域完全是领军地位,比Hibernate更受欢迎,优势非常多,也是非常值得我们学习的。但Mybatis并不尽善尽美,其自身的设计、编码也还有许多不足,甚至是缺陷,这篇文章来简要讨论一下这些缺陷:

1.Mybatis使用DTD作为XML配置文件的校验文件,但是很明显,DTD差不多是快被淘汰的技术了,功能非常有限,扩展性非常差,扩展性非常差,扩展性非常差,可读性也不好,Spring能够从DTD到XSD华丽转身,但Mybatis始终没这个魄力。

2.版本兼容性做的不好,就拿3.3.0—>3.4.0来说,按业界通用规范,第2级版本号升级,可以添加功能,但是要保证向下兼容性,然而Mybatis的做法并不完全是这样的,看一下关键接口StatementHandler的关键方法prepare:


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

这里没有添加一个方法,而是直接在原方法中添加了一个参数!类似例子还有不少,就不一一列举了。

3.Mybatis的插件,采用一个通用的Interceptor接口,配以@Intercepts、@Signature等注解,实现对多个组件的多种方法的拦截,看似非常灵活,在我看来其实是结构不够清晰,实际开发时,你会把对StatementHandler和ResultSetHandler的拦截增强放在一个类里面吗?不会是吧(会?你当单一职责原则、开闭原则都是狗屎吗),那有什么必要强制使用同一个接口呢?

另外,使用@Signature注解来设别需要被拦截的组件方法,如果注解有错,编译也是不会报错的,而只能等到运行时才能发现,再看上面的例子:

假设我针对3.3.0版本实现了一个插件:


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

然后,升级为3.4.0,结果呢,编译一直正常,但是等到运行,却抛出异常了。

4.Mybatis的缓存简直就是鸡肋,而且不管有没有配置需要使用缓存、是否更新缓存,都要去计算CacheKey,不使用缓存、也不更新缓存的情况下,这种计算完全是浪费。

5.Mybatis的批量执行,看下面的一个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_NAME1
ps.setString(2, "数据" + random);//FIELD_NAME2
ps.setString(3, "参数" + random);//FIELD_NAME3
ps.addBatch();
}
int[] rs = ps.executeBatch();
}finally{
try{
ps.close();
}catch(Exception e){}
}
}

代码没有什么违和感,能够执行正常,也可以按预期的回滚,也就是说同一个事务中的同一个connection,可以同时运行普通sql和batch,但是你在同一个事务的SqlSession中试试,反馈给你的是——不能在同一个事务中切换执行方式!

6、数据库产品的兼容性:Mybatis把SQL的控制权交给了开发人员,于是从道德上占据了制高点——你写的不兼容,那是你自己的水平不行!但,这是一个真正的优秀框架的正确姿势吗?为什么就不能提供一些辅助性的兼容实施?比如说在Oracle中被奉为神明的DECODE函数,是否可以在SqlMapper中提供一个<decode>标签,在后面默默的修改成CASE WHEN?或者说,官方不提供没有关系,但你得提供扩展方式啊,于是又回到了:扩展性非常差,扩展性非常差,扩展性非常差。重要的事说三遍,但,我已经说六遍了。

以上所述是小编给大家介绍的Mybatis的缺陷问题,希望对大家有所帮助!

标签:mybatis,缺陷
0
投稿

猜你喜欢

  • SpringBoot整合Mybatis-plus的具体过程使用

    2022-06-15 19:38:52
  • ScrollView与ListView合用(正确计算Listview的高度)的问题解决

    2021-12-30 07:14:58
  • 详解Java弱引用(WeakReference)的理解与使用

    2022-07-13 12:37:32
  • Java基础学习之方法的重载知识总结

    2023-10-27 01:45:15
  • Java文件操作之按行读取文件和遍历目录的方法

    2023-11-24 16:58:21
  • 一个进程间通讯同步的C#框架引荐

    2023-01-18 17:55:03
  • 解决Druid动态数据源配置重复刷错误日志的问题

    2021-06-06 17:44:51
  • .net中常用的正则表达式

    2021-06-12 00:15:44
  • Android 中ScrollView嵌套GridView,ListView的实例

    2023-06-15 15:49:56
  • C#实现winform自动关闭MessageBox对话框的方法

    2022-09-02 02:21:53
  • Mybatis使用JSONObject接收数据库查询的方法

    2023-01-17 05:10:43
  • C++异常处理入门(try和catch)

    2022-09-18 04:16:34
  • Java SSM配置文件案例详解

    2022-10-14 09:43:19
  • mybatis 查询返回Map<String,Object>类型

    2023-11-14 07:06:09
  • SpringMVC域对象共享数据示例详解

    2023-03-10 22:21:21
  • java实现冒泡排序算法

    2023-10-17 20:44:01
  • Android自定义View实现等级滑动条的实例

    2023-12-08 19:57:53
  • java实现基于SMTP发送邮件的方法

    2023-04-06 12:22:07
  • Java线程安全问题小结_动力节点Java学院整理

    2021-09-25 21:01:43
  • Android MessageQueue消息队列主要作用详解

    2021-11-11 15:25:39
  • asp之家 软件编程 m.aspxhome.com