difference between collection and association mapping in mybatis 3

user533 picture user533 · Sep 14, 2012 · Viewed 21.6k times · Source

I am doing mysql queries execution from mybatis3. I am new to this. What is the difference between collection and association mapping in mybatis 3?

Specific example below.

SELECT e.empid AS empid,e.empname AS empname,
       e.empsalary AS empsalary,p.proname AS proname,p.proid AS proid 
FROM projects p,employees e,projectassigns pa 
WHERE pa.empid=e.empid AND pa.proid=p.proid; 

I need all the details of employee and project.

I have given the result map as follows.

<resultMap id="resultProjects" type="com.pratap.model.ProjAssigns"> 
  <association property="employee" javaType="com.pratap.model.Employee"
               resultMap="resultEmployees" />
  <association property="project" javaType="com.pratap.model.Project"     
               resultMap="resultProjects" />  
</resultMap>

Can anybody explain the difference taking my example or your own example?

I am confused with this..

Thank you.

Answer

quux00 picture quux00 · Sep 16, 2012

I am going to assume that you have a many to many relationship between Projects and Employees, which is why you created a Project Assignment table. This Project Assignment table / object may only have two fields/columns: a mapping of project id to employee id - a classic "bridge table" (aka "join" or "junction" table).

When you map this model to an object graph, you have three options:

  1. A Project object can have a list of all employees assigned to it
  2. An Employee object can have a list of projects s/he is assigned to
  3. Create a Project Assignment object that has a mapping of each projects to its employee and each employee to his/her project.

In your example you chose the last option.


Association

An association is a single mapping for a "has-one" relationship.

Suppose an Employee can only be assigned to one Project at a time. Some models call this a "has-one" or "belongs to" relationship. If you want to make Employee your "primary" focus in the object graph, then you would map it with an association to his/her Project:

<resultMap id="employeeResultMap" type="Employee">
  <constructor>
    <idArg column="employee_id" javaType="_integer"/>
  </constructor>
  <result property="firstName"  column="first_name"/>
  <result property="lastName" column="last_name"/>
  <!-- etc. for other simple properties of Employee -->

  <!-- Project is a "complex property" of Employee, so we use an -->
  <!-- association to grab all of the Projects properties also -->
  <association property="assignedProject" resultMap="projectResultMap"/>
</resultMap>

In this case your objects would look like this:

public Employee {
  int id;
  String firstName;
  String lastName
  Project assignedProject;
}

public Project {
  int id;
  String name;
  String abc;
}


Collection

An collection is a "list" or "set" of associations.

Now model the inverse - we make Project the primary focus. A Project has a "has-many" relationship with Employee, so it will have a list or collection of those, so we use a "collection" mapping:

<resultMap id="projectResultMap" type="Project">
  <constructor>
    <idArg column="project_id" javaType="_integer"/>
    <arg column="name" javaType="String"/>
  </constructor>
  <result property="abc" column="abc"/>

  <!-- This tells mybatis that there can be multiple Employees -->
  <!-- to look up and get their properties -->
  <collection property="employees" ofType="Employee">
    <constructor>
      <idArg column="employee_id" javaType="_integer"/>
    </constructor>
    <result property="firstName"  column="first_name"/>
    <result property="lastName" column="last_name"/>
  </collection>
</resultMap>

Now your objects would look like this:

public Employee {
  int id;
  String firstName;
  String lastName
}

public Project {
  int id;
  String name;
  String abc;
  List<Employee> employees;
}


Project Association

To have a Project Association object, you would either need:

  1. A single Project Association object that maps all projects to employees and vice versa
  2. One Project Association object per project, mapping a project to its employees
  3. One Project Association object per employee, mapping an employee to his/her projects

The first option is rather complex and messy - you would be trying to do relational mapping with object graphs (hash tables most likely).

I would choose to make one of the entities (Project or Employee) the primary focus and then model it as I showed above. The one case I didn't cover is if Employee is your primary focus and an Employee can be on multiple projects, then make that a "has-many" relationship using a collection rather than the association I used above.

Final Note: if it would help to see examples of using a "has-one" association and a "has-many" collection, see the MyBatis Koans I created: https://github.com/midpeter444/mybatis-koans. Koans 10 and 11 demonstrate this.