处理 Mybatis 中一对多、多对一、多对多映射的黑魔法

前言

先看看Mybatis官方介绍

MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

注意,这里是简单的XML! 可是,当我们的数据库表关系错综复杂,表与表之存在一对多、多对一、多对多的关系时,如何通过mybatis表示出他们的关系呢?网上很多文章都在介绍 association、 collection,我先不说association、 collection有多好,先来看看一个具体实例。

下图是订单的数据库表关系

 

这里写图片描述

 

有这样一个需求,我要展示类似于淘宝订单的效果,如下图:


这里写图片描述

 

我们看到上面的订单就会想到,要展示一条订单,需要:订单信息、物流信息、卖家信息、买家信息、商品信息、商品属性信息、商品状态信息…,至少也要5/6张表的数据,其中,订单对买家/卖家是多对一关系、订单对商品时多对多关系…,看看类似的xml:

扫描二维码关注公众号,回复: 3331173 查看本文章
<span style="color:#000000"><code><span style="color:#880000"><!-- 查询用户及购买的商品  type写的是user类的全路径  把数据映射到user中   --></span>
    <span style="color:#006666"><<span style="color:#4f4f4f">resultMap</span> <span style="color:#4f4f4f">type</span>=<span style="color:#009900">"org.mybatis.po.User"</span> <span style="color:#4f4f4f">id</span>=<span style="color:#009900">"UserAndItemsResultMap"</span>></span>
        <span style="color:#880000"><!-- 用户信息 --></span>
        <span style="color:#006666"><<span style="color:#4f4f4f">id</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"user_id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"id"</span> /></span>
        <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"username"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"username"</span> /></span>
        <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"sex"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"sex"</span> /></span>
        <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"address"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"address"</span> /></span>

        <span style="color:#880000"><!-- 订单信息一个用户对应多个订单,使用collection映射--></span>
        <span style="color:#006666"><<span style="color:#4f4f4f">collection</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"ordersList"</span> <span style="color:#4f4f4f">ofType</span>=<span style="color:#009900">"org.mybatis.po.Orders"</span>></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">id</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"id"</span> /></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"user_id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"userId"</span> /></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"number"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"number"</span> /></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"createtime"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"createtime"</span> /></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"note"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"note"</span> /></span>

            <span style="color:#880000"><!-- 订单明细一个订单包括 多个明细  --></span>
            <span style="color:#006666"><<span style="color:#4f4f4f">collection</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"orderdetailList"</span> <span style="color:#4f4f4f">ofType</span>=<span style="color:#009900">"org.mybatis.po.Orderdetail"</span>></span>
                <span style="color:#006666"><<span style="color:#4f4f4f">id</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"orderdetailid"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"id"</span> /></span>
                <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"orders_id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"ordersId"</span> /></span>
                <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"items_id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"itemsId"</span> /></span>
                <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"items_num"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"itemsNum"</span> /></span>

                <span style="color:#880000"><!-- 商品信息一个订单明细对应一个商品--></span>
                <span style="color:#006666"><<span style="color:#4f4f4f">association</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"items"</span> <span style="color:#4f4f4f">javaType</span>=<span style="color:#009900">"org.mybatis.po.Items"</span>></span>
                    <span style="color:#006666"><<span style="color:#4f4f4f">id</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"items_id"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"id"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">id</span>></span>
                    <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"name"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"name"</span> /></span>
                    <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"price"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"price"</span> /></span>
                    <span style="color:#006666"><<span style="color:#4f4f4f">result</span> <span style="color:#4f4f4f">column</span>=<span style="color:#009900">"detail"</span> <span style="color:#4f4f4f">property</span>=<span style="color:#009900">"detail"</span> /></span>
                <span style="color:#006666"></<span style="color:#4f4f4f">association</span>></span>

            <span style="color:#006666"></<span style="color:#4f4f4f">collection</span>></span>

        <span style="color:#006666"></<span style="color:#4f4f4f">collection</span>></span>
        ...
        <span style="color:#880000"><!--还有卖家、买家、物流...--></span>
        ...</code></span>

仅仅这一个订单,如果用association、 collection来实现,xml何其多、何其复杂!除了xml,还有一堆实体类要写,写着写着很容易乱!这跟Mybatis官网上说的简单xml相悖,我想要的效果是简简单单的像一个实体类就能映射的xml,任何人,无论是初学者还是老程序员都能一眼直观的xml。 
 

抛砖引玉

那么,要怎样将订单的xml简化,我先来一个抛砖引玉,mybatis和hibernate最大的区别是什么?


Mybatis可以更细致的定制化! hibernate 具体更强的移植性和缓存机制。既然说Mybatis可以更细致的定制化,如何定制!通过sql优化、sql定制,既然sql可以根据具体的需求而定,那么我可以利用sql处理数据库表的关系,只需要返回直观的结果给我就行。一言蔽之,就是:把一对多、多对一、多对多关系扔到sql中去处理,xml只需要接收最直接、最简单的数据即可!

<!-- 查询用户及购买的商品 type写的是user类的全路径 把数据映射到user中 --> <resultMap type="org.mybatis.po.User" id="UserAndItemsResultMap"> <!-- 用户信息 --> <id column="user_id" property="id" /> <result column="username" property="username" /> <result column="sex" property="sex" /> <result column="address" property="address" /> <!-- 订单信息一个用户对应多个订单,使用collection映射--> <collection property="ordersList" ofType="org.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="orderdetailList" ofType="org.mybatis.po.Orderdetail"> <id column="orderdetailid" property="id" /> <result column="orders_id" property="ordersId" /> <result column="items_id" property="itemsId" /> <result column="items_num" property="itemsNum" /> <!-- 商品信息一个订单明细对应一个商品--> <association property="items" javaType="org.mybatis.po.Items"> <id column="items_id" property="id"></id> <result column="name" property="name" /> <result column="price" property="price" /> <result column="detail" property="detail" /> </association> </collection> </collection> ... <!--还有卖家、买家、物流...--> ...

好,回到订单,显示一个订单需要哪些信息,需要如下信息:

<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> OrderInfo {

    <span style="color:#880000">//订单id</span>
    <span style="color:#000088">private</span> Integer id; 

    <span style="color:#880000">//订单价格</span>
    <span style="color:#000088">private</span> Integer price;

    <span style="color:#880000">//订单生成时间</span>
    <span style="color:#000088">private</span> Date createdTime;

    <span style="color:#880000">//订单状态</span>
    <span style="color:#000088">private</span> Integer status;

    <span style="color:#880000">//商品数量</span>
    <span style="color:#000088">private</span> Integer util;

    <span style="color:#880000">//买家电话</span>
    <span style="color:#000088">private</span> String phone;

    <span style="color:#880000">//买家名字</span>
    <span style="color:#000088">private</span> String userName;

    <span style="color:#880000">//物流地址</span>
    <span style="color:#000088">private</span> String receiverAddress;

    <span style="color:#880000">//支付方式</span>
    <span style="color:#000088">private</span> String payName;

    <span style="color:#880000">//商品名称</span>
    <span style="color:#000088">private</span> String productName;

    <span style="color:#880000">//商品属性</span>
    <span style="color:#000088">private</span> String standard;

    <span style="color:#880000">//卖家名称</span>
    <span style="color:#000088">private</span> String marketName;

    <span style="color:#880000">//商品缩略图</span>
    <span style="color:#000088">private</span> String productPhoto;

    setter and getter...
</code></span>
  • public class OrderInfo { //订单id private Integer id; //订单价格 private Integer price; //订单生成时间 private Date createdTime; //订单状态 private Integer status; //商品数量 private Integer util; //买家电话 private String phone; //买家名字 private String userName; //物流地址 private String receiverAddress; //支付方式 private String payName; //商品名称 private String productName; //商品属性 private String standard; //卖家名称 private String marketName; //商品缩略图 private String productPhoto; setter and getter...
    xml怎么写? 我不需要association、 collection就可以实现,把数据库关系交给数据库处理,我用最原始的and 表示(这里以mysql为例)
<span style="color:#000000"><code>...
 <select id=<span style="color:#009900">"selectOrderInfoByOrderId"</span> resultType=<span style="color:#009900">"com.vbtime.thor.wrapper.OrderInfo"</span> parameterType=<span style="color:#009900">"java.lang.Integer"</span>>
    select o<span style="color:#009900">.id</span> as id, o<span style="color:#009900">.status</span> as status, o<span style="color:#009900">.price</span> as price,o<span style="color:#009900">.created</span>_time as createdTime, o<span style="color:#009900">.util</span> as util, u<span style="color:#009900">.name</span> as userName, u<span style="color:#009900">.phone</span> as phone, r<span style="color:#009900">.receiver</span>_address as receiverAddress, pay<span style="color:#009900">.name</span> as payName, 
       group_concat(concat(ps<span style="color:#009900">.name</span>,<span style="color:#009900">':'</span>,psv<span style="color:#009900">.value</span>) Separator <span style="color:#009900">';'</span>)  as standard, m<span style="color:#009900">.name</span> as marketName,p<span style="color:#009900">.name</span> as productName,p<span style="color:#009900">.photo</span> as productPhoto 
       from  rorder o, order_standard_value os, product_standard ps, product_standard_values psv, user u, product p, market m, order_market om, order_product op, pay_type pay, receiver r where
        u<span style="color:#009900">.id</span> = o<span style="color:#009900">.user</span>_id <span style="color:#000088">and</span> p<span style="color:#009900">.id</span> = op<span style="color:#009900">.product</span>_id <span style="color:#000088">and</span> o<span style="color:#009900">.id</span> = op<span style="color:#009900">.order</span>_id <span style="color:#000088">and</span> m<span style="color:#009900">.id</span>= om<span style="color:#009900">.market</span>_id <span style="color:#000088">and</span> o<span style="color:#009900">.id</span> = om<span style="color:#009900">.order</span>_id <span style="color:#000088">and</span> o<span style="color:#009900">.id</span> = os<span style="color:#009900">.order</span>_id <span style="color:#000088">and</span> psv<span style="color:#009900">.id</span> = os<span style="color:#009900">.standard</span>_value_id <span style="color:#000088">and</span>
         ps<span style="color:#009900">.id</span>= psv<span style="color:#009900">.product</span>_standard_id <span style="color:#000088">and</span> pay<span style="color:#009900">.id</span> = o<span style="color:#009900">.pay</span>_id <span style="color:#000088">and</span> r<span style="color:#009900">.id</span> = o<span style="color:#009900">.recevier</span>_id <span style="color:#000088">and</span> o<span style="color:#009900">.id</span> = <span style="color:#009900">#{orderId}</span>
 </select>
 ...</code></span>

猜你喜欢

转载自blog.csdn.net/zalan01408980/article/details/82698638