0

Good evening guys, I'm trying to implement a jdbctemplate model with controller / Service / Dao / DaoImpl / and Mapper ... But by the models I see the mapper needs to implement RowMapper or ParameterizedRowMapper and both have a maprow method that does not return a List. As I needed a List I implemented a method in the mapper to get me the list I needed. but I do not know what to call it. In the customerList method I have to pass the CustomerMapper inside the query like this:

jdbcTemplate.query (sql, new CustomerMapper (), id);

And the customer mapper must implement either RowMapper or ParameterizedRowMapper so that the jdbcTemplate.query accept it and along with RowMapper or ParameterizedRowMapper the maprow method must come.

When I call the Mapper method via the listCustomer when entering the CustomerMapper class it automatically enters the first mapRow method and does not enter the method I wanted listCustomer that would return the List that I need.

Any idea how to help me do this?

I need to return a list of customers. just this! But following this form of implementation...

Thank you!

My class:

@Controller
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @ResponseBody
    @RequestMapping(value = "/customer/{id}", method = RequestMethod.GET)
    public Map<String, Object> searchCustomer(@PathVariable(value="id") Long id, 
            final HttpServletRequest request) throws IOException, SQLException {

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

        List<Customer> customerList = customerService.searchCustomer(id);

        map.put("customer", customerList);

        return map;
    }


}
SERVICE
@Service
public class CustomerService {

    @Autowired
    private CustomerDAO dao;

    public List<Customer> searchCustomer(Long id) throws SQLException {

        return dao.listCustomer(id);

    }

}

DAO
public interface CustomerDAO {


    List<Customer> listCustomer(Long id);

}

DAOIMPL
public class CustomerDAOImpl implements CustomerDAO {

    @Autowired
    private SimpleJdbcTemplate jdbcTemplate;    
    String sql = "SELECT  * FROM purchases C WHERE C.ID = ?";


    public List<Customer> listCustomer(Long id) {
        return jdbcTemplate.query(sql, new CustomerMapper(), id);
    }

}

//MAPPER
public class CustomerMapper implements RowMapper<Customer>{


    public Customer mapRow(ResultSet rs, int arg1) throws SQLException {

        ... "N" RULES INSIDE BUT DONT RETURN ArrayList OR LIST.... ANYAWAY..


        //THIS METHOD IS INTERFACE INHERITANCE AND HAS TO BE IMPLEMENTED
        //BUT I NEED A METHOD THAT RETURNS A LIST OF CUSTOMERS FOR THE CONTROLLER
        //AND THEREFORE IT RETURNS JUST 1 CUSTOMER 

    }

    //SO I CREATED THIS OTHER METHOD THAT RETURNS A LIST OF CUSTOMERS AND 
    //IMPLEMENTED IN THE INTERFACE ... BUT I DO NOT KNOW HOW THE MAPPER CALLS IT ...
     //NOT MAPROW
    public List<Customer> listCustomer(ResultSet rs, int arg1) throws SQLException {

        List<Customer> customerList = new ArrayList<Customer>();

        Customer customer = new Customer();

        while (rs.next()) {
            if (rs.getString("ID") != null)
            customer.setEtpId(rs.getString("ID"));
            ......
            ......
            customerList.add(customer);
        }

        return customerList;

    }

}

sorry, I did not put a whole query of an example, but I'm sorry if it was poorly explained. Well, what I need is to pass the customer number to make a select in the table of purchases for example, and bring me all purchases from that customer.

for example.

Select * from table purchases p where p.customerid = 4;

This would be the query, so let's imagine that it returns 5 records. I want the mapper to return me a list of buying objects (not customer) with the 5 purchases that that customer made.

Understood now?

I will set the example for better understanding.

Thanks for the answers!

Barzectree
  • 77
  • 1
  • 2
  • 7
  • You don’t need to return a list. It is called rowmapper for a reason. It maps a row. The jdbctemplate will use that to convert all records of the result into a customer and return a list of customers, you don’t need to worry about that. – M. Deinum Sep 07 '18 at 07:09
  • Also how can a query on the primary key, id, result in multiple rows. – M. Deinum Sep 07 '18 at 07:11
  • @M.Deinum sorry, I did not put a whole query of an example, but I'm sorry if it was poorly explained. Well, what I need is to pass the customer number to make a select in the table of purchases for example, and bring me all purchases from that customer. for example. Select * from table purchases p where p.customerid = 4; This would be the query, so let's imagine that it returns 5 records. I want the mapper to return me a list of buying objects (not customer) with the 5 purchases that that customer made. Understood? I will set the example for better understanding. Thanks for the answers! – Barzectree Sep 07 '18 at 15:35
  • The mapper still should return a single element. The jdbctemplate wwill call the mapRow method for each row in the results et. It will then construct a list out of it. So no you don’t need it to return a list. – M. Deinum Sep 07 '18 at 19:06

3 Answers3

1

Seems like the problem lies in the understanding of RowMapper.

Since, Jdbc has no idea of how you want to map your row to an object, it asks you for the mapping. So the RowMapper's sole responsibility is to provide this mapping. Nothing else. Change your mapRow like below.

public Customer mapRow(ResultSet rs, int arg1) throws SQLException {

     Customer customer = null;

     if (rs.getString("ID") != null){
        customer = new Customer()
        customer.setEtpId(rs.getString("ID"));
        ......
        ......
     }
     return customer;
}

JdbcTemplate will apply this mapper to map a row with an object. If you have multiple rows, it will convert all the rows to a list of Customers using this rowMapper. JdbcTemplate will do this transparently so that you don't need to worry about it.

Edit:

After your edit, you are explaining that you need a list of purchase information from purchases table for a given customer. For that case, you actually need a PurchaseRowMapper. That will map a record from your purchases table with a Class named (maybe) PurchaseInformation. That will return you a list of PurchaseInformation objects.

Sazzadur Rahaman
  • 6,938
  • 1
  • 30
  • 52
  • Sazzadur thanks for the reply, but it does not happen the way you are saying. JDBC will overwrite the customer list, that is, if I have 5 customers on the list, my return will only be the fifth or last in the list. What I need is to return the 5 within an object understand? I tried it the way you explained and it does not return the 5 .. – Barzectree Sep 07 '18 at 15:09
  • @Barzectree, I have updated my answer, let me know whether this addresses your need. Thanks! – Sazzadur Rahaman Sep 07 '18 at 16:55
1

I have find the solution... this example with another entity but it works!

           String sqlSelectQuery = "SELECT name, email, address, telephone FROM contact";
52
            List listContacts = jdbcTemplateObj.query(sqlSelectQuery, new RowMapper() {
53
                public Contact mapRow(ResultSet result, int rowNum) throws SQLException {
54
                    Contact contactObj = new Contact();
55
                    contactObj.setName(result.getString("name"));
56
                    contactObj.setEmail(result.getString("email"));
57
                    contactObj.setAddress(result.getString("address"));
58
                    contactObj.setPhone(result.getString("telephone"));
59
                    return contactObj;
60
                }
61
            });
62

63
            // Displaying The SQL Records
64
            for (Contact contactDetail : listContacts) {
65
                System.out.println(contactDetail.toString());
66
            }
67
Barzectree
  • 77
  • 1
  • 2
  • 7
-1

Rowmapper Implementaion :

public class CustomerMapper implements RowMapper<Customer>{

  List<Customer> customerList = new ArrayList<Customer>();

 public Customer mapRow(ResultSet rs, int arg1) throws SQLException {      
  Customer customer = new Customer();
    while (rs.next()) {
        if (rs.getString("ID") != null)
        customerList.add(rs.getString("ID"));
    }
    customer.setEtpId(customerList);
    return customer;
  }
}

Above code will return list of customer's. Please refer to https://stackoverflow.com/a/27593565/2695504 or RowMapper vs ResultSet for rowMapper explanation.

Ramesh
  • 161
  • 2
  • 11
  • Although correct you shouldn’t do that in a RowMapper. It should map a single row. – M. Deinum Sep 07 '18 at 07:10
  • May I know the reason please – Ramesh Sep 07 '18 at 07:39
  • Because spring will call the mapRow method for each result. You don’t need to iterate yourself. – M. Deinum Sep 07 '18 at 14:06
  • Ramesh this is so strange, is not it? You can be a list of clients, ie you will receive items of the type costumers ... you add a list in that list and then add a list to the object ... will become a mess not? If you have not returned, do not have a list, that is every time you go through the id and give an add it will overwrite .... – Barzectree Sep 07 '18 at 15:25