Mapstruct Mapping from Resultset

  Kiến thức lập trình

I am attempting to use Mapstruct to map a DTO from a ResultSet.

This is not directly possible without using expresson in the @Mapping annotation like this:

    @Mapping(target="name", expression = "java(rs.getString("propName"))")
    @Mapping(target="value", expression = "java(rs.getString("propValue"))")
    NameValuePair map(ResultSet rs) throws SQLException;

This is an ugly solution. However, the Mapstruct developers have decided they will not provide direct support for ResultSet mapping (source).

Is it possible to use Mapstruct @Context and qualifiedByName to do something like this (this doesn’t work because ResultSet doesn’t have a field named “source”)?

     // doesn't work, source doesn't exist on ResultSet
    @Mapping(target="name", source="name", qualifiedByName = "stringValue")
    @Mapping(target="value", source="value", qualifiedByName = "stringValue")
    NameValuePair map(String source, @Context ResultSet rs);

    @Named("stringValue")
    default String stringValue(String source, @Context ResultSet resultSet) {

        try {
            String result = resultSet.getString(source);
            return result;
        } catch (SQLException e) {
            return null; // no, I'm not really going to return null
        }
    }

I’ve looked for an easy explanation in the Mapstruct reference guide, but nothing is jumping out at me.

Can anyone help?

EDIT 2: Implementation of NameValuePair

@Data
@NoArgsConstructor
@AllArgsConstructor
public class NameValuePair {

    private String name;
    private String value;
    
    // convenience constructor for going from a Map<String, Object> but
    // you're sure value is a string
    public NameValuePair(Object name, Object value) {
        this((String) name, (String) value);
    }

}

EDIT: To you anonymous people voting to close my question, why don’t you tell me what’s wrong with it?

Your target has to be a property in your output object, in your case, it is NameValuePair. Meaning to say, both “name” and “value” are String properties in this class.

Can you provide a snippet of that class? Additionally, can you also provide a snippet of your ResultSet.getString(String source) method?

Edit: You mapped your source wrongly. You should map it as so:

@Mapping(target="name", source="source", qualifiedByName = "stringValue")
@Mapping(target="value", source="source", qualifiedByName = "stringValue")
NameValuePair map(String source, @Context ResultSet rs);

To further illustrate this mapping, imagine:

@Getter
public class Source {
    private String name;
}

A Mapstruct mapper for above class would then be:

@Mapping(target="name", source="source.name", qualifiedByName = "stringValue")
@Mapping(target="value", source="source.name", qualifiedByName = "stringValue")
NameValuePair map(Source source, @Context ResultSet rs);

Or alternatively:

@Mapping(target="name", source="source", qualifiedByName = "qualifySource")
@Mapping(target="value", source="source", qualifiedByName = "qualifySource")
NameValuePair map(Source source, @Context ResultSet rs);

with its @Named method:

@Named("qualifySource")
default String stringValue(Source source, @Context ResultSet resultSet) {

    try {
        String result = resultSet.getString(source.getName());
        return result;
    } catch (Exception e) {
        return "";
    }
}

3

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT