Nested Classes - CustomRowMapper !! Not a Problem Anymore !! - Part 1
Tags: java, mysql, spring, coding
Published: 2022-03-25 17:54:21


**What is Spring Boot:**
Spring Boot is an open source, microservice-based Java web framework.

**RowMapper:**
RowMapper<T> interface is used by JdbcTemplate for mapping rows of a ResultSet on a per-row basis.

**Introduction**
Here we are going to use custom row mapper when we want only a single object as return type

**Problem in RowMapper for nested Classes:**
We can't directly assign  parameters returned from DB to the class model because we never able to exact individual primitive data types variable due to nesting of classes.

##Class Diagram used in this Example:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhdhjxwr3ylkpuyhmpi2.png)

##Simple Class : Not Nested Classes
**SportsMasterDTO.java**
```java
package workspace;

public class SportsMasterDTO {
  private int id;
  private String sportsCode;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getSportsCode() {
    return sportsCode;
  }

  public void setSportsCode(String sportsCode) {
    this.sportsCode = sportsCode;
  }
}

```
**SportsMetaDTO Class:**
```java
package workspace;

public class SportsMetaDTO {
  private int id;
  private int sportsName;
  private int sportsMasterId;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public int getSportsName() {
    return sportsName;
  }
  public void setSportsName(int sportsName) {
    this.sportsName = sportsName;
  }
  public int getSportsMasterId() {
    return sportsMasterId;
  }
  public void setSportsMasterId(int sportsMasterId) {
    this.sportsMasterId = sportsMasterId;
  }
  @Override
  public String toString() {
    return "SportsMetaDTO [id=" + id + ", sportsName=" + sportsName + ", sportsMasterId="
        + sportsMasterId + "]";
  }
}

```
**ThresholdDTO class**
```java
package workspace;

public class ThresholdDTO {
  private int id;
  private int sportsMetaDataId;
  private String value;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public int getSportsMetaDataId() {
    return sportsMetaDataId;
  }

  public void setSportsMetaDataId(int sportsMetaDataId) {
    this.sportsMetaDataId = sportsMetaDataId;
  }

  public String getValue() {
    return value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return "ThresholdDTO [id=" + id + ", sportsMetaDataId=" + sportsMetaDataId + ", value=" + value
        + "]";
  }
  

}

```
## Nested Class:

**Nested Class: SportsThresholdCommonDTO**

```java
package workspace;

public class SportsThresholdCommonDTO {
  private SportsMasterDTO sportsMasterDTO;
  private SportsMetaDTO sportsMetaDTO;
  private ThresholdDTO thresholdDTO;
  public SportsMasterDTO getSportsMasterDTO() {
    return sportsMasterDTO;
  }
  public void setSportsMasterDTO(SportsMasterDTO sportsMasterDTO) {
    this.sportsMasterDTO = sportsMasterDTO;
  }
  public SportsMetaDTO getSportsMetaDTO() {
    return sportsMetaDTO;
  }
  public void setSportsMetaDTO(SportsMetaDTO sportsMetaDTO) {
    this.sportsMetaDTO = sportsMetaDTO;
  }
  public ThresholdDTO getThresholdDTO() {
    return thresholdDTO;
  }
  public void setThresholdDTO(ThresholdDTO thresholdDTO) {
    this.thresholdDTO = thresholdDTO;
  }
  @Override
  public String toString() {
    return "SportsThresholdCommonDTO [sportsMasterDTO=" + sportsMasterDTO + ", sportsMetaDTO="
        + sportsMetaDTO + ", thresholdDTO=" + thresholdDTO + "]";
  }
}
```


##How To use rowmapper if mysql returns a single object for nested class:
**MYSQL Query Which contain joins on 3 tables with limit 1**
```mysql
select 
  sm.id as sportsMasterId, 
  sm.sportsCode, 
  smd.id as sportsMetaId, 
  smd.sportsName, 
  smd.sportsMasterId, 
  t.id as thresholdId, 
  t.sportsMetaDataId, 
  t.value 
from 
  sportsMaster 
  inner join sportsMetaData smd on sm.id = smd.sportsMasterId 
  inner join threshold t on t.sporsMetaDataId = smd.id limit 1

```
**How to Access DataBase:**

**Java Method**
```java
public SportsThresholdCommonDTO getSportsThresholdCommonObject() {
    String sql =
        "select sm.id as sportsMasterId, sm.sportsCode, smd.id as sportsMetaId, smd.sportsName, smd.sportsMasterId, t.id as thresholdId, t.sportsMetaDataId, t.value from sportsMaster inner join sportsMetaData smd on sm.id = smd.sportsMasterId inner join threshold t on t.sporsMetaDataId = smd.id limit 1";
return jdbcTemplate.queryForObject(sql, SportsThresholdCommonDTO.class);
  }
```

##<u>The Wait Ends Here !!!</u>

**Mapper Class**
```java
package workspace;

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.tree.RowMapper;

public class SportsThresholdCommonMapper implements RowMapper<SportsThresholdCommonDTO> {

  @Override
  public SportsThresholdCommonDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
    SportsThresholdCommonDTO sportsThresholdCommonDTO = new SportsThresholdCommonDTO();
    SportsMasterDTO sportsMasterDTO = new SportsMasterDTO();
    SportsMetaDTO sportsMetaDTO = new SportsMetaDTO();
    ThresholdDTO thresholdDTO = new ThresholdDTO();
    sportsMasterDTO.setId(rs.getInt("sportsMasterId"));
    sportsMasterDTO.setSportsCode(rs.getString("sportsCode"));
    sportsMetaDTO.setId(rs.getInt("sportsMetaId"));
    sportsMetaDTO.setSportsName(rs.getString("sportsName"));
    sportsMetaDTO.setSportsMasterId(rs.getInt("sportsMasterId"));
    thresholdDTO.setId(rs.getInt("thresholdId"));
    thresholdDTO.setSportsMetaDataId(rs.getInt("sportsMetaId"));
    thresholdDTO.setValue(rs.getString("value"));
    sportsThresholdCommonDTO.setSportsMasterDTO(sportsMasterDTO);
    sportsThresholdCommonDTO.setSportsMetaDTO(sportsMetaDTO);
    sportsThresholdCommonDTO.setThresholdDTO(thresholdDTO);
    return sportsThresholdCommonDTO;
  }
}
```
##Alternate Way:
1. Make a new model which contains variable of all classes
2. Make Aliases to map t model properly
3. Result will be a unnested class with all data.

**Drawback of making another model**
1. Maintainability overheads
2. Making aliases and keeping different names in all models

**Conclusion**
We are able to get nested class object from mysql with the help of custom row mapper.