MyBatis是一款流行的Java ORM框架。我们可以使用它来实现数据的持久化操作。在MyBatis中,很多查询的结果都是List对象,但是有时候我们需要将复杂的结果集映射到List对象中。这个时候我们可以使用MyBatis中的ResultMap进行映射。
ResultMap是 MyBatis 映射语句中最重要的元素之一。 它可以很好地将复杂类型的结果集,映射成 Java 中比较复杂的对象(AssembleObject)。下面是利用ResultMap映射复杂类型list的攻略:
创建POJO类
首先,我们需要创建一个POJO类,来对应结果集中的每一条记录。例如,我们创建一个Student类,包含id、name、age、gender这四个属性:
public class Student {
private int id;
private String name;
private int age;
private String gender;
//省略getter/setter方法
}
创建ResultMap配置
在MyBatis的映射文件中,我们需要创建一个ResultMap来映射上面的POJO类。配置的方式如下:
<resultMap id="studentMap" type="com.example.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="gender" column="gender"/>
</resultMap>
上面的配置中,我们创建了一个id为studentMap的ResultMap,并将type属性设置为我们创建的Student类。接下来,我们为每个属性制定映射关系。因为我们的表中列名和属性名是相同的,所以这里可以直接省略column属性。如果列名和属性名不同,使用column属性指定映射关系。
将ResultMap应用到SQL语句中
在执行SQL语句的时候,我们使用ResultMap来映射结果集。例如,我们有如下的SQL语句:
<select id="selectAllStudents" resultMap="studentMap">
select * from student
</select>
这里使用了select标签来执行SQL语句,resultMap属性指定了我们刚才创建的studentMap。
示例1:映射一对多关系
下面我们举一个映射一对多关系的例子。假设我们有一个班级表classroom,其中每个班级有多个学生,我们需要查询出所有的班级信息及对应的学生信息。我们可以将班级和学生合并成一个结果集,根据班级的id分组,然后使用ResultMap将结果映射为List
<resultMap id="classroomMap" type="com.example.Classroom">
<id property="id" column="id"/>
<result property="name" column="name"/>
<collection property="students" ofType="com.example.Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<result property="age" column="student_age"/>
<result property="gender" column="student_gender"/>
</collection>
</resultMap>
<select id="selectAllClassrooms" resultMap="classroomMap">
select c.id,c.name,s.id as student_id,s.name as student_name,s.age as student_age,s.gender as student_gender
from classroom c
left join student s on c.id = s.classroom_id
order by c.id
</select>
上面的配置中,我们创建了一个id为classroomMap的ResultMap,并将type属性设置为我们创建的Classroom类。在ResultMap中,我们为Classroom类的每个属性,制定了对应的映射关系。对于students属性,我们使用collection标签来将一个Classroom对象中的students属性映射为多个Student对象。由于一个Classroom对象包含多个Student对象,我们需要使用ofType属性来指定集合中元素的类型。
注意到上面的Sql语句中,我们快速连接了两张表,将结果转化为了我们需要的样式(一条classroom记录对应多条student记录),由于多条记录不会映射为一个对象,所以我们需要用Collection解决。
示例2:映射嵌套List关系
下面我们举一个映射嵌套List关系的例子。假设我们有一个部门表department,其中每个部门下面有多个员工,而且每个员工还对应多个技能属性。我们需要查询所有的部门信息及其下面的所有员工和对应的技能信息。我们可以将部门、员工、技能合并成一个结果集,然后使用ResultMap将结果映射为List
public class Department {
private int id;
private String name;
private List<Employee> employees;
//省略getter/setter方法
}
public class Employee {
private int id;
private String name;
private int age;
private List<Skill> skills;
//省略getter/setter方法
}
public class Skill {
private int id;
private String name;
//省略getter/setter方法
}
<resultMap id="departmentMap" type="com.example.Department">
<id property="id" column="department_id"/>
<result property="name" column="department_name"/>
<collection property="employees" ofType="com.example.Employee">
<id property="id" column="employee_id"/>
<result property="name" column="employee_name"/>
<result property="age" column="employee_age"/>
<collection property="skills" ofType="com.example.Skill">
<id property="id" column="skill_id"/>
<result property="name" column="skill_name"/>
</collection>
</collection>
</resultMap>
<select id="selectAllDepartments" resultMap="departmentMap">
select d.id as department_id,d.name as department_name,e.id as employee_id,e.name as employee_name,e.age as employee_age,
s.id as skill_id,s.name as skill_name
from department d
left join employee e on d.id = e.department_id
left join skill s on e.id = s.employee_id
order by d.id,e.id
</select>
上面的配置中,我们创建了一个id为departmentMap的ResultMap,并将type属性设置为我们创建的Department类。在ResultMap中,我们为Department类的每个属性,制定了对应的映射关系。对于employees属性,我们使用collection标签来将一个Department对象中的employees属性映射为多个Employee对象。对于skills属性,我们使用collection标签将一个Employee对象中的skills属性映射为多个Skill对象。
在SQL语句中,我们使用多个left join进行连接,将结果转换为以部门和员工为外键的唯一记录,然后就可以方便地使用collection标签进行多重嵌套的映射。
形如请求:
GET /api/selectAllDepartments
返回测试数据:
[
{
"id":1,
"name":"开发部",
"employees":[
{
"id":1,
"name":"张三",
"age":25,
"skills":[
{
"id":1,
"name":"Java"
},
{
"id":2,
"name":"C++"
}
]
},
{
"id":2,
"name":"李四",
"age":28,
"skills":[
{
"id":3,
"name":"JavaScript"
},
{
"id":4,
"name":"SQL"
}
]
}
]
},
{
"id":2,
"name":"市场部",
"employees":[
{
"id":3,
"name":"王五",
"age":30,
"skills":[
{
"id":5,
"name":"销售"
},
{
"id":6,
"name":"客户接待"
}
]
},
{
"id":4,
"name":"赵六",
"age":32,
"skills":[
{
"id":7,
"name":"市场调研"
},
{
"id":8,
"name":"销售管理"
}
]
}
]
}
]
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis 如何利用resultMap复杂类型list映射 - Python技术站