5

I have two classes

class Deptartment{
  int deptid,
  String deptname;
  List<Employee> employees;

}

class Employee{

 int empid;
 String empname;
 int deptid;

}

Table: 
Department:

    deptid,deptname

Employee

    empid,empname,deptid

Query: select * from deptartment d,employee e where  d.deptid= e.deptid

Now how can i populate Department object using spring jdbc template?

0

3 Answers 3

10

To help Sean Patrick Floyd, here's his solution with a single query :

final Map<Integer, Department> departments = new HashMap<Integer, Department>();
this.jdbcTemplate.query(
    "select d.deptid, d.deptname, e.empid, e.empname from Department d inner join Employee on e.deptid = e.deptid",
    new RowMapper<Employee>() {
        public Department mapRow(ResultSet rs, int rowNum) throws SQLException {
            Integer deptId = rs.getInt("deptid");
            Department d = (Department) departments.get(deptId);
            if (d == null) {
                String deptName = rs.getString("deptname");
                d = new Department();
                d.setDeptId(deptId);
                d.setDeptName(deptName);
                departments.put(deptId, d);
            }
            Employee employee = new Employee();
            employee.setEmpId(rs.getInt("empid"));
            employee.setEmpName(rs.getString("empname"));
            employee.setDeptId(deptId);
            d.getEmployees().add(employee);
            return employee;
        }
    });
List<Department> result = new ArrayList<Department>(departments.values());    

It happens to be shorter and more efficient.

Sign up to request clarification or add additional context in comments.

2 Comments

Could this whole code snippet be extracted in a separate class, which implements RowMapper<Employee>?
It would be nice if you could use ParameterizedBeanPropertyRowMapper.newInstance e.g. ParameterizedBeanPropertyRowMapper.newInstance(Employee.class) to map the attributes as well as for your department without the need for rs.gets.
2

There is no direct support of this scenario in Spring currently. However, you can use the following MultipleRowMapper class proposed for inclusion into future versions of Spring.

3 Comments

isn't this doable with a ResultsetExtractor?
@abalogh: Obviously, you can do it manually as well, but the proposed class simplifies it.
You're right, I've checked the link, just was surprised you wrote 'no direct support', which at first I understood as 'not doable' :)
0

Something like this will do:

Department department = this.jdbcTemplate.queryForObject(
        "select deptid, deptname from Department where deptid = :deptid",
        new Object[deptid],
        new RowMapper<Department>() {
            public Department mapRow(ResultSet rs, int rowNum) throws SQLException {
                Department department = new Department();
                department.setDeptid(rs.getInt("deptid"));
                department.setDeptname(rs.getString("deptname"));
                return department;
            }
        });
department.setEmployees(this.jdbcTemplate.query(
        "select empid, empname from Employee",
            new RowMapper<Employee>() {
                public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Employee employee = new Employee();
                    employee.setEmpid(rs.getInt("emptid"));
                    employee.setEmpname(rs.getString("empname"));
                    return department;
                }
            });

4 Comments

So, instead of one query, you are executing n + 1 (n being the number of departements). I wouldn't call this a good solution.
@JB Nizet: of course it would be much more efficient with a join, but the Java side would get a lot more complicated and I'm lazy.
I wanted the code for retriving a department given a deptid, so there will be one department object containing a List<Employee>, can you please provide a code snippet for it
@akshay : then why did you specify a query returning all the departments with all their emmployees?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.