利用java8 中 lambda 方法引用获取字段属性

一 背景:

   在公司开发过程中,项目中集成了一个mybatis框架tk.mybatis,然后看到用到一些api进行数据查询如:

 

       Example example = new Example(XXDO.class);
        example.createCriteria()
            .andEqualTo("spaceId", spaceId);
       XXMapper.selectByExample(example)

当时本人并没有深入tk.mybatis 的一些新特性api,而是去想一个问题:

 直接在方法查询中把字段写死,首先不符合java编码规范,再次当字段名有改变,这里是不可知的。当时本人就在想一个问题,怎么解决这个问题,幸好我们用的jdk版本是1.8 ,当时我就在想能不能通过方法引用获取字段,于是就尝试这么去解决。

问题解决前提:

   利用方法引用,首先 你的pojo中字段命名以及get 方法命名需要规则,建议采取lombok中@Data或者@Getter生成字段的get方法。

思路:

 一 : 根据方法引用 解析获取 该方法引用的方法名

二: 将获取到的方法名(getXaa或isAxx),去除get或者is 将剩下的字符的第一个字母小写就是字段名了。

代码如下:

 首先 需要自己定义一个jdk中类似的Function 并且集成 Serializable,如:

public interface PropertyFunc extends Function, Serializable {

}

 第二步骤,解析方法引用:

 

public class ReflectionFieldName {


    public static  String getFieldName(PropertyFunc func) {
        try {
            // 通过获取对象方法,判断是否存在该方法
            Method method = func.getClass().getDeclaredMethod("writeReplace");
            method.setAccessible(Boolean.TRUE);
            // 利用jdk的SerializedLambda 解析方法引用
            java.lang.invoke.SerializedLambda serializedLambda = (SerializedLambda) method.invoke(func);
            String getter = serializedLambda.getImplMethodName();
            return resolveFieldName(getter);
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

    private static String resolveFieldName(String getMethodName) {
        if (getMethodName.startsWith("get")) {
            getMethodName = getMethodName.substring(3);
        } else if (getMethodName.startsWith("is")) {
            getMethodName = getMethodName.substring(2);
        }
        // 小写第一个字母
        return firstToLowerCase(getMethodName);
    }

    private static String firstToLowerCase(String param) {
        if (StringUtils.isBlank(param)) {
            return "";
        }
        return param.substring(0, 1).toLowerCase() + param.substring(1);
    }
}

完毕。

编写测试类:


import lombok.Data;

@Data
public class Person {
    private String name;
    private Long age;

    public static void main(String[] args) {
      System.out.println(ReflectionFieldName.getFieldName(Person::getName));
    }
}

 

输出结果:

利用java8 中 lambda 方法引用获取字段属性_第1张图片

后记:

  由于tk.mabatis的insert方法有些问题不能完成某些需求,我们打算写一些注解配合fix。然后本人把源码clone下来的时候,一步消息看了tk他是直接方法引用传值的,如:


        Weekend example = Weekend.of(XXDO.class);
        example.weekendCriteria()
            .andEqualTo(XXDO::getAbId, id);
        

 

 

 

你可能感兴趣的:(java)