如存在问题 或有更好建议 请联系 作者QQ:2940500
本文使用商城系统订单模块讲解 需要注意的地方使用红字指出
=========================正-文-分-割-线============================
2019-03-04 补充:
在一对多的情况下 返回的数据是带有重复的 但是封装的时候不会有重复数据
比如 一个订单 拥有多个子订单 我们根据订单表去left join 订单子表时候查询 返回的数据条数是根据子表的条数
如果业务需求是需要不进行后端分页 那么直接查询后根据下边的文章说的那么样封装即可
但是如果需求 需要后端分页 比如只取前10 条数据 (limit 10 ) 的时候
就会出现问题:因为显示的条数是根据子订单的条数 来显示的 如果主订单 里边包含10个子订单 那么我们封装完成后返回给页面的可能就只有一个主订单对象
解决方式 对订单子表使用group by进行分组即可 封装还是正常封装 不受影响
第一点:区别
Association和Collection使用时机区别:
Association 在一对一,多对一时使用
Collection 在一对多,多对多时使用
在association标签中 javaType属性指向的是实体类的属性
在collection标签中 javaType属性指向的是集合的类型 ofType指向的是集合的泛型类型
第二点:表关系
食用本文前把第二点详细看一下 效果更佳
共使用到了 6 个表:
1:订单表 2:用户表 3:地址表 4:订单详情表 5:商品表 6:商品类型表
表之间关系:
订单表外键用户表(一对一),订单表外键地址表(一对一),订单表通过订单编号外联订单详情表(一对多)
订单详情表外键商品表(一对一)
商品表外键商品类型表(一对一)
其他几个表没什么注意的地方就不截图了 如果真的需要评论区回复 我再补上,其实就是很普通的存数据的表 连就完事了!
第三点:数据接收
现在表关系知道了那怎么取数据呢?用什么实体类接收呢? 好像正常的订单实体类都是Id 并不能正常接收吧.
数据接收有两种方式:
1. 用Map接收,返回的K值 就是数据库的字段名 或者 AS 后的名字, V值就是数据库取出的值
2. 创建Vo对象 具体请看截图 (我是使用Java的三大特性之一:继承) 使用Vo类去继承原实体类 就可以获得到原实体类的所有属性直接再在Vo实体类中加入需要的对象属性即可,个人经验这样使用 如果发现这样存在问题请联系我 谢谢!!
至于没有Get Set 是因为对项目集成了Lombok 具体使用方式有时间的话会写一篇Lombok的文章
两种方式的区别:
1. HashMap接收简单,不需要创建实体类 注意使用HashMap接收时 由于HashMap的特性 会造成对象的持续引用 JVM的垃圾回收机制 不能及时回收,在一定时机会导致JVM空间被占满 JVM调优可以解决但是也是暂时的 具体请百度了解JVM垃圾回收机制原理,和Map集合特性 和解决方式
2. Vo需要封装Vo对象 在resultMap 时需要去封装resuMap 写的会很多(本文讲的Association和Collection就是要封装时用到的)但是 更符合 Java面向对象的思想 也不会造成对象的持续引用
两种方式有好有坏 看个人选择 我这里使用的返回Vo
第三步:编写sql
用的LEFT JOIN 左连接查询 (像订单表和Muser表可以用INNER JOIN内连接 来查询这些细节就不多说 个人看情况使用不同连接查询) 为了方便截图就 使用了 * 来代替要取得字段,开发过程中应尽量避免使用* 来代替所查询的字段
看着比较乱的话可以看一下把表名AS后的 sql:
Mapper完整sql :
<sql id="OrderVo">
mall_order.id AS oid,
mall_order.order_no AS oorder_no,
mall_order.user_id AS ouser_id,
mall_order.shipping_id,
mall_order.payment,
mall_order.payment_type,
mall_order.postage,
mall_order.`status` AS ostatus,
mall_order.payment_time,
mall_order.send_time,
mall_order.end_time,
mall_order.close_time,
mall_order.create_time AS ocreate_time,
mall_order.update_time AS oupdate_time,
mall_muser.id AS mid,
mall_muser.username,
/* `password`, 安全问题 密码字段不取*/
mall_muser.nickname,
mall_muser.head_img,
mall_muser.phone,
mall_muser.`level`,
mall_muser.member_id,
mall_muser.qr_code,
mall_muser.scroe,
mall_muser.balance,
mall_muser.birthday,
mall_muser.sex,
mall_muser.wechat_id,
mall_muser.create_time AS mcreate_time,
mall_muser.update_time AS mupdate_time,
mall_muser.state,
mall_shipping.id AS sid,
mall_shipping.user_id AS suser_id,
mall_shipping.receiver_name,
mall_shipping.receiver_phone,
mall_shipping.receiver_mobile,
mall_shipping.receiver_province,
mall_shipping.receiver_city,
mall_shipping.receiver_district,
mall_shipping.receiver_address,
mall_shipping.receiver_zip,
mall_shipping.create_time AS screate_time,
mall_shipping.update_time AS supdate_time,
mall_order_item.id AS oiid,
mall_order_item.user_id AS oiuser_id,
mall_order_item.order_no AS oiorder_no,
mall_order_item.product_id,
mall_order_item.product_name,
mall_order_item.product_image,
mall_order_item.current_unit_price,
mall_order_item.quantity,
mall_order_item.total_price,
mall_order_item.create_time AS oicreate_time,
mall_order_item.update_time AS oiupdate_time,
mall_product.id AS pid,
mall_product.category_id,
mall_product.`name` AS pname,
mall_product.subtitle,
mall_product.main_image,
mall_product.sub_images,
mall_product.detail,
mall_product.price,
mall_product.discount_price,
mall_product.is_discount,
mall_product.stock,
mall_product.buy_num,
mall_product.`status` AS pstatus,
mall_product.create_time AS pcreate_time,
mall_product.update_time AS pupdate_time,
mall_product.integral_multiples,
mall_category.id AS cid,
mall_category.parent_id,
mall_category.`name` AS cname,
mall_category.`status` AS cstatus,
mall_category.sort_order,
mall_category.create_time AS ccreate_time,
mall_category.update_time AS cupdate_time
</sql>
<select id="selectOrderVoList" resultMap="OrderVoResult">
SELECT
<include refid="OrderVo"></include>
FROM
mall_order
LEFT JOIN mall_muser ON mall_order.user_id = mall_muser.id
LEFT JOIN mall_shipping ON mall_order.shipping_id = mall_shipping.id
LEFT JOIN mall_order_item ON mall_order.order_no = mall_order_item.order_no
LEFT JOIN mall_product ON mall_order_item.product_id = mall_product.id
LEFT JOIN mall_category ON mall_product.category_id = mall_category.id
</select>
第四步:封装resultMap
项目里用到的封装的层数比较多 看关键的地方就行
需要注意的地方:
在association 中javaType指向的是实体类的属性
在collection 中javaType 指向的是集合的类型 ofType指向的是集合的泛型类型
<resultMap type="com.xxx.project.platform.order.domain.vo.OrderVo" id="OrderVoResult">
<result property="id" column="oid"/>
<result property="orderNo" column="oorder_no"/>
<result property="userId" column="ouser_id"/>
<result property="shippingId" column="shipping_id"/>
<result property="payment" column="payment"/>
<result property="paymentType" column="payment_type"/>
<result property="postage" column="postage"/>
<result property="status" column="ostatus"/>
<result property="paymentTime" column="payment_time"/>
<result property="sendTime" column="send_time"/>
<result property="endTime" column="end_time"/>
<result property="closeTime" column="close_time"/>
<result property="createTime" column="ocreate_time"/>
<result property="updateTime" column="oupdate_time"/>
<association property="muser" javaType="com.xxx.project.platform.muser.domain.Muser">
<result property="id" column="mid"/>
<result property="username" column="username"/>
<result property="nickname" column="nickname"/>
<result property="headImg" column="head_img"/>
<result property="phone" column="phone"/>
<result property="level" column="level"/>
<result property="memberId" column="member_id"/>
<result property="qrCode" column="qr_code"/>
<result property="scroe" column="scroe"/>
<result property="balance" column="balance"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="wechatId" column="wechat_id"/>
<result property="createTime" column="mcreate_time"/>
<result property="updateTime" column="mupdate_time"/>
</association>
<!-- 这里的javaType 是实体类的类型-->
<association property="shipping" javaType="com.xxx.project.platform.shipping.domain.Shipping">
<result property="id" column="sid"/>
<result property="userId" column="suser_id"/>
<result property="receiverName" column="receiver_name"/>
<result property="receiverPhone" column="receiver_phone"/>
<result property="receiverMobile" column="receiver_mobile"/>
<result property="receiverProvince" column="receiver_province"/>
<result property="receiverCity" column="receiver_city"/>
<result property="receiverDistrict" column="receiver_district"/>
<result property="receiverAddress" column="receiver_address"/>
<result property="receiverZip" column="receiver_zip"/>
<result property="createTime" column="screate_time"/>
<result property="updateTime" column="supdate_time"/>
</association>
<!-- 简单理解:在collection中ofType 指定的是泛型类型 javaType指定的是 集合类型(不强制指定)-->
<collection property="orderItemVoList" javaType="java.util.ArrayList"
ofType="com.xxx.project.platform.orderItem.domain.vo.OrderItemVo">
<result property="id" column="oiid"/>
<result property="userId" column="oiuser_id"/>
<result property="orderNo" column="oiorder_no"/>
<result property="productId" column="product_id"/>
<result property="productName" column="product_name"/>
<result property="productImage" column="product_image"/>
<result property="currentUnitPrice" column="current_unit_price"/>
<result property="quantity" column="quantity"/>
<result property="totalPrice" column="total_price"/>
<result property="createTime" column="oicreate_time"/>
<result property="updateTime" column="oiupdate_time"/>
<association property="productVo" javaType="com.xxx.project.platform.product.domain.vo.ProductVo">
<result property="id" column="pid"/>
<result property="categoryId" column="category_id"/>
<result property="name" column="pname"/>
<result property="subtitle" column="subtitle"/>
<result property="mainImage" column="main_image"/>
<result property="subImages" column="sub_images"/>
<result property="detail" column="detail"/>
<result property="price" column="price"/>
<result property="discountPrice" column="discount_price"/>
<result property="isDiscount" column="is_discount"/>
<result property="stock" column="stock"/>
<result property="buyNum" column="buy_num"/>
<result property="status" column="pstatus"/>
<result property="createTime" column="pcreate_time"/>
<result property="updateTime" column="pupdate_time"/>
<association property="category" javaType="com.xxx.project.platform.category.domain.Category">
<result property="id" column="cid"/>
<result property="parentId" column="parent_id"/>
<result property="name" column="cname"/>
<result property="status" column="cstatus"/>
<result property="sortOrder" column="sort_order"/>
<result property="createTime" column="ccreate_time"/>
<result property="updateTime" column="cupdate_time"/>
</association>
</association>
</collection>
</resultMap>
使用Debug 查看取出的数据 可以看到返回的OrderVo已经被封装完成 (时间比较紧 文章后半部分长话短说)