English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Mybatis هو إطار عمل مستدام في الصناعة، يتم استخدامه بشكل شائع جدًا، خفيف الوزن وسهل الاستخدام، ويحتل مكانة قيادية في مجال IT المالي، أكثر شعبية من Hibernate، ويتمتع بمزايا كثيرة جدًا، وهو أيضًا ما يجب أن نتعلم منه. ولكن Mybatis ليس مثاليًا تمامًا، تصميمه وكتابته يحتويان على العديد من النقاط الضعيفة، وحتى العيوب، هذا المقال سيقوم بمناقشة هذه العيوب بشكل مختصر:
1. Mybatis يستخدم DTD كملف التحقق من ملفات التكوين XML، ولكن من الواضح أن DTD تقترب من الإزالة تقريبًا، لديها وظيفة محدودة جدًا، وقابلية التوسع ضعيفة جدًا، وقابلية التوسع ضعيفة جدًا، وقابلية التوسع ضعيفة جدًا، وقراءة سيئة أيضًا، يمكن لـ Spring أن يتحول بشكل رائع من DTD إلى XSD، ولكن لم يكن لدي Mybatis القدرة على ذلك.
2. لا يتم تنفيذ التكامل الإصداري بشكل جيد، لنأخذ مثالًا على 3.3.0 -> 3.4.0، وفقًا للمواصفات العامة للصناعة، يمكن إضافة ميزات عند تحديث المستوى الثاني من الرقم الإصداري، ولكن يجب ضمان التكامل الإصداري، ومع ذلك، لا يتبع 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 لتحديد المكونات التي يجب أن يتم توقيفها، إذا كان التوقيع خاطئًا، لن يظهر خطأ في التجميع، بل يمكن اكتشافه فقط عند تشغيل البرنامج، انظر المثال أعلاه:
افترض أنني قمت بتطوير إضافة (plugin) لمسلسل الإصدارات 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 { يعود تنفيذ invocation.proceed(); } @Override public Object plugin(Object target) {}} return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } }
ثم، بعد التحديث إلى إصدار 3.4.0، كانت الكود يتم تجميعه بشكل صحيح، ولكن عند تشغيله، تم إطلاق استثناء.
4.مكتبة التخزين المؤقت الخاصة بـ Mybatis هي مثل العظام، وهي لا تستخدم مهما كان الإعداد أو التحديث، يجب حساب مفتاح التخزين المؤقت، مما يكون ضربًا في الهواء إذا لم تستخدم التخزين المؤقت أو تحديثه.
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 للنصائح، مما يوفر نقطة مرتفعة أخلاقية - إذا لم تكن متوافقًا، فإن مستوى مهارتك غير كافٍ! ولكن، هل هذا هو الوضع الصحيح للإطار الممتاز؟ لماذا لا يمكن تقديم بعض التطبيقات المساعدة للتوافق؟ على سبيل المثال، هل يمكن تقديم وسم <decode> في SqlMapper لتغيير CASE WHEN بشكل سري؟ أو ربما لا يقدمها المطورون الرسميون، لكن يجب أن يقدموا طريقة التوسع، مما يعود إلى: قصور في التوسع، قصور في التوسع، قصور في التوسع. مهمة قيلت ثلاث مرات، لكن قلت ست مرات.
ما تم ذكره أعلاه هي مشاكل العيوب لـ Mybatis التي قدمناها لكم، نأمل أن تكون مفيدة لكم!