.Net转Java自学之路—Mybatis框架篇四(高级映射、延迟加载)

高级映射:

   一对一查询:对应表t_Orders、t_User

select t_orders.*,t_user.username,t_user.address
from t_orders,t_user
where t_orders.user_id=t_user.id
实例SQL语句

    resultType实现方式:

      创建一个po类来扩展不属于表t_orders表的字段。

public class OrdersCustom extends Orders{
    private String username;
    private String address;
    //get()\set()Code...
}

      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.ccir.mybatis.mapper.OrdersMapper">
    <select id="findOrdersUser" resultType="cn.ccir.mybatis.entity.OrdersCustom">
        select t_orders.*,t_user.username,t_user.address 
        from t_orders,t_user
        where t_orders.user_id=t_user.id
    </select>
</mapper>

      mapper接口:

public List<OrdersCustom> findOrdersUser() throws Exception;

    resultMap实现方式:

      使用resultMap将查询结果中的信息映射到Orders对象中。在Orders实体类中添加User属性,将查询出来的用户信息映射到Orders对象的user属性中。

private User user;
//get/set方法Code...
<!-- 定义resultMap -->
<resultMap type="cn.ccir.mybatis.entity.Orders" id="OrdersUserResultMap">
    <!-- 配置映射的Orders信息,在主表Orders中配置查询列的唯一标识id标签
        若有多个列组成唯一标识,则配置多个id -->
    <id column="id" property="id"/>
    <result column="user_id" property="userid"/>
    <result column="note" property="note"/>
    <!-- .....Orders中的字段和属性...... -->
    
    <!-- 配置映射的User信息
        association:用于樱色和关联查询单个对象的信息
        property:要将关联查询的用户信息映射到Orders中那个属性 -->
    <association property="user" javaType="cn.ccir.mybatis.entity.User">
        <!-- id:关联用户的唯一标识
            column:指定唯一标识用户信息的列
            property:映射到user的那个属性 -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="address" property="address"/>
    </association>
</resultMap>
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
    select t_orders.*,t_user.username,t_user.address 
    from t_orders,t_user
    where t_orders.user_id=t_user.id
</select>
mapper.xml
public List<Orders> findOrdersUserResultMap() throws Exception;
mapper接口

    resultType和resultMap实现一对一查询时,使用resultType实现较为简单。
    若pojo中没有查询出来的列名,需要增加列名对应的属性,即可完成映射。若没有查询结果的特殊要求建议使用resultType。
    而resultMap需要单独定义resultMap,若有对查询结果有特殊的要求,使用resultMap可以完成,将关联查询映射pojo的属性中。
    resultMap可以实现延迟加载。
    resultType无法实现延迟加载。

  一对多查询:

select t_orders.*
    ,t_user.username,t_user.address 
    ,t_ordersdetail.item_num,t_ordersdetail.item_name
from t_orders,t_user,t_ordersdetail
where t_orders.user_id=t_user.id 
    and t_orders.id=t_ordersdetail.order_id
实例SQL语句:t_orders、t_ordersdetails。实现内容要求t_orders中的数据不能重复。

    在Orders实体类中添加List的OrderDetail属性:

private List<OrderDetail> orderDetails;
//get/set方法Code...

    resultMap实现方式:

<!-- 定义resultMap时,使用extends继承,不用再配置orders信息和user信息的映射 -->
<resultMap type="cn.ccir.mybatis.entity.Orders" id="OrdersAndOrdersDetail" extends="OrdersUserResultMap">
    <!-- 配置orders -->
    <!-- <id column="id" property="id"/>
    <result column="user_id" property="userid"/>
    <result column="note" property="note"/> -->
    <!-- 配置user -->
    <!-- <association property="user" javaType="cn.ccir.mybatis.entity.User">
        <id column="user_id" javaType="id"/>
        <result column="username" property="username"/>
        <result column="address" property="address"/>
    </association> -->
    <!-- 配置ordersdetail
        一条orders对应多条ordersdetail,使用collection进行映射
        collection:对关联查询到多条记录映射到集合对象中
        property;将关联查询到多条记录映射到Orders的ordersDetials属性
        ofType:指定映射到集合属性中pojo的类型 -->
    <collection property="ordersDetails" ofType="cn.ccir.mybatis.entity.OrderDetail">
        <!-- id:t_ordersdetail的唯一标识
            property:要将t_ordersdetail的唯一标识映射到OrdersDetail的id属性 -->
        <id column="detail_id" property="id"/>
        <result column="item_num" property="item_num"/>
        <result column="item_name" property="item_name"/>
    </collection>
</resultMap>
<select id="findOrdersAndOrdersDetail" resultMap="OrdersAndOrdersDetail">
    select t_orders.*
        ,t_user.username,t_user.address 
        ,t_ordersdetail.id detail_id,t_ordersdetail.item_num,t_ordersdetail.item_name
    from t_orders,t_user,t_ordersdetail
    where t_orders.user_id=t_user.id 
        and t_orders.id=t_ordersdetail.order_id
</select>
mapper.xml配置文件
public List<Orders> findOrdersAndOrdersDetail() throws Exception;
mapper接口

    Mybatis使用collection对关联查询的多条记录映射到一个List集合中。

  多对多查询:

select t_orders.*
    ,t_user.username,t_user.address 
    ,t_ordersdetail.id detail_id,t_ordersdetail.item_num
    ,t_ordersdetail.item_name
    ,t_ordersdetail.goods_id
    ,t_goods.goods_name,t_goods.goods_price
from t_orders,t_user,t_ordersdetail,t_goods
where t_orders.user_id=t_user.id 
    and t_orders.id=t_ordersdetail.order_id
    and t_ordersdetail.goods_id=t_goods.id
实例SQL:t_user、t_orders、t_orders、t_ordersdetail、t_goods
private List<Orders> orders;
//get/set方法Code...
在User实体类中定义Orders
private List<OrdersDetail> orderDetail;
//get/set方法Code...
在Orders中定义OrdersDetail
private Goods goods;
//get/set方法Code...
在OrdersDetail中定义Goods
<resultMap type="cn.ccir.mybatis.entity.User" id="UserAndGoods">
    <!-- 配置User信息 -->
    <id column="user_id" property="id"/>
    <result column="username" property="username"/>
    <result column="address" property="address"/>
    <!-- 配置Orders信息:一条user信息对应多条orders信息 -->
    <collection property="orders" ofType="cn.ccir.mybatis.entity.Orders">
        <id column="id" property="id"/>
        <result column="note" property="note"/>
    </collection>
    <!-- 配置OrdersDetails信息:一个Orders对应多条OrdersDetail -->
    <collection property="ordersDetails" ofType="cn.ccir.mybatis.entity.OrderDetail">
        <id column="detail_id" property="id"/>
        <result column="item_num" property="item_num"/>
        <result column="item_name" property="item_name"/>
    </collection>
    <!-- 配置Goods信息 一条OrderDetails信息对应一条Goods信息 -->
    <association property="goods" javaType="cn.ccir.mybatis.entity.Goods">
        <id column="goods_id" property="id"/>
        <result column="goods_name" property="goods_name"/>
        <result column="goods_price" property="goods_price"/>
    </association>
</resultMap>
<select id="findUserAndGoods" resultMap="UserAndGoods">
    select t_orders.*
        ,t_user.username,t_user.address 
        ,t_ordersdetail.id detail_id,t_ordersdetail.item_num
        ,t_ordersdetail.item_name
        ,t_ordersdetail.goods_id
        ,t_goods.goods_name,t_goods.goods_price
    from t_orders,t_user,t_ordersdetail,t_goods
    where t_orders.user_id=t_user.id 
        and t_orders.id=t_ordersdetail.order_id
        and t_ordersdetail.goods_id=t_goods.id
</select>
mapper.xml配置
public List<User> findUserAndGoods() throws Exception;
mapper接口

延迟加载:

   resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

  延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能。因为查询单表比关联查询多张表速度要快。

  使用association实现延迟加载:

    需要使用association中的select指定延迟加载去执行的statement的id值。
    当需要查询t_orders并且关联t_user信息。
    mapper.xml配置:在配置时需要定义俩个mapper的方法对应的statement。先实现对Orders的信息查询。再关联查询User中的信息查询。

<!-- 延迟加载的resultMap -->
<resultMap type="cn.ccir.mybatis.entity.Orders" id="OrdersUserLazyLoad">
    <id column="id" property="id"/>
    <result column="user_id" property="userid"/>
    <result column="note" property="note"/>
    <!-- 实现对User信息进行延迟加载
        select:指定延迟加载需要执行的statement的id(是根据user_id查询User信息statement)。
            要使用UserMapper.xml中findUserById完成根据用户id的查询。
            若findUserById不再本mapper.xml中需要前面加namespace
        column:订单信息中关联用户信息查询的列,是user_id -->
    <association property="user" javaType="cn.ccir.mybatis.entity.User" 
        select="cn.ccir.mybatis.mapper.UserMapper.findUserById" column="user_id">
    </association>
</resultMap>
<select id="findOrdersUserLazyLoad" resultMap="OrdersUserLazyLoad">
    select * from t_Orders
</select>
public List<Orders> findOrdersUserLazyLoad() throws Exception;

  延迟加载配置:

    在Mybatis中默认是未开启延迟加载。需要在SqlMapConfig.xml中setting配置开启延迟加载。

    lazyLoadingEnabel:全局设置懒加载。若设为false,则所有相关联的都会被初始化加载。默认为:false。

    aggressiveLazyLoading:当设置为true时,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。默认为true。

<!-- 开启延迟加载配置 -->
<settings>
    <!-- 打开延迟加载的开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 将积极加载改为消极加载。即按需要加载 -->
    <setting name="aggressveLazyLoading" value="false"/>
</settings>

 

posted @ 2019-03-17 11:58  水痕灬  阅读(205)  评论(0编辑  收藏  举报