前言
简单来说在mybatis.xml中实现关联查询实在是有些麻烦,正是因为起框架本质是实现orm的半自动化。 那么mybatis实现一对一的关联查询则是使用association属性和resultMap属性。
搭建开发环境
创建student表、teacher表来搭建一对一的关联查询场景,student表添加外键supervisor_id实现和teacher表的关联
1 CREATE TABLE [dbo].[t_teacher]( 2 [id] [int] IDENTITY(1,1) NOT NULL, 3 [name] [nvarchar](30) NULL, 4 [title] [nvarchar](30) NULL, 5 PRIMARY KEY CLUSTERED 6 ( 7 [id] ASC 8 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 9 ) ON [PRIMARY] 10 11 GO
1 CREATE TABLE [dbo].[t_student]( 2 [id] [int] IDENTITY(1,1) NOT NULL, 3 [name] [nvarchar](30) NULL, 4 [major] [nvarchar](30) NULL, 5 [supervisor_id] [int] NULL, 6 PRIMARY KEY CLUSTERED 7 ( 8 [id] ASC 9 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 10 ) ON [PRIMARY]
一对一关联查询
一对一关联的关键是在mapper.xml中创建resultMap。 如下代码看到了在studentResultMap中添加了属性association,property是在model类中的外键属性名称,别忘记指定JavaType
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.autohome.mapper.Student"> 6 <resultMap id="studentResultMap" type="Student"> 7 <id property="id" column="id"/> 8 <result property="name" column="name"/> 9 <result property="major" column="major"/> 10 <association property="supervisor" javaType="Teacher"> 11 <id property="id" column="t_id" /> 12 <result property="name" column="t_name"/> 13 <result property="title" column="title"/> 14 </association> 15 </resultMap> 16 17 18 <select id="getStudentById" parameterType="int" resultMap="studentResultMap"> 19 SELECT st.id,st.name,st.major, 20 t.id t_id,t.name t_name,t.title 21 FROM t_student st inner join t_teacher t on st.supervisor_id=t.id 22 where st.id=#{id} 23 </select> 24 </mapper>
teacher model
public class Teacher { private int id; private String name; private String title; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
student model
public class Student { private int id; private String name; private String major; private Teacher supervisor; public Teacher getSupervisor() { return supervisor; } public void setSupervisor(Teacher supervisor) { this.supervisor = supervisor; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMajor() { return major; } public void setMajor(String major) { this.major = major; } }
单元测试
@Test public void getStudentById(){ SqlSession sqlSession=null; try{ sqlSession=sqlSessionFactory.openSession(); Student student = sqlSession.selectOne("com.autohome.mapper.Student.getStudentById",1); System.out.println("id:"+student.getId()+",name:"+student.getName()+",导师姓名:"+student.getSupervisor().getName()+",导师职称:"+student.getSupervisor().getTitle()); }catch(Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } }
附实现截图
嵌套resultMap
如上的resultmap用起来总是不方便的,万一后续再到其他关联查询需要用到teacher表呢,那么我们把teacherResultMap单独拿出来,不仅是resultMap可以嵌套,sql语句也可以嵌套。
分别创建studentResultMap和suprvisorResultMap。后在studentResultMap的association中使用resultMap引用supervisorResultMap。
<mapper namespace="com.autohome.mapper.Student"> <resultMap id="studentResultMap" type="Student"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="major" column="major"/> <association property="supervisor" resultMap="suprvisorResultMap"/> </resultMap> <resultMap id="suprvisorResultMap" type="Teacher"> <id property="id" column="t_id" /> <result property="name" column="t_name"/> <result property="title" column="title"/> </resultMap> <select id="getStudentById" parameterType="int" resultMap="studentResultMap"> SELECT st.id,st.name,st.major, t.id t_id,t.name t_name,t.title FROM t_student st inner join t_teacher t on st.supervisor_id=t.id where st.id=#{id} </select> </mapper>
实现结果和上面相同