projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.9k stars 2.39k forks source link

[FEATURE] @FieldNameConstants add custom generation strategy for fieldname function #2157

Open SummerXSH opened 5 years ago

SummerXSH commented 5 years ago

Now @FieldNameConstants generate field name is

@FieldNameConstants()
@Data
public class Test {
    private Integer userId;
    private String userName;
    private Date birthday;

    public static class Fields {
        public static String userId = "userId";
        public static String userName = "userName";
        public static String birthday = "birthday";
    }
}

can add custom generate strategy function for field name ? From example :

@FieldNameConstants(strategy = Strategy.UpToUnderline)
@Data
public class Test {
    private Integer userId;
    private String userName;
    private Date birthday;

    public static class Fields {
        public static String userId = "user_id";
        public static String userName = "user_name";
        public static String birthday = "birthday";
    }
}

"UpToUnderline" this way is friendly for mapping of DB field .

Maaartinus commented 5 years ago

@SummerXSH I'm rather sure, you can't. As Lombok runs during compilation, it can't rely on your Strategy.UpToUnderline being compiled and ready to be called. Actually, Lombok has basically access to nothing but the current compilation unit.

In case you're asking if Lombok provides such strategies, the answer is no as well.


Nonetheless, there may be a way: Use @FieldNameConstants(asEnum=true), add

public enum Fields {
    public String underlinedName() {
        // https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/base/CaseFormat.html
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.UNDERSCORE, name());
        // or your own implementation
    }
}

I haven't tried this. This way you won't get compile-time constants, actually, you wan't get any constants.


In case it works, you could avoid code repetitions with

public enum Fields implements YourFieldNameConstantsInterface {
}

and default methods in your interface. I haven't tried this either.

SummerXSH commented 5 years ago

Thanks for your answer,I understand what you said.If can't customize generate strategy, can provide a choice for generate field name ? From example :

@FieldNameConstants(type = "UpToUnderline")
@Data
public class Test {
    private Integer userId;
    private String userName;
    private Date birthday;

    public static class Fields {
        public static String userId = "user_id";
        public static String userName = "user_name";
        public static String birthday = "birthday";
    }
}

Or at lombok.config file configuration just like lombok.fieldNameConstants.uppercase = true. I mean is how to get 'UpToUnderline' way field name.eg: userName -> user_name. This way of field name can use in com.baomidou.mybatisplus.core.conditions.query.QueryWrapper calss .

Maaartinus commented 5 years ago

@SummerXSH This is a working example printing USER_NAME:

import java.time.LocalDate;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
import com.google.common.base.CaseFormat;

@FieldNameConstants(asEnum=true)
@Data
public class SummerXsh {
    private Integer userId;
    private String userName;
    private LocalDate birthday; // much better than `Date`

    public enum Fields {
        ; // This is necessary!
        public String underlinedName() {
            // https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/base/CaseFormat.html
            return CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, name());
            // or your own implementation
        }
    }

    public static void main(String[] args) {
        System.out.println(Fields.userName.underlinedName());
    }
}

However, the docs says literally

in that case lombok will try to UPPER_CASE the name.

which most probably does exactly what you want. It needs v1.18.8, which I don't have yet, so try it yourself.


Please format your post using three backticks like this:

```java
class Foo {
  // formatted java code
}
This will be rendered as:
```java
class Foo {
  // formatted java code
}
SummerXSH commented 5 years ago

Your example need add unnecessary code to each required class。I think it is not good. I think the way ("userName -> user_name" ) is useful, so I hope Lombok can add this new feature.

rspilker commented 5 years ago

@SummerXSH, can you explain how you would use this? I mean, I know most mapping frameworks have already a way to map field naming strategies, and most databases don't care about the casing.

It is not obvious to me that being able to generate lowercase-with_underscores would reduce a lot of boilerplate. And having it configurable does increase the maintenance load.

tim-ooohtv commented 2 years ago

I have a similar case where I would like to have custom naming:

@FieldNameConstants(asEnum = true)
public class User {
    @JsonProperty("_id")
    private String id;
    private String name;

    // The generated enum
    public enum Fields {
        _id,
        name
    }
}

Ideally to make it more generic, it would be nice to have a separate field annotation e.g. @FieldNameConstant("_id") since the underlying name could be from @Column, @JsonProperty, @Field, etc

ManOki commented 1 year ago

In addition add another string containing the original camel-case name (at least to enum).

Otherwise there is no simple mapping from USERNAME or USER_NAME to userName.