宽为限 紧用功 工夫到 滞塞通
mybatis中对象与对象之间的关系与hibernate不同,hibernate可以直接通过配置,一步到位将对象关联到对应的对象里。
mybatis需要实现对象关联主要分这几步骤:
1、对象里包含要关联的对象;
2、额外提供一个属性存关联对象的id;
3、xml文件里配置association(与被关联的Mapper接口里的查询方法对应);
4、被关联的Mapper接口文件中提供对应的查询本对象方法(与association对应)。
mybatis中一对一级联在resultMap里是用 association属性配置的
在这里以学生(Student)和学生证(StudentSelfcard)之间的一对一关系来做案例,我们忽略次要的东西直接看主要的,这里Student里包含StudentSelfcard
,然后我们也添加了一个studentSelfcardId
属性,下面是Student类主要代码
...
/**
* 实际使用时的对象,mybatis通过studentSelfcardId关联
*/
private StudentSelfcard studentSelfcard;
public StudentSelfcard getStudentSelfcard() {
return studentSelfcard;
}
public void setStudentSelfcard(StudentSelfcard studentSelfcard) {
this.studentSelfcard = studentSelfcard;
}
/**
* 额外提供的属性,mybatis关联用
*/
private int studentSelfcardId;
public int getStudentSelfcardId() {
return studentSelfcardId;
}
public void setStudentSelfcardId(int studentSelfcardId) {
this.studentSelfcardId = studentSelfcardId;
}
...
这里先不说为什么要多一个额外属性,接下来我们看看studentMapper.xml文件里的配置
...
<mapper namespace="com.learn.chapter4.mapper.StudentMapper">
<resultMap id="studentMap" type="com.learn.chapter4.po.Student">
<id property="id" column="id" />
<result property="cnname" column="cnname" />
<result property="sex" column="sex" jdbcType="INTEGER" javaType="com.learn.chapter4.enums.SexEnum" />
<result property="studentSelfcardId" column="student_selfcard_id" />
<!-- 本条语句会通过select的内容去它对应的Mapper.xml文件里去找到对应id的select方法,并得到方法返回的对象 -->
<association property="studentSelfcard" column="id"
select="com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId" />
</resultMap>
<select id="getStudent" parameterType="int" resultMap="studentMap">
select * from t_student where id = #{id}
</select>
<!-- 在StudentSelfcardMapper.xml配置中通过本条语句找到关联的Student对象 -->
<select id="findStudentByStudentSelfcardId" parameterType="int" resultMap="studentMap">
select * from t_student where student_selfcard_id = #{studentSelfcardId}
</select>
</mapper>
ok,有疑问的话很正常,先存着。接下来我们看它关联的对象实体类及对应的xml配置文件,先是java文件
/**
* 实际使用时的对象,mybatis通过studentId关联
*/
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
/**
* 额外提供的属性,mybatis关联用
*/
private int studentId;
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
嗯,还是一个样,然后看studentSelfcardMapper.xml 文件
...
<mapper namespace="com.learn.chapter4.mapper.StudentSelfcardMapper">
<resultMap id="studentSelfcardMap" type="com.learn.chapter4.po.StudentSelfcard">
<id property="id" column="id" />
<result property="studentId" column="student_id" />
<result property="native_" column="native" />
<result property="issueDate" column="issue_date" />
<result property="endDate" column="end_date" />
<result property="note" column="note" />
<!-- 本条语句会通过select的内容去它对应的Mapper.xml文件里去找到对应id的select方法,并得到方法返回的对象 -->
<association property="student" column="id"
select="com.learn.chapter4.mapper.StudentMapper.findStudentByStudentSelfcardId" />
</resultMap>
<select id="getStudentSelfcard" parameterType="int" resultMap="studentSelfcardMap">
select * from t_student_selfcard where id = #{id}
</select>
<!-- 在StudentMapper.xml配置中通过本条语句找到关联的StudentSelfcard对象 -->
<select id="findStudentSelfcardByStudentId" parameterType="int" resultMap="studentSelfcardMap">
select * from t_student_selfcard where student_id = #{studentId}
</select>
</mapper>
到这里估计你已经发现,实体类之间它们除了各自的属性不一样之外,其关联关系配置的方式都是一样的。都有一个额外的要关联对象的id属性,那么它有什么用呢?
看图,很明显
StudentMapper.xml

StudentSelfcardMapper.xml

没错它们是专门为了找到对应关联对象的具体值而存在的,通过这个额外属性mybatis查到了关联的值,然后再将它封装成对象,放到主对象中。这里怎么查由我们自己定义,最后的功能hibernate一样,不过hibernate是不用自己定义查询方法和他们的具体关联,这点比较方便。
association 通过select值来找到对应Mapper的select。
我们再来看看Mapper接口文件
public interface StudentMapper {
public Student getStudent(int id);
/**
* 关联专用
* @param selfcardId
* @return
*/
public Student findStudentByStudentSelfcardId(int selfcardId);
}
public interface StudentSelfcardMapper {
public StudentSelfcard getStudentSelfcard(int id);
/**
* 关联专用
* @param studentId
* @return
*/
public StudentSelfcard findStudentSelfcardByStudentId(int studentId);
}
最后我们看测试代码及测试效果
import org.apache.ibatis.session.SqlSession;
import com.learn.chapter4.mapper.StudentMapper;
import com.learn.chapter4.mapper.StudentSelfcardMapper;
import com.learn.chapter4.po.Student;
import com.learn.chapter4.po.StudentSelfcard;
import com.learn.chapter4.util.SqlSessionFactoryUtil;
/**
* @Description: mybatis一对一关联测试
* @author zhougm
* @date 2017年8月5日,下午10:57:06
*
*/
public class AssociationTest {
public static void main(String[] args) {
SqlSession sqlSession = SqlSessionFactoryUtil.openSqlSession();
// 学生类关联学生证类
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.getStudent(214840101);
System.out.println(student.getStudentSelfcard().getStudentId());
// 学生证类关联学生类
StudentSelfcardMapper studentSelfcardMapper = sqlSession.getMapper(StudentSelfcardMapper.class);
StudentSelfcard studentSelfcard = studentSelfcardMapper.getStudentSelfcard(1);
System.out.println(studentSelfcard.getStudent().getStudentSelfcardId());
}
}
运行结果

数据库信息
t_student
t_student_selfcard

ok! mybatis级联,一对一就这么简单