mybatis级联,一对一

宽为限 紧用功 工夫到 滞塞通

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级联,一对一就这么简单这里写图片描述

MyBatis支持通过级联查询来实现一对一关系的查询。在进行一对一级联查询时,需要使用MyBatis提供的`association`标签来配置关联关系。 首先,需要在映射文件中定义两个相关的结果映射。一个是主实体对象的映射,另一个是关联实体对象的映射。例如,我们有一个订单(Order)实体和一个用户(User)实体,订单有一个外键指向用户表。 ```xml <!-- 订单实体映射 --> <resultMap id="orderResultMap" type="com.example.Order"> <id property="id" column="order_id" /> <result property="orderNo" column="order_no" /> <association property="user" javaType="com.example.User"> <id property="id" column="user_id" /> <result property="username" column="username" /> <result property="email" column="email" /> </association> </resultMap> <!-- 用户实体映射 --> <resultMap id="userResultMap" type="com.example.User"> <id property="id" column="user_id" /> <result property="username" column="username" /> <result property="email" column="email" /> </resultMap> ``` 然后,在查询订单时,使用`association`标签配置一对一关联查询: ```xml <select id="getOrderById" resultMap="orderResultMap"> SELECT o.id as order_id, o.order_no, u.id as user_id, u.username, u.email FROM orders o INNER JOIN users u ON o.user_id = u.id WHERE o.id = #{orderId} </select> ``` 这样,当执行`getOrderById`查询时,MyBatis会自动进行一对一级联查询,将订单对象的关联用户对象填充进去。 注意:以上示例中的表名、列名等需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值