Cleverly use Lambda expressions to obtain object attribute names and bid farewell to magic values

In our daily development, when using MyBatis-Plus to write SQL and execute, table fields will inevitably be used. Although MyBatis-Plus provides LambdaQueryWrapper to help us use Lambda method to call object property names, sometimes magic values ​​are still used. , when the attribute name of the object is changed, we will inevitably miss it and cause a production accident.

1. Define Function that supports serialization

import java.io.Serializable;
import java.util.function.Function;

/**
 * 支持序列化的 Function
 *
 * @author miemie
 * @since 2018-05-12
 */
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
    
    
}

This is a function provided by MyBatis-Plus, and the calling method is also very simple. For example, we have an entity object UserDO

public class UserDO {
    
    

	private Long id;

	private String name;

	private Integer age;

	private String phone;
}

The calling method is:

SFunction<UserDO, Long> func = UserDO::getId;

2. Get the attribute name

For example, our calling method UserDO::getId above hopes to obtain the "id" string. Next, we use the tool class provided by MyBatis-Plus to obtain the attribute name.

import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.reflection.property.PropertyNamer;

import java.beans.Introspector;

/**
 * 获取属性名工具类
 *
 * @author asurplus
 */
public class FieldUtils {
    
    

    /**
     * 获取Java属性名
     *
     * @return userName
     */
    public static <T, R> String getFieldName(SFunction<T, R> func) {
    
    
        // 获取 lambda 表达式实现方法的名称
        String fieldName = LambdaUtils.extract(func).getImplMethodName();
        // 去掉前缀:get,is
        fieldName = PropertyNamer.methodToProperty(fieldName);
        // 首字母小写
        return Introspector.decapitalize(fieldName);
    }
}

Calling method:

public static void main(String[] args) {
    
    
    String fieldName = FieldUtils.getFieldName(UserDO::getId);
    System.out.println(fieldName);
}

Output:
Insert image description here

3. Get the database field name

We have obtained the attribute name above, so the field name is the camel case to underline operation.

/**
 * 获取数据库字段名
 *
 * @return user_name
 */
public static <T, R> String getColumnName(SFunction<T, R> func) {
    
    
    String fieldName = getFieldName(func);
    // 转下划线
    return StrUtil.toUnderlineCase(fieldName);
}

StrUtil.toUnderlineCase() here is implemented using the tool class in the hutool tool package

Calling method:

public static void main(String[] args) {
    
    
    String fieldName = FieldUtils.getColumnName(UserDO::getUserName);
    System.out.println(fieldName);
}

Output:
Insert image description here

4. Bottom call

Above we obtained the object attribute name with the help of the LambdaUtils tool class of MyBatis-Plus. So how do we obtain it without introducing MyBatis-Plus?

/**
 * 获取Java属性名
 *
 * @return userName
 */
public static <T, R> String getFieldName(SFunction<T, R> func) {
    
    
    try {
    
    
        Method method = func.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(true);
        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(func);
        String fieldName = serializedLambda.getImplMethodName();
        if (fieldName.startsWith("get")) {
    
    
            fieldName = fieldName.substring(3);
        }
        if (fieldName.startsWith("is")) {
    
    
            fieldName = fieldName.substring(2);
        }
        // 首字母小写
        return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
    } catch (ReflectiveOperationException e) {
    
    
        throw new RuntimeException(e);
    }
}

The LambdaUtils of MyBatis-Plus also uses the same underlying call, so that we can use Lambda expressions to obtain the object attribute names without writing magic values. When the attribute names are changed, the idea development tool will remind us, and we can Discover changes promptly

If you find any deficiencies while reading, please leave a message! ! !

Guess you like

Origin blog.csdn.net/qq_40065776/article/details/132853851