Mybatis关联查询

Posted javajava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis关联查询相关的知识,希望对你有一定的参考价值。

mybatis实现表与表之间的查询,将查询的结果集进行映射(reslutType/resultMap高级映射)

1.首先分析表与表之间的关系.步骤如下:

1)   按模块去分析表,不要一次全部分析         2)了解每个表存储了什么业务数据        3)了解表中关键字段(主键/外键/索引字段/非空字段)

4)   了解表与表之间数据级别的关系(外键关系)     5)了解表与表之间的业务关系(一对一/一对多/多对多)

 

 

 

(一)  一对一查询 

需求:   查询订单关联查询用户信息

1. resultType实现

1.1创建实体类继承orders

 

public class OrdersCustom extends Orders {
    //应该包括 订单及订单关联信息的属性
    //由于继承订单类只需要添加一些关联属性
    //用户信息
    private String username;
    private String address;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

 

1.2 mapper.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">
<!-- namespace是mapper.java的全路径,底层是在类里selectOne("test.findBy..","张")-->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">

<!-- 查询订单关联查询用户 -->
<select id="findOrdersAndUserByResultType" resultType="cn.itcast.mybatis.po.OrdersCustom">
SELECT
orders.*,
user.username,
user.address
FROM
orders,
USER
WHERE orders.user_id = user.id
</select>


</mapper>

 1.3 mapper.java

public interface OrdersMapperCustom {
    //一对一查询,查询订单关联查询用户
    public List<OrdersCustom> findOrdersAndUserByResultType() throws Exception;
}

2. resultMap实现

2.1实体类添加user对象

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //创建订单的用户
    private User user;

2.2  mapper.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.itcast.mybatis.mapper.OrdersMapperCustom">

    <!-- 查询订单及用户的resultMap
    type:查询结果集映射的java对象类型
     -->
    <resultMap type="orders" id="ordersAndUserByResultMap">
        <!-- 订单信息的映射配置 -->
        <!-- id:唯一标识 列 ,这里是订单信息的唯一标识 -->
        <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"/>
        
        <!-- 用户信息的映射配置 
        association:关联映射单个对象
        property:将关联的用户信息映射到orders的哪个属性中
        javaType:property对应的类型
        -->
        <association property="user" javaType="cn.itcast.mybatis.po.User">
            <!-- id:用户信息的唯一标识 
            result:用户信息列
            property:将关联查询的列映射到user的哪个属性中
             -->
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="address" property="address"/>
        
        </association>
        
    </resultMap>

<!-- 查询订单关联查询用户,使用resultMap -->
    <select id="findOrdersAndUserByResultMap" resultMap="ordersAndUserByResultMap">
        SELECT 
          orders.*,
          user.username,
          user.address 
        FROM
          orders,
          USER 
        WHERE orders.user_id = user.id 
    </select>
</mapper>

2.3  mapper.java

//一对一查询,使用resultMap
    public List<Orders> findOrdersAndUserByResultMap() throws Exception;

如果需要将关联查询的信息映射到pojopojo属性中, 为了获取数据方便,可以使用resultMap

如果使用延迟加载,只能使用resultMap

(二)  一对多查询 

需求:查询订单关联查询明细信息

注意: association是映射到单个对象中,标签使用javaType映射对象类型

         collection是映射到集合对象中,标签使用ofType映射对象类型.

1.1创建实体类继承orders

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //创建订单的用户
    private User user;
    
    //关联的订单明细信息
    private List<Orderdetail> orderdetails;

1.2  mapper.xml   

<!-- 查询订单关联查询明细resultMap
    extends:resultMap可以继承另一个resultMap,如果跨mapper,前边要加namespace
     -->
    <resultMap type="orders" id="ordersAndOrderDetailResultMap" extends="ordersAndUserByResultMap">
        <!-- 映射订单信息和用户信息采用继承 -->
        
        <!-- 订单明细信息
        collection:将关联信息映射到一个List集合对象中
        property:要将关联信息映射到orders主对象中的哪个属性中
        ofType:关联信息映射到一个List中对象类型
        
         -->
        <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
            <!-- id:订单明细的唯一标识 列 -->
            <id column="orderdetail_id" property="id"/>
            <result column="id" property="ordersId"/>
            <result column="items_id" property="itemsId"/>
            <result column="items_num" property="itemsNum"/>
        
        </collection>
<!-- 一对多查询,查询订单关联查询明细 --> 注意:resultMap的值为上面的resultMap的id
    <select id="findOrdersAndOrderDetail" resultMap="ordersAndOrderDetailResultMap">
        SELECT 
          orders.*,
          user.username,
          user.address,
          orderdetail.id orderdetail_id,
          orderdetail.items_id,
          orderdetail.items_num
        FROM
          orders,
          USER ,
          orderdetail
        WHERE orders.user_id = user.id  AND orderdetail.orders_id = orders.id
    </select>

1.3 mapper.java

//一对多查询,查询订单及明细
    public List<Orders> findOrdersAndOrderDetail()throws Exception;

(三)  多对多查询 

需求: 查询用户信息及用户购买的商品信息

1.1  映射需求:  在user中设置一个List<Orders> orders属性,在order对象中设置List<Orderdetail> orderdeils 属性,在Orderdetail中设置Items属性。

最终查询出来的用户列表,用户信息映射到List<User>中.

 1.2 mapper.xml

<!-- 查询用户及用户购买的商品信息 
    最终要将查询结果映射成List<User>
    -->
    <resultMap type="user" id="userAndItemsResultMap">
        <!-- 用户信息 -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="address" property="address"/>
                
        <!-- 订单信息
        一个用户可以创建多个订单
         -->
         <collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders">
             <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" />
                 <!-- 订单明细信息
            一个订单包括多个明细信息
             -->
             <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
                     <id column="orderdetail_id" property="id"/>
                    <result column="id" property="ordersId"/>
                    <result column="items_id" property="itemsId"/>
                    <result column="items_num" property="itemsNum"/>
                            <!-- 商品信息 
                            一个明细对应一个商品
                            -->
                            <association property="items" javaType="cn.itcast.mybatis.po.Items">
                                <id column="items_id" property="id"/>
                                <result column="items_name" property="name"/>
                                <result column="items_pic" property="pic"/>
                            </association>
    
             </collection>
         </collection>
<!-- 多对多查询,查询用户及用户购买的商品信息 --> <select id="findUserAndItems" resultMap="userAndItemsResultMap"> SELECT orders.*, user.username, user.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, items.name items_name, items.pic items_pic FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id = orders.id AND items.id = orderdetail.items_id </select>

 1.3  mapper.java

//多对多查询,查询用户及用户购买订单
    public List<User> findUserAndItems()throws Exception;

(四)  延迟加载

1.1  需求:查询订单关联查询用户信息,对关联查询用户信息延迟加载:也就是只加载订单,点击查询用户是再加载用户信息.(尽量从单表中查询)

1.2 在SqlMapConfig.xml中.

<!-- 通过setting配置mybatis的运行参数 注意,设置运行参数会影响 mybatis的运行,一定要注意! --> <settings> <!-- 延迟加载的总开关 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 设置为false实现按需求加载 --> <setting name="aggressiveLazyLoading" value="false"/> </settings>

1.3   mapper.xml     sql语句:单表查询:select*from orders

<!-- 查询订单延迟加载 用户-->
    <resultMap type="orders" id="ordersLazyLoadingUserResultMap">
         <!-- 订单信息映射 -->
         <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" />

        <!-- 一个订单只能由一个用户,延迟加载用户信息
        select就是延迟加载的sql语句,指定sql所在statement的id  userMapper.xml中sql,namespace.id
        column:关联查询的列,这里就是orders表中外键user_id(SELECT * FROM USER WHERE id=orders.user_id)
         -->
        <association property="user" javaType="cn.itcast.mybatis.po.User" 
            select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
        </association>
        
    </resultMap>
    
    <!-- 查询订单关联查询用户实现延迟加载 -->
    
    <select id="findOrdersLazyLoadingUser" resultMap="ordersLazyLoadingUserResultMap">
        
        <!-- 查询订单的sql -->
        select * from orders
    </select>

1.4 mapper.java

 

//查询订单延迟加载用户信息
    public List<Orders> findOrdersLazyLoadingUser()throws Exception;

 ResultMap提供延迟加载,通过association 可以延迟加载一个对象,collection可以延迟加载多个对象.即集合对象.

 

以上是关于Mybatis关联查询的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis--02

mybatis第二天——大纲待更新

mybatis专题-----代码生成器关联查询缓存

mybatis关联查询,一对一,一对多

mybatis 一对一关联 association 返回空值

MyBatis学习——分步查询与延迟加载