Mybatis is a very popular lasting layer framework in the industry. It is lightweight and easy to use. It is completely leading in the financial IT field. It is more popular than Hibernate, with many advantages and is also worth learning from. But Mybatis is not perfect, and its own design and coding still have many shortcomings, even defects. This article briefly discusses these defects:
1.Mybatis uses DTD as the verification file for XML configuration files, but it is obvious that DTD is almost an erased technology. It has very limited functions, very poor scalability, very poor scalability, very poor scalability, and poor readability. Spring can turn gorgeously from DTD to XSD, but Mybatis has never had this courage.
2. If the version compatibility is not done well, take 3.3.0―>3.4.0 as an example. According to the industry's general specifications, the second level version number can be upgraded, and functions can be added, but backward compatibility must be ensured. However, Mybatis's approach is not exactly like this. Take a look at the key method of StatementHandler to prepare:
// 3.3.0Statement prepare(Connection connection)throws SQLException;// 3.4.0Statement prepare(Connection connection, Integer transactionTimeout)throws SQLException;
There is no method added here, but a parameter is added directly to the original method! There are many similar examples, so I won’t list them one by one.
3. Mybatis plug-in uses a general Interceptor interface, accompanied by annotations such as @Intercepts and @Signature to implement multiple methods of interception of multiple components. It seems very flexible. In my opinion, the structure is actually not clear enough. During actual development, will you put the interception enhancement of StatementHandler and ResultSetHandler in one class? Isn't it right (yes? Are you the single responsibility principle and the opening and closing principle all shit?), so why is it necessary to force the same interface?
In addition, use the @Signature annotation to specify the component methods that need to be intercepted. If the annotation is wrong, the compilation will not report an error. You can only wait until it is run to discover it. Let’s take a look at the above example:
Suppose I implemented a plugin for version 3.3.0:
@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) {}}Then, it was upgraded to 3.4.0. As a result, the compilation was normal, but when it was run, an exception was thrown.
4. Mybatis' cache is simply useless, and regardless of whether there is a configuration, it is necessary to use the cache or update the cache, it is necessary to calculate the CacheKey. If there is no cache or update the cache, this calculation is a waste.
5. For batch execution of Mybatis, see the following JDBC example:
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, "Data" + random);//FIELD_NAME2ps.setString(3, "Parameter" + random);//FIELD_NAME3ps.addBatch();}int[] rs = ps.executeBatch();} finally{try{ps.close();}catch(Exception e){}}}The code has no sense of incongruity, can execute normally, and can also roll back as expected. That is to say, the same connection in the same transaction can run ordinary SQL and batch at the same time, but you try it in the SqlSession of the same transaction, and what you feedback to you is that you cannot switch the execution method in the same transaction!
6. Compatibility of database products: Mybatis handed over the control of SQL to developers, so it morally occupied the commanding heights - what you wrote is incompatible, that is your own level! But is this the right pose for a really good frame? Why can't some auxiliary compatible implementation be provided? For example, if the DECODE function, which is regarded as a god in Oracle, can it be provided with a <decode> tag in SqlMapper and silently modified to CASE WHEN later? In other words, it doesn’t matter if the official does not provide it, but you have to provide an expansion method, so I come back to: the scalability is very poor, the scalability is very poor, and the scalability is very poor. I said the important things three times, but I have said them six times.
The above is the defects of Mybatis introduced to you by the editor. I hope it will be helpful to you!