Java8通过Function获取字段名的步骤

摘要: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

到此这篇关于Java8通过Function获取字段名的文章就介绍到这了,更多相关java8 function 字段名内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 8 Function函数式接口及函数式接口实例

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接口可以现有的函数友好地支持 lambda. 介绍 函数式接口其实就是一个抽象接口类,在Java 8之前已有的函数式接口有以下. java.lang.Runnable java.util.concurrent.Callable java.util.Comparator 等等... 使用方法 其实上述所说的接口类只需要使用Fun

  • java中functional interface的分类和使用详解

    java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function. 在java 8之前,如果需要使用到匿名function需要new一个类的实现,但是有了lambda表达式之后,一切都变的非常简介. 我们看一个之前讲线程池的时候的一个例子: //ExecutorService using class ExecutorService executorService = Executors.newSingleThreadExecutor(); executorSer

  • underscore之function_动力节点Java学院整理

    因为underscore本来就是为了充分发挥JavaScript的函数式编程特性,所以也提供了大量JavaScript本身没有的高阶函数. bind bind()有什么用?我们先看一个常见的错误用法: 'use strict'; console.log('Hello, world!'); // 输出'Hello, world!' var log = console.log; log('Hello, world!'); // Uncaught TypeError: Illegal invocati

  • Java8中stream和functional interface的配合使用详解

    前言 Java 8 提供了一组称为 stream 的 API,用于处理可遍历的流式数据.stream API 的设计,充分融合了函数式编程的理念,极大简化了代码量. 大家其实可以把Stream当成一个高级版本的Iterator.原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作:高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如"过滤掉长度大于10的字符串"."获取每个字符串的首字母"等,具体这些操作如何应用到每个元素上,

  • Java8通过Function获取字段名的步骤

    摘要:Java8通过Function获取字段名,解决硬编码,效果类似于mybatis-plus的LambdaQueryWrapper. 本文总共三个步骤: 1.使Function获取序列化能力: 2.通过SFunction获取字段名: 3.建一些业务代码进行测试: 使Function获取序列化能力 import java.io.Serializable; import java.util.function.Function; /** * 使Function获取序列化能力 */ @Function

  • Java8通过Function获取字段名的方法(获取实体类的字段名称)

    看似很鸡肋其实在某些特殊场景还是比较有用的. 比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value. 方法一: 声明 String key1="aaa"; key为 key1,value 为map.get(key1); Map<String,Object> map=new HashMap<>(); map.put("aaa",1); //获取map的key 和value //key 为key1 Str

  • php获取字段名示例分享

    复制代码 代码如下: <?php$link = mysql_connect('localhost', 'username', 'password');$fields = mysql_list_fields("database", "table", $link);$columns = mysql_num_fields($fields);$field = false;for ($i = 0; $i < $columns; $i++) {    $field

  • 微信小程序获取用户手机号码的详细步骤

    目录 前言 接下来我们通过服务器获取授权 deciphering解密方法 总结 前言 我们在做小程序开发的过程中,经常会涉及到用户身份的问题,最普遍的就是我们要获取用户的手机号码,通过微信获取手机号码后可以减少很多操作,比如用户手机号码验证等,我们还可以给用户发送提示短信,那么本文主要讲解如何获取用户手机号码. 获取用户手机号码 分为以下几步: 第一点击页面获取授权按钮 第二获取用户授权参数 第三根据加解密算法解密手机号码 接下来我们来实现以上三步 先看前端页面 <!--index.wxml--

  • 初识Java8中的Stream

    lambda表达式是stream的基础,初学者建议先学习lambda表达式,http://www.jb51.net/article/121129.htm 1.初识stream 先来一个总纲: 东西就是这么多啦,stream是java8中加入的一个非常实用的功能,最初看时以为是io中的流(其实一点关系都没有),让我们先来看一个小例子感受一下: @Before public void init() { random = new Random(); stuList = new ArrayList<St

  • 用C语言winform编写渗透测试工具实现SQL注入功能

    目录 用C语言winform编写渗透测试工具使SQL注入 一.SQL注入 二.实现步骤 三.代码实现 四.软件使用步骤 用C语言winform编写渗透测试工具使SQL注入 一.SQL注入 原理: SQL注入是指攻击者在Web应用程序中事先定义好的查询语句的结尾加上额外的SQL语句,这些一般都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作.(危害:盗取网站敏感信息.绕过验证登录网站后台.借助数据库的存储过程进行权限提升等操作).造成的原因是程序员在编写Web程序时,没有对浏览

  • php实现可用于mysql,mssql,pg数据库操作类

    本文实例讲述了可用mysql,mssql,pg三种数据库的数据库操作类,你只要作任何修改就可以方便的改变你数据库的类型.分享给大家供大家参考.具体分析如下: 函数清单,索引: Open:打开数据库连接 Line:71 Close:关闭数据库连接 Line:107 SelectDB:选择数据库 Line:129 Query:创建查询 Line:151 DataSeek:移动记录指针 Line:175 FieldName:获取字段名称 Line:198 FieldType:获取字段类型 Line:2

  • SpringDataJPA之Specification复杂查询实战

    目录 SpringDataJPA Specification复杂查询 前言 实现 Specification与Controller业务逻辑 ApiReturnUtil.page封装 查询效果 可能遇到的错误 JpaSpecificationExecutor接口 Specification 一个一目了然的方法 Criteria+TypedQuery 开发过程中JPA Specification的应用 为什么需要Specification 应用场景 JPA Specification实现复杂查询 J

  • JavaWeb学习笔记分享(必看篇)

    自定义列表 <dl></dl>:表示列表的范围 **在里面 <dt></dt>:上层内容 **在里面 <dd></dd>:下层内容 有序列表 <ol></ol>:有序列表的范围 --属性 type:设置排序方式,1(默认),a,i.. **在ol标签里面 <li>具体内容</li> 无序列表 <ul></ul>:无序列表的范围 --属性 type:circle(空

  • Redis中散列类型的常用命令小结

    Redis散列类型 Redis是采用字典结构以键值对的形式存储数据的,而散列类型(hash)的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其他数据类型,也就是说,散列类型不能嵌套其他的数据类型.一个散列类型键可以包含至多2^32-1个字段. 除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套.比如集合类型的每个元素只能是字符串,不能是一个集合或者散列表等. 散列类型适合存储对象:使用对象类别和ID构成建名,使用字段表示对象的属性,而字段值存储属性值.例

随机推荐