7.MyBatis 关联查询(一对一)

1 关联查询映射

    1.1 分析数据模型

        思路 : 

            1. 每张表记录的数据内容

            2. 每张表重要的字段(主键,外键,非空字段)

            3. 表与表之间的关系(外键关系)

            4. 表与表之间的业务关系(建立在某个业务意义基础上去分析




            如图:wKioL1WGuAWjZzqeAAEQn8WugTc060.jpg




    1.2 一对一查询

         有三种实现方法:

                resultType

                resultMap中的association嵌套查询

                resultMap中的嵌套结果

        需求:

            进行订单查询,包括用户的姓名和地址信息

        SQL语句:

           SELECT

                orders.id,orders.user_id,orders.number,orders.createtime,orders.note,user.username,user.address

           FROM

                orders, user

           WHERE

                orders.user_id = user.id;

        方法一:resultType

                复杂查询时,单表对应的domain类已不能满足输出结果集的映射。

                所以要根据需求建立一个扩展类来作为resultType的类型。

        创建domain类(OrdersExt.java): 

package cn.mybatis.mapper.domain;
/**
 * 使用此类来映射订单和用户的查询结果,此类继承订单,所以是扩展的
 * @author 刘泽栋
 * @date 2015年6月21日 下午10:08:57
 */
public class OrdersExt extends Orders {
    /**
     * 添加用户的属性
     */
    private String username;
    private String sex;
    private String address;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    } 
}




























        编写mapper接口(OrdersMapper.java)

public interface OrdersMapper {
    // 进行订单查询,包括用户的姓名和地址信息
    public List<OrdersExt> findOrders();
}


        编写映射文件(OrdersMapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.mybatis.mapper.mapper.OrdersMapper">
    <!-- 定义查询订单的SQL片段 -->
    <sql id="select_orders">
        orders.id,
        orders.user_id,
        orders.number,
        orders.createtime,
        orders.note
    </sql>
    <!-- 定义查询用户的SQL片段 -->
    <sql id="select_user">
        user.username,
        user.address
    </sql>

    <!-- 查询订单信息,包括用户的姓名和地址 -->
    <select id="findOrders" resultType="ordersExt">
        SELECT
            <include refid="select_orders"/>,
            <include refid="select_user"/>
        FROM orders, user
        WHERE orders.user_id = user.id
    </select>
</mapper>

        

      加载配置文件(sqlMapConfig.xml)

<!-- 批量加载mapper文件,需要mapper接口文件和mapper映射文件名称相同且在同一个包下 -->
    <mappers>
        <package name="cn.mybatis.mapper.mapper"/>

    </mappers>


        编写测试代码(OrdersMapperTest.java)

package cn.mybatis.mapper.mapper;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.mybatis.mapper.domain.OrdersExt;
/**
 * 测试mybatis的关联映射
 * @author 刘泽栋
 * @date 2015年6月21日 下午10:57:23
 */
public class OrdersMapperTest {
    
    private SqlSessionFactory sqlSessionFactory;
    
    @Before
    public void setUp() throws Exception {
        String resource = "sqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    /**
     * 测试,进行订单查询,包括用户的姓名和地址信息
     */
    @Test
    public void testFindOrders() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        
        // 测试
        List<OrdersExt> list = ordersMapper.findOrders();
        System.out.println(list);
        
        sqlSession.close();
    }
}


        


        方法二:resultMap的association嵌套查询

            修改SQL:

                SELECT orders.id,orders.user_id,orders.number,orders.createtime,orders.note FROM orders;

            修改domain类(OrdersExt.java)

package cn.mybatis.mapper.domain;
/**
 * 使用此类来映射订单和用户的查询结果,此类继承订单,所以是扩展的
 * @author 刘泽栋
 * @date 2015年6月21日 下午10:08:57
 */
public class OrdersExt extends Orders {
    /**
     * 添加用户的属性
     */
    private String username;
    private String sex;
    private String address;
    
    // 用户信息
    private User user;
    
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "OrdersExt [username=" + username + ", sex=" + sex
                + ", address=" + address + "]";
    }
}



            编写mapper接口(OrdersMapper.java)

// 进行订单查询,包括用户的姓名和地址信息(resultMap的嵌套查询)
public List<OrdersExt> findOrdersResultMapOfSelect();

            编写映射文件(OrdersMapper.xml)

<!-- 定义orderUserSelectResultMap 嵌套查询 -->
    <resultMap type="ordersExt" id="ordersUserSelectResultMap">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        <!-- 映射一对一关联关系的用户对象(嵌套查询) -->
        <!-- property:指定关联对象要映射到哪个属性上
            javaType:指定关联对象所映射属性的java类型
            column:如果使用嵌套查询,则通过column指定子查询的查询条件所对应的结果列
            select:指定嵌套查询的子查询statementId
        -->
        <association property="user" javaType="cn.mybatis.mapper.domain.User" column="user_id" select="cn.mybatis.mapper.mapper.UserMapper.findUserById"></association>
    </resultMap>
    
    <!-- 进行订单查询,包括用户的姓名和地址信息(resultMap的嵌套查询) -->
    <select id="findOrdersResultMapOfSelect" resultMap="ordersUserSelectResultMap">
        SELECT
            <include refid="select_orders"/>
        FROM orders
    </select>

             加载配置文件(sqlMapConfig.xml)

<!-- 批量加载mapper文件,需要mapper接口文件和mapper映射文件名称相同且在同一个包下 -->
    <mappers>
        <package name="cn.mybatis.mapper.mapper"/>

    </mappers>


            编写测试代码(OrdersMapperTest.java)

/**
     * 进行订单查询,包括用户的姓名和地址信息(resultMap的嵌套查询)
     */
    @Test
    public void testFindOrdersResultMapOfSelect() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        
        // 测试
        List<OrdersExt> list = ordersMapper.findOrdersResultMapOfSelect();
        System.out.println(list);
        
        sqlSession.close();
    }

        




        方法三:resultMap的association嵌套结果

            SQL语句:

                     SELECT

                        orders.id,orders.user_id,orders.number,orders.createtime,orders.note,user.username,user.address

                     FROM

                        orders, user

                    WHERE

                        orders.user_id = user.id;

                 编写mapper接口(OrdersMapper.java)

    // 进行订单信息查询,包括用户的名称和地址信息(resultMap之嵌套结果)
    public List<OrdersExt> findOrdersResultMap();

                编写映射文件(OrdersMapper.xml)

<!-- 定义orderUserResultMap -->
    <resultMap type="ordersExt" id="ordersUserResultMap">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        <!-- 映射一对一关联关系的用户对象,采用嵌套结果(内部映射) -->
        <!--
            property:指定关联对象要映射到哪个属性上
            javaType:指定关联对象所映射属性的java类型
          -->
        <!-- id标签:指定关联对象结果集的唯一标识,很重要,不写不会报错,但是会影响性能 -->
        <association property="user" javaType="cn.mybatis.mapper.domain.User">
            <id column="user_id" property="id"/>
            <result column="username" property="username" />
            <result column="address" property="address" />
        </association>
    </resultMap>
    
    <!-- 进行订单信息查询,包括用户的名称和地址信息 (ResultMap之嵌套结果) -->
    <select id="findOrdersResultMap" resultMap="ordersUserResultMap">
        SELECT
            <include refid="select_orders"/>,
            <include refid="select_user"/>
        FROM orders, user
        WHERE orders.user_id = user.id
    </select>

                 加载配置文件(sqlMapConfig.xml)

<!-- 批量加载mapper文件,需要mapper接口文件和mapper映射文件名称相同且在同一个包下 -->
    <mappers>
        <package name="cn.mybatis.mapper.mapper"/>

    </mappers>


                编写测试代码(OrdersMapperTest.java)

/**
     * 进行订单信息查询,包括用户的名称和地址信息(resultMap之嵌套结果)
     */
    @Test
    public void testFindOrdersResultMap() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        
        // 测试
        List<OrdersExt> list = ordersMapper.findOrdersResultMap();
        System.out.println(list);
        
        sqlSession.close();
    }

       


你可能感兴趣的:(mybatis,关联查询,一对一)