Namagiri Sridhar
Namagiri Sridhar

Reputation: 187

return only specific fields

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

Answers (1)

MohamedSanaulla
MohamedSanaulla

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

Related Questions