In depth analysis of Mybatis defects

  • 2020-05-12 02:35:26
  • OfStack

Mybatis is a very popular durable layer framework in the industry. It is lightweight and easy to use. It is a complete leader in the field of financial IT, and is more popular than Hibernate. However, Mybatis is not perfect, and its own design and coding also have many shortcomings and even defects. This article briefly discusses these defects:

1.Mybatis USES DTD as the calibration file of XML configuration file, but it is clear that DTD is almost obsolete technology with very limited functions, poor scalability, poor scalability, and poor readability. Spring can make a gorgeous turn from DTD to XSD, but Mybatis never has the same drive.

2. If version compatibility is not good, take 3.3.0 -- > 3.4.0, according to the industry general specification, level 2 version number upgrade, you can add functions, but to ensure downward compatibility, however, the practice of Mybatis is not exactly like this, see 1 key interface StatementHandler key method prepare:


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

Instead of adding a method, you simply add a parameter to the original method! There are many similar examples, but I won't list 11.

3. The plug-in of Mybatis, which adopts a general Interceptor interface and annotation of @Intercepts and @Signature, realizes the interception of multiple methods for multiple components. It seems very flexible, but in my opinion, the structure is not clear enough. It can't be, can it? What is the need to force the use of the same interface?

In addition, the @Signature annotation is used to specify which component methods need to be intercepted. If the annotation is incorrect, the compiler will not report the error until runtime. See the following example:

Suppose I implement a plug-in for version 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) {
}
}

Then, it was upgraded to 3.4.0, and as a result, compile 1 worked, but when it ran, it threw an exception.

4. The cache of Mybatis is simply a chicken's hole, and the calculation of CacheKey should be made with or without the configuration to use the cache and whether or not to update the cache, which is completely wasteful without using the cache and without updating the cache.

5. Batch execution of Mybatis, see an example of JDBC below:


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, " data " + random);//FIELD_NAME2
ps.setString(3, " parameter " + random);//FIELD_NAME3
ps.addBatch();
}
int[] rs = ps.executeBatch();
}finally{
try{
ps.close();
}catch(Exception e){}
}
}

The code has no sense of violation, can perform normally, can also be rolled back as expected, that is, the same transaction in the same 1 connection, can run normal sql and batch at the same time, but you try in the same transaction in SqlSession, feedback to you is - can not switch the execution mode in the same transaction!

6. Database product compatibility: Mybatis hands control of SQL to the developer, thus taking the moral high ground -- if what you write isn't compatible, it's at your own level! But is this the right posture for a really good frame? Why can't it provide some complementary compatibility implementation? For example, can the DECODE function, which is deified in Oracle, be provided with one in SqlMapper < decode > The tag, which was silently changed to CASE WHEN? Or, it doesn't matter if it's not officially available, but you have to provide ways to extend it, so it goes back to: very poor extensibility, very poor extensibility, very poor extensibility. Say the important thing three times, but I've already said it six times.

The above is this site to introduce you Mybatis defects, I hope to help you!


Related articles: