English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Mybatis è un framework di persistenza molto popolare nel settore, leggero e facile da usare, in campo finanziario IT è in posizione di leadership, più popolare di Hibernate, con molti vantaggi e assolutamente degno di essere studiato. Ma Mybatis non è perfetto, il suo design e codice presentano ancora molte lacune, persino difetti. Questo articolo discute brevemente questi difetti:
1.Mybatis utilizza DTD come file di validazione per i file XML di configurazione, ma è chiaro che DTD è quasi obsoleto, con funzionalità molto limitate, scarsa estensibilità, scarsa estensibilità, scarsa estensibilità, e scarsa leggibilità. Spring è in grado di fare una trasformazione spettacolare da DTD a XSD, ma Mybatis non ha mai avuto questa audacia.
2. La compatibilità delle versioni non è stata gestita bene; prendiamo ad esempio il passaggio da 3.3.0 a 3.4.0, secondo lo standard comune dell'industria, un aggiornamento del secondo livello della versione può aggiungere funzionalità, ma deve garantire la compatibilità向下, tuttavia, il metodo chiave prepare dell'interfaccia StatementHandler di Mybatis non segue del tutto questo schema, guardiamo il metodo chiave prepare di StatementHandler:
// 3.3.0 Statement prepare(Connection connection) throws SQLException; // 3.4.0 Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;
Qui non è stato aggiunto un metodo, ma direttamente un parametro all'interno del metodo originale! Ci sono molti esempi simili, non elenco tutti.
3. Gli plugin di Mybatis utilizzano un'interfaccia Interceptor universale, abbinata alle annotazioni @Intercepts, @Signature, ecc., per intercettare metodi di vari componenti, sembrando molto flessibile, ma secondo me, la struttura non è chiara abbastanza; durante la sviluppo, metteresti l'intercettazione di StatementHandler e ResultSetHandler in una stessa classe? Non credo (credi? Sei un idiota delle principi di职责单一和开闭吗), quindi c'è bisogno di forzare l'uso della stessa interfaccia?
Inoltre, l'annotazione @Signature viene utilizzata per identificare i componenti dei metodi che devono essere intercettati; se l'annotazione è errata, la compilazione non segnerà un errore, ma solo durante l'esecuzione; guardando l'esempio sopra:
Ipotesi: ho implementato un plugin per la versione 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) { } }
Poi, aggiornato a 3.4.0, il risultato è che il compilazione è sempre stato normale, ma durante l'esecuzione, è stato lanciato un'eccezione.
4.La cache di Mybatis è praticamente inutile, e indipendentemente dal fatto che sia configurata o meno l'uso della cache, o se sia necessario aggiornare la cache, è necessario calcolare la CacheKey. Senza utilizzare la cache né aggiornare la cache, questo calcolo è completamente inutile.
5.Esempio di esecuzione batch di Mybatis, vedere sotto un esempio 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, "dato" + random);//FIELD_NAME2 ps.setString(3, "parametro" + random);//FIELD_NAME3 ps.addBatch(); } int[] rs = ps.executeBatch(); }finally{ try{ ps.close(); catch(Exception e){} } }
Il codice non ha una sensazione di incongruenza, può eseguire normalmente e può essere roll back come previsto, il che significa che la stessa connection in una stessa transazione può eseguire sql normale e batch contemporaneamente, ma se provi a cambiare il modo di esecuzione nella stessa SqlSession della transazione, il feedback che ricevi è - non è possibile cambiare il modo di esecuzione nella stessa transazione!
6.Compatibilità dei prodotti di database: Mybatis consegna il controllo SQL ai sviluppatori, quindi moralmente occupa un punto alto - se non sei compatibile, è perché non hai abbastanza capacità! Ma è questa la postura corretta di un framework veramente eccellente? Perché non fornire alcune implementazioni di compatibilità ausiliarie? Ad esempio, il funzione DECODE venerata in Oracle, potrebbe essere fornito un tag <decode> in SqlMapper, che viene modificato silenziosamente in CASE WHEN? O forse, non c'è problema se non fornite ufficialmente, ma dovete fornire un modo di estensione, quindi torniamo di nuovo: estensibilità molto scarsa, estensibilità molto scarsa, estensibilità molto scarsa. Importante, lo dico tre volte, ma l'ho detto sei volte.
Quello che ho descritto sopra sono i problemi di difetti di Mybatis che ho introdotto per voi, spero che sia utile a tutti voi!