欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java8通过Function获取字段名

程序员文章站 2022-10-04 09:18:11
Java8通过Function获取字段名。不用再硬编码,效果类似于mybatis-plus的LambdaQueryWrapper。 ......

摘要:java8通过function获取字段名。不用再硬编码,效果类似于mybatis-plus的lambdaquerywrapper。

本文总共三个步骤:
1、使function获取序列化能力;
2、通过sfunction获取字段名;
3、建一些业务代码进行测试;

使function获取序列化能力

import java.io.serializable;
import java.util.function.function;

/**
 * 使function获取序列化能力
 */
@functionalinterface
public interface sfunction<t, r> extends function<t, r>, serializable {
}

通过sfunction获取字段名

import java.lang.invoke.serializedlambda;
import java.lang.reflect.field;
import java.lang.reflect.invocationtargetexception;
import java.lang.reflect.method;

public class columnutil {

    public static <t> string getname(sfunction<t, ?> fn) {
        // 从function取出序列化方法
        method writereplacemethod;
        try {
            writereplacemethod = fn.getclass().getdeclaredmethod("writereplace");
        } catch (nosuchmethodexception e) {
            throw new runtimeexception(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isaccessible = writereplacemethod.isaccessible();
        writereplacemethod.setaccessible(true);
        serializedlambda serializedlambda;
        try {
            serializedlambda = (serializedlambda) writereplacemethod.invoke(fn);
        } catch (illegalaccessexception | invocationtargetexception e) {
            throw new runtimeexception(e);
        }
        writereplacemethod.setaccessible(isaccessible);

        // 从lambda信息取出method、field、class等
        string fieldname = serializedlambda.getimplmethodname().substring("get".length());
        fieldname = fieldname.replacefirst(fieldname.charat(0) + "", (fieldname.charat(0) + "").tolowercase());
        field field;
        try {
            field = class.forname(serializedlambda.getimplclass().replace("/", ".")).getdeclaredfield(fieldname);
        } catch (classnotfoundexception | nosuchfieldexception e) {
            throw new runtimeexception(e);
        }

        // 从field取出字段名,可以根据实际情况调整
        tablefield tablefield = field.getannotation(tablefield.class);
        if (tablefield != null && tablefield.value().length() > 0) {
            return tablefield.value();
        } else {
            return fieldname.replaceall("[a-z]", "_$0").tolowercase();
        }
    }
}

建一些业务代码进行测试

import java.lang.annotation.elementtype;
import java.lang.annotation.retention;
import java.lang.annotation.retentionpolicy;
import java.lang.annotation.target;

/**
 * 字段名注解。测试用
 */
@target(elementtype.field)
@retention(retentionpolicy.runtime)
public @interface tablefield {
    string value() default "";
}
import java.io.serializable;

/**
 * 用户实体类。测试用
 */
public class user implements serializable {

    private string loginname;

    @tablefield("nick")
    private string nickname;

    public string getloginname() {
        return loginname;
    }

    public void setloginname(string loginname) {
        this.loginname = loginname;
    }

    public string getnickname() {
        return nickname;
    }

    public void setnickname(string nickname) {
        this.nickname = nickname;
    }
}
/**
 * 测试用
 */
public class test {
    public static void main(string[] args) {
        system.out.println("字段名:" + columnutil.getname(user::getloginname));
        system.out.println("字段名:" + columnutil.getname(user::getnickname));
    }
}

运行结果:
字段名:login_name
字段名:nick