(一)案例背景
  有4张表:用户表(user),商户表(business),订单表(orders),评论表(comment),这四张表的关系如下图所示:
十五、Mybatis之“一对一对一”_xml
  关于上表,需要特别说明的是,因为“订单表(orders)”已经建立了与用户和商户的关系,而我们的“评论表(comment)”又与“订单表(orders)”建立了关系,所以我们的“评论表(comment)”无需再与用户、商户建立关系。通俗点说,我通过“评论表(comment)”中的“订单id”,我就能查询到对应的用户和商户。

  根据上面的分析,我建立了对应的JavaBean:

//用户:
public class User extends BaseBean {
private Long phone;
private String name;
private String password;
private Date createDate;
}
//商户
public class Business extends BaseBean {
private String title;
private String subtitle;
private String imgFileName;
private Integer price;
private Integer distance;
/**
* 已售数量
*/
private Integer number;
/**
* 星级
*/
private Integer star;
/**
* 总评价次数
*/
private Integer commentNum;
/**
* 描述
*/
private String desc;
/**
* 这里对应字典里的代码
*/
private String city;
private String category;

/**
* 多对一
* 上面对应字典里的代码,而我们需要显示的是字典中的name,所以这里加了两个Dictionary对象
*/
private Dictionary cityDictionary;
private Dictionary categoryDictionary;
}
//订单
public class Order extends BaseBean {
/**
* 商户id
*/
private Integer businessId;
/**
* 用户id
*/
private Integer userId;
/**
* 已售数量
*/
private Integer num;
/**
* 评论状态
* 0:未评论
* 2:已评论
*/
private Integer commentState;
/**
* 价格
*/
private Double price;

/**
* 创建时间
*/
private Date createDate;

/**
* 用户(多对1)
*/
private User user;
/**
* 评论(多对1)
*/
private Business business;
}
//评论
public class Comment extends BaseBean {
/**
* 订单id
*/
private Integer orderId;
/**
* 评价内容
*/
private String content;
/**
* 星级
*/
private Integer star;
/**
* 评论创建时间
*/
private Date createTime;
/**
* 用户
*/
private Order order;
/**
* 用户(这里是为了查询评论提供用户手机号入口,本质上是想共用一个查询条件)
*/
private User user;
/**
* 商户(这里是为了查询评论提供商户id入口,本质上是想共用一个查询条件)
*/
private Business business;
}

  在sql配置文件中,建立了映射关系

//OrderMapper.xml
<mapper namespace="com.imooc.dao.OrderDao">
<resultMap id="OrderMap" type="Order">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="business_id" property="businessId"/>
<result column="num" property="num"/>
<result column="comment_state" property="commentState"/>
<result column="price" property="price"/>
<result column="createDate" property="createDate"/>
<association property="user" javaType="User">
<result column="phone" property="phone"/>
</association>
<association property="business" javaType="Business">
<result column="img_file_name" property="imgFileName"/>
<result column="title" property="title"/>
</association>
</resultMap>
</mapper>

//CommentMapper.xml
<mapper namespace="com.imooc.dao.CommentDao">
<resultMap id="CommentMap" type="Comment">
<id column="id" property="id"/>
<result column="order_id" property="orderId"/>
<result column="content" property="content"/>
<result column="star" property="star"/>
<result column="createTime" property="createTime"/>
</resultMap>
</mapper>

(二)问题
  问题:现在需要根据商户id来查询所有对应的评论列表?

(三)解析
  因为我们并没有建立评论表与商户表之间的映射关系,所以我们无法像配置“1对1”映射关系这样在“CommentMapper.xml”中配置商户。
  但是请看上面的“OrderMapper.xml”配置文件,在这里我们是配置了“订单表”和“商户表”、“用户表”1对1关系的(​​​<resultMap id="OrderMap" type="Order">​​),同时我们在“Comment”对象中也是有“Order”成员变量的,我们只要把这个“resultMap”利用起来即可,即配置”CommentMap”与“OrderMap”的“1对1”映射关系。这就是我所说的“1对1对1”(商户:订单:评论),具体配置代码如下:

<resultMap id="CommentMap" type="Comment">
<id column="id" property="id"/>
<result column="order_id" property="orderId"/>
<result column="content" property="content"/>
<result column="star" property="star"/>
<result column="createTime" property="createTime"/>
<!-- 配置Order的resultMap“1对1”关系,实现映射关系的“传递” -->
<association property="order" resultMap="com.imooc.dao.OrderDao.OrderMap"/>
</resultMap>

  使用方式如下:

<!-- 其中“u.phone,b.title”会自动映射到“OrderMap”,再由“OrderMap”映射到“Order”对象的“Business”成员变量中的“title”属性和“User”成员变量中的“phone”属性 -->
<select id="searchByPage" parameterType="Comment" resultMap="CommentMap">
SELECT co.id,co.order_id,co.content,co.star,co.createTime,u.phone,b.title
FROM `comment` co,orders o,`user` u,business b
<where>
AND co.order_id=o.id AND o.user_id=u.id AND o.business_id=b.id
<if test="id != null">AND co.id=#{id}</if>
<if test="orderId != null">AND co.order_id=#{orderId}</if>
<if test="searchKey != null and !"".equals(searchKey.trim())">
AND (
b.title LIKE CONCAT('%',#{searchKey},'%')
OR u.phone=#{searchKey}
)
</if>
<if test="business != null and business.id != null">AND b.id=#{business.id}</if>
</where>
ORDER BY co.createTime ASC
</select>