美文网首页
MyBatis系列之高级结果映射之一对一查询

MyBatis系列之高级结果映射之一对一查询

作者: 今有所思 | 来源:发表于2016-10-30 16:39 被阅读221次

    1. 一对一关系

    首先,我们拥有两张表,分别为Student和Address,每个学生都拥有一个地址。

    Student表信息如下:

    STUD_ID NAME E-MAil PHONE ADDR_ID

    Address表信息如下:

    ADDR_ID STREET CITY STATE ZIP COUNTRY
    public class Address {  
        private Integer addrId;  
        private String street;  
        private String city;  
        private String state;  
        private String zip;  
        private String country;  
        // setters & getters  
    }  
    public class Student {  
        private Integer studId;  
        private String name;  
        private String email;  
        private PhoneNumber phone;  
        private Address address;  
        //setters & getters  
    }  
    
    <resultMap type="Student" id="StudentWithAddressResult">  
        <id property="studId" column="stud_id"/>  
        <result property="name" column="name"/>  
        <result property="email" column="email"/>  
        <result property="phone" column="phone"/>  
        <result property="address.addrId" column="addr_id"/>  
        <result property="address.street" column="street"/>  
        <result property="address.city" column="city"/>  
        <result property="address.state" column="state"/>  
        <result property="address.zip" column="zip"/>  
        <result property="address.country" column="country"/>  
    </resultMap>  
    
    <select id="selectStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">  
        SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE,  
        ZIP, COUNTRY  
        FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON  
        S.ADDR_ID=A.ADDR_ID  
        WHERE STUD_ID=#{studId}  
    </select>  
    

    我们可以在<resultMap>的节点中,嵌套放入Address的信息。在<resultMap>中,学生的地址参数值是通过address.XX来获取的。像这样,我们可以将嵌套对象的属性引用到任何地方。我们可以使用如下的方法来调用嵌套对象:

    public interface StudentMapper {  
        Student selectStudentWithAddress(int studId);  
    } 
    
    int studId = 1;  
    StudentMapper studentMapper =  sqlSession.getMapper(StudentMapper.class);  
    Student student = studentMapper.selectStudentWithAddress(studId);  
    System.out.println("Student :"+student);  
    System.out.println("Address :"+student.getAddress());  
    

    上面展示了一种方法关于一对一的映射。可是问题来了,如果我们调用的Address对象中也包含了其它的对象,也就是说Address对象与其它对象也存在关系的话,那我们不就要做同样的嵌套工作。
    Maybatis提供了更好的方法,那就是应用Nested ResultMap和Nested Select的声明。下面笔者将会介绍。

    2. 使用用Nested ResultMap

    我们可以获取Student的信息连带着Adress信息,我们可以运用到NestedResultMap,使用方法如下的例子

    <resultMap type="Address" id="AddressResult">  
        <id property="addrId" column="addr_id"/>  
        <result property="street" column="street"/>  
        <result property="city" column="city"/>  
        <result property="state" column="state"/>  
        <result property="zip" column="zip"/>  
        <result property="country" column="country"/>  
    </resultMap>  
    <resultMap type="Student" id="StudentWithAddressResult">  
        <id property="studId" column="stud_id"/>  
        <result property="name" column="name"/>  
        <result property="email" column="email"/>  
        <association property="address" resultMap="AddressResult"/>  
    </resultMap>  
    <select id="findStudentWithAddress" parameterType="int" 
    resultMap="StudentWithAddressResult"> SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE,  
    ZIP, COUNTRY  
    FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON  
    S.ADDR_ID=A.ADDR_ID  
    WHERE STUD_ID=#{studId}  
    </select>
    

    上面的例子中,<association>元素可能被使用加载一个对象的关联。在例子中,<association>>元素中还涉及到<resultMap>的节点,这个使用与前面的是一样的。我们还可使用如下的方法来使用<association>

    <resultMap type="Student" id="StudentWithAddressResult">  
        <id property="studId" column="stud_id"/>  
        <result property="name" column="name"/>  
        <result property="email" column="email"/>  
        <association property="address" javaType="Address">  
            <id property="addrId" column="addr_id"/>  
            <result property="street" column="street"/>  
            <result property="city" column="city"/>  
            <result property="state" column="state"/>  
            <result property="zip" column="zip"/>  
            <result property="country" column="country"/>  
        </association>  
    </resultMap>  
    

    3. 使用 Nested Select

    我们可以使用嵌套的Select语句来获取Student信息上连带着Adress的信息。

    <resultMap type="Address" id="AddressResult">  
        <id property="addrId" column="addr_id"/>  
        <result property="street" column="street"/>  
        <result property="city" column="city"/>  
        <result property="state" column="state"/>  
        <result property="zip" column="zip"/>  
        <result property="country" column="country"/>  
    </resultMap>  
    
    <select id="findAddressById" parameterType="int"  
    resultMap="AddressResult">  
    SELECT * FROM ADDRESSES WHERE ADDR_ID=#{id}  
    </select>  
    
    <resultMap type="Student" id="StudentWithAddressResult">  
        <id property="studId" column="stud_id"/>  
        <result property="name" column="name"/>  
        <result property="email" column="email"/>  
        <association property="address" column="addr_id" select="findAddressById"/>  
    </resultMap>  
    
    <select id="findStudentWithAddress" parameterType="int"  
    resultMap="StudentWithAddressResult">  
    SELECT * FROM STUDENTS WHERE STUD_ID=#{Id}  
    </select>  
    

    在这个方法中,这个<association>元素的select有名称放到了<select>的id中。所以执行上面的语句将会执行两条SQL语句,一个是findStudentById,另一个是findAddressById,而且后者主要就是加载Addresss的信息。

    我们可以用下面的方法来执行findStudentWithAddress.

    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);  
    Student student = mapper.selectStudentWithAddress(studId);  
    System.out.println(student);  
    System.out.println(student.getAddress());  
    

    相关文章

      网友评论

          本文标题:MyBatis系列之高级结果映射之一对一查询

          本文链接:https://www.haomeiwen.com/subject/kwluuttx.html