ibatis-sqlmap和sourceforge.ibatis对sqlmap的变量处理的不同

本文探讨了ibatis-sqlmap中如何通过get方法名称获取属性值,并对比了不同实现方式的区别。详细解释了ClassInfo类的实现过程,包括get和set方法的处理及字段读取的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在sqlmap文件中会定义一些DO并从DO去除对应的属性值替换sql的变量名

<insert id="MS-BRANDOFFER-INSERT" parameterClass="TA-brandOffer">
        insert into industry_brand_offer (gmt_create, gmt_modified, offer_id,brand_member_id, status, operator,audit_reason)
        values (now(), now(), #offerId#, #brandMemberId#, #status#, #operator#, #auditReason#)
    <selectKey resultClass="java.lang.Long" keyProperty="id">
    SELECT LAST_INSERT_ID() AS ID
 </selectKey>
</insert>

那么ibtais怎么从TA-brandOffer去除对应的比如offerId的值的呢,

ibatis-sqlmap是通过get方法名称,只要方法以get开头,则从get方法名称后面部分取出,并将后面部分第一个字段转为小写。

ClassInfo这个类的实现

private ClassInfo(Class clazz) {
   className = clazz.getName();
   addMethods(clazz);
   readablePropertyNames = (String[]) getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
   writeablePropertyNames = (String[]) setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
 }
 private void addMethods(Class cls) {
   Method[] methods = getAllMethodsForClass(cls);
   for (int i = 0; i < methods.length; i++) {
     String name = methods[i].getName();
     if (name.startsWith("set") && name.length() > 3) {
       if (methods[i].getParameterTypes().length == 1) {
         name = dropCase(name);
         if (setMethods.containsKey(name)) {
           // TODO(JGB) - this should probably be a RuntimeException at some point???
 
           log.error("Illegal overloaded setter method for property " + name + " in class " + cls.getName() +
 
               ".  This breaks the JavaBeans specification and can cause unpredicatble results.");
         }
         setMethods.put(name, methods[i]);
         setTypes.put(name, methods[i].getParameterTypes()[0]);
       }
     } else if (name.startsWith("get") && name.length() > 3) {
       if (methods[i].getParameterTypes().length == 0) {
         name = dropCase(name);
         getMethods.put(name, methods[i]);
         getTypes.put(name, methods[i].getReturnType());
       }
     } else if (name.startsWith("is") && name.length() > 2) {
       if (methods[i].getParameterTypes().length == 0) {
         name = dropCase(name);
         getMethods.put(name, methods[i]);
         getTypes.put(name, methods[i].getReturnType());
       }
     }
     name = null;
   }
 }
 
private static String dropCase(String name) {
   if (name.startsWith("is")) {
     name = name.substring(2);
   } else if (name.startsWith("get") || name.startsWith("set")) {
     name = name.substring(3);
   } else {
     throw new ProbeException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
   }
 
   if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
     name = name.substring(0, 1).toLowerCase(Locale.US) + name.substring(1);
   }
 
   return name;
 }

而sourceforge.ibatis包得处理则不一样,除了从get方法取还从类的field属性取

private ClassInfo(Class clazz) {
  className = clazz.getName();
  addDefaultConstructor(clazz);
  addGetMethods(clazz);
  addSetMethods(clazz);
  addFields(clazz);
  readablePropertyNames = (String[]) getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
  writeablePropertyNames = (String[]) setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
}
  private void addGetMethods(Class cls) {
  Method[] methods = getClassMethods(cls);
  for (int i = 0; i < methods.length; i++) {
    Method method = methods[i];
    String name = method.getName();
    if (name.startsWith("get") && name.length() > 3) {
      if (method.getParameterTypes().length == 0) {
        name = dropCase(name);
        addGetMethod(name, method);
      }
    } else if (name.startsWith("is") && name.length() > 2) {
      if (method.getParameterTypes().length == 0) {
        name = dropCase(name);
        addGetMethod(name, method);
      }
    }
  }
}
 
private void addGetMethod(String name, Method method) {
  getMethods.put(name, new MethodInvoker(method));
  getTypes.put(name, method.getReturnType());
}
private void addFields(Class clazz) {
  Field[] fields = clazz.getDeclaredFields();
  for (int i = 0; i < fields.length; i++) {
    Field field = fields[i];
    if (canAccessPrivateMethods()) {
      try {
        field.setAccessible(true);
      } catch (Exception e) {
        // Ignored. This is only a final precaution, nothing we can do.
      }
    }
    if (field.isAccessible()) {
      if (!setMethods.containsKey(field.getName())) {
        addSetField(field);
      }
      if (!getMethods.containsKey(field.getName())) {
        addGetField(field);
      }
    }
  }
  if (clazz.getSuperclass() != null) {
    addFields(clazz.getSuperclass());
  }
}
 
private void addSetField(Field field) {
  setMethods.put(field.getName(), new SetFieldInvoker(field));
  setTypes.put(field.getName(), field.getType());
}
 
private void addGetField(Field field) {
  getMethods.put(field.getName(), new GetFieldInvoker(field));
  getTypes.put(field.getName(), field.getType());
}

所以如果get方法名称后面对应的属性名跟field字段一直,则用两个包都没问题,但是如果get方法后面的属性跟field名称不一样,则加载了sourceforge.ibatis仍然没问题,但是加载ibatis-sqlmap这个包就会出错了。

修改方法最好是改get方法了,保证get方法的属性名跟field字段名一样。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值