Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Analog of BeanPropertySqlParameterSource that can handle public fields

I have a simple model, instances of which I want to save in MySQL using Spring JDBCTemplate. I use DAO that saves model objects using simple sql (insert into user(id, email...) value (:id, :email...)). Is there any framework that can extract parameters from the model (when the model is just POJO with public fields). So, I need something similar to Spring's BeanPropertySqlParameterSource, but with the ability to work with public fields instead of properties.

Example of the model class:

public class User {
    public int id;
    public String email;
    public String login;
    public String password;
}

I know that extending AbstractSqlParameterSource can solve my problem, but I hope to find existing framework.

UPD

Implementation based on AbstractSqlParameterSource:

public class PublicFieldsSqlParameterSource extends AbstractSqlParameterSource {

    Map<String, Object> props = new HashMap<>();

    public PublicFieldsSqlParameterSource(Object object) {
        Field[] fields = object.getClass().getFields();
        for (Field field : fields) {
            String name = field.getName();
            try {
                Object value = field.get(object);
                props.put(name, value);
            } catch (IllegalAccessException ignored) {
            }
        }
    }

    @Override
    public boolean hasValue(String paramName) {
        return props.containsKey(paramName);
    }

    @Override
    public Object getValue(String paramName) throws IllegalArgumentException {
        return props.get(paramName);
    }
}
like image 549
Ernest Sadykov Avatar asked Jul 27 '15 13:07

Ernest Sadykov


1 Answers

As mentionned in my comment if the reason for not wanting getter/setters is code clutter, I would recommend Lombok.

Here is a typical model class, that can be constructed by Spring (@NoArgsConstructor + @Data for getters and setters). @Builder and @AllArgsConstructor allow the generation of the Builder pattern with all fields.

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SubscriptionData {

    @Id
    @Indexed
    private UUID key;

    private String productId;

    private String receiptString;

    private Date expirationDate;

}

Here is an example of a Spring service with constructor injection. The @RequiredArgsConstructor creates a constructor with all the non-initialized final fields and the onConstructor parameter adds the Spring-@Autowired annotation to it. If you have many service-dependencies this can remove quite some clutter.

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__({ @Autowired }))
public class OperatorServiceImpl implements OperatorService {

  private final WhoisService whoisService;

  ...
}
like image 184
revau.lt Avatar answered Oct 20 '22 00:10

revau.lt