Reputation: 187
String sql = "SELECT " + columnList + " FROM result";
List<Result> result = jdbcTemplate.query(sql, new ResultRowMapper());
Result Class has so many fields . I want to return only those fields specified in the column list in my JSON whether null or not null. Solution I came up with is to create a temp class with the fields in the columnlist on the fly and then use it like below:
List<TempClass> result = jdbcTemplate.query(sql, new ResultRowMapper());
Any suggestions on how should I create this Temp class? Fields will change based on user input.
Thanks for your time.
Upvotes: 0
Views: 1757
Reputation: 6242
From your query and comment above you indicate that the column list in SELECT
clause is dynamic which means even the RowMapper
would change based on the list.
Let's create an interface ResultRowMapper
which extends org.springframework.jdbc.core.RowMapper
as shown below:
public interface ResultRowMapper extends RowMapper<Person> {
default List<String> getColumnList(){
return Arrays.asList("id", "first_name", "last_name", "dob", "place_of_birth", "address");
}
default String getColumnListAsString(){
return getColumnList().stream().collect(Collectors.joining(", "));
}
@Override
default Person mapRow(ResultSet resultSet, int i) throws SQLException {
Person p = new Person();
p.setId(resultSet.getLong("id"));
p.setFirstName(resultSet.getString("first_name"));
p.setLastName(resultSet.getString("last_name"));
p.setAddress(resultSet.getString("address"));
p.setPlaceOfBirth(resultSet.getString("place_of_birth"));
return p;
}
}
Then I will create different implementations of this ResultRowMapper
interface based on our needs:
@Component("DefaultResultRowMapper")
public class DefaultResultRowMapper implements ResultRowMapper {
}
@Component("NameResultRowMapper")
public class NameResultRowMapper implements ResultRowMapper {
@Override
public List<String> getColumnList(){
return Arrays.asList("id", "first_name", "last_name");
}
@Override
public Person mapRow(ResultSet resultSet, int i) throws SQLException {
Person p = new Person();
p.setId(resultSet.getLong("id"));
p.setFirstName(resultSet.getString("first_name"));
p.setLastName(resultSet.getString("last_name"));
return p;
}
}
@Component("AddressResultRowMapper")
public class AddressResultRowMapper implements ResultRowMapper {
@Override
public List<String> getColumnList(){
return Arrays.asList("id", "dob", "place_of_birth", "address");
}
@Override
public Person mapRow(ResultSet resultSet, int i) throws SQLException {
Person p = new Person();
p.setId(resultSet.getLong("id"));
p.setAddress(resultSet.getString("address"));
p.setPlaceOfBirth(resultSet.getString("place_of_birth"));
return p;
}
}
Then in the Spring boot application I will use it in the following way:
@Slf4j
@SpringBootApplication
public class CustomRowMapperApplication implements ApplicationRunner {
@Autowired @Qualifier("NameResultRowMapper")
ResultRowMapper nameResultRowMapper;
@Autowired @Qualifier("DefaultResultRowMapper")
ResultRowMapper defaultResultRowMapper;
@Autowired @Qualifier("AddressResultRowMapper")
ResultRowMapper addressResultRowMapper;
@Autowired
JdbcTemplate jdbcTemplate;
public static void main(String[] args) {
new SpringApplication(CustomRowMapperApplication.class).run(args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
List<Person> peopleWithName = jdbcTemplate.query("SELECT " + nameResultRowMapper.getColumnListAsString()
+ " FROM person", nameResultRowMapper);
log.info("People with name: {} ", peopleWithName);
List<Person> people = jdbcTemplate.query("SELECT " + defaultResultRowMapper.getColumnListAsString()
+ " FROM person", defaultResultRowMapper);
log.info("People with all detail: {} ", people);
List<Person> peopleWithAddress = jdbcTemplate.query("SELECT " + addressResultRowMapper.getColumnListAsString()
+ " FROM person", addressResultRowMapper);
log.info("People with address: {} ", peopleWithAddress);
}
}
Upvotes: 1