通过项目逐步深入了解Mybatis<三>

相关阅读:

1、通过项目逐步深入了解Mybatis<一>

2、 通过项目逐步深入了解Mybatis<二>

本项目所有代码及文档都托管在 Github地址:https://github.com/zhisheng17/mybatis

Mybatis 高级知识

安排:对订单商品数据模型进行分析

订单商品数据模型

《通过项目逐步深入了解Mybatis<三>》” /></span></p><h3>数据模型分析思路:</h3><p>1、每张表记录的数据内容(分模块对每张表记录的内容进行熟悉,相当于学习系统需求的过程)</p><p>2、每张表重要的的字段设置(非空字段、外键字段)</p><p>3、数据库级别表与表之间的关系(外键关系)</p><p>4、表与表业务之间的关系(要建立在每个业务意义的基础上去分析)</p><h3>数据模型分析模型</h3><ul><li><p>用户表 user:记录购买商品的用户信息</p></li><li><p>订单表 order:记录用户所创建的订单(购买商品的订单)</p></li><li><p>订单明细表 orderdetail:(记录了订单的详细信息即购买商品的信息)</p></li><li><p>商品表 items:记录了商品信息</p></li></ul><p><strong>表与表业务之间的关系</strong>:</p><p>在分析表与表之间的业务关系时需要建立在某个业务意义基础上去分析。</p><p>先分析数据级别之间有关系的表之间的业务关系:</p><p>1、<strong>usre和orders</strong>:</p><p>user —> orders:一个用户可以创建多个订单,一对多</p><p>orders —> user:一个订单只由一个用户创建,一对一</p><p>2、 <strong>orders和orderdetail</strong>:</p><p>orders —> orderdetail:一个订单可以包括 多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系</p><p>orderdetail —> orders:一个订单明细只能包括在一个订单中,一对一</p><p>3、 <strong>orderdetail 和 itesm</strong>:</p><p>orderdetail —> itesms:一个订单明细只对应一个商品信息,一对一</p><p>items —> orderdetail:一个商品可以包括在多个订单明细 ,一对多</p><p>再分析数据库级别没有关系的表之间是否有业务关系:</p><p>4、 <strong>orders 和 items</strong>:</p><p>orders 和 items 之间可以通过 orderdetail 表建立 关系。</p><p><span><img layer-src=

  • Mapper 文件

OrdersMapperCustom.java

public interface OrdersMapperCustom
{
    public OrdersCustom findOrdersUser() throws Exception;
}
  • 测试代码(记得在 SqlConfig.xml中添加载 OrdersMapperCustom.xml 文件)

     @Test
    public void testFindOrdersUser() throws Exception
    {
      SqlSession sqlSession = sqlSessionFactory.openSession();
      //创建OrdersMapperCustom对象,mybatis自动生成代理对象
      OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
      //调用OrdersMapperCustom的方法
       List<OrdersCustom> list = ordersMapperCustom.findOrdersUser();
      System.out.println(list);
      sqlSession.close();
    }
  • 测试结果

《通过项目逐步深入了解Mybatis<三>》” /></span></p><p>​</p><p>​</p><h3>使用 resultMap</h3><ul><li><p>sql 语句(和上面的一致)</p></li><li><p>使用 resultMap 映射思路</p></li></ul><p>使用 resultMap 将查询结果中的订单信息映射到 Orders 对象中,在 orders 类中添加 User 属性,将关联查询出来的用户信息映射到 orders 对象中的 user 属性中。</p><pre><code> //用户信息
 private User user;</code></pre><ul><li><p>映射文件</p></li></ul><p><code>OrdersMapperCustom.xml</code></p><p>先定义 resultMap</p><pre><code><!--定义查询订单关联查询用户信息的resultMap
        将整个查询结果映射到cn.zhisheng.mybatis.po.Orders
    -->
    <resultMap id=

<!--查询订单关联查询用户信息, 使用 resultMap-->
    <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
        SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id
    </select>
  • Mapper 文件

    public List<Orders> findOrdersUserResultMap() throws Exception;
  • 测试代码

    @Test
     public void testFindOrdersUserResultMap() throws Exception
     {
         SqlSession sqlSession = sqlSessionFactory.openSession();
         //创建OrdersMapperCustom对象,mybatis自动生成代理对象
         OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
         //调用OrdersMapperCustom的方法
         List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();
         System.out.println(list);
         sqlSession.close();
     }
  • 测试结果

《通过项目逐步深入了解Mybatis<三>》” /></span></p><h3>使用 resultType 和 resultMap 一对一查询小结</h3><ul><li><p>resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。</p></li><li><p>resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。resultMap可以实现延迟加载,resultType无法实现延迟加载。</p></li></ul><h2>一对多查询</h2><p><strong>需求</strong>:查询订单及订单明细信息</p><p><strong>SQL语句</strong>:</p><p>确定主查询表:订单表</p><p>确定关联查询表:订单明细表</p><p>在一对一查询基础上添加订单明细表关联即可。</p><pre><code>SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id FROM orders, USER,
orderdetail WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id</code></pre><p>分析:</p><p>使用 resultType 将上边的查询结果映射到 pojo 中,订单信息的就是重复。</p><p>要求:</p><blockquote><p>对 orders 映射不能出现重复记录。</p></blockquote><p>在 orders.java 类中添加 List<orderDetail> orderDetails 属性。</p><p>最终会将订单信息映射到 orders 中,订单所对应的订单明细映射到 orders 中的 orderDetails 属性中。</p><p>映射成的 orders 记录数为两条(orders信息不重复)</p><p>每个 orders 中的 orderDetails 属性存储了该订单所对应的订单明细。</p><p><strong>映射文件</strong>:</p><p>首先定义 resultMap</p><pre><code><!--定义查询订单及订单明细信息的resultMap使用extends继承,不用在中配置订单信息和用户信息的映射-->
    <resultMap id=

 <!--查询订单及订单明细信息, 使用 resultMap-->
    <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
        SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id
        FROM orders, USER,orderdetail WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
    </select>

Mapper 文件

public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;

测试文件

@Test
    public void testFindOrdersAndOrderDetailResultMap() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建OrdersMapperCustom对象,mybatis自动生成代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        //调用OrdersMapperCustom的方法
        List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();
        System.out.println(list);
        sqlSession.close();
    }

测试结果

《通过项目逐步深入了解Mybatis<三>》” /></span></p><h3>总结:</h3><p>mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。</p><p>使用resultType实现:将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。</p><h2>多对多查询</h2><p><strong>需求</strong>:查询用户及用户购买商品信息。</p><p><strong>SQL语句</strong>:</p><p>查询主表是:用户表</p><p>关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:</p><p>orders、orderdetail、items</p><pre><code>SELECT   orders.*, USER.username, USER.sex, USER.address,  orderdetail.id orderdetail_id,
orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.name items_name,
items.detail items_detail, items.price items_price FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id</code></pre><p><strong>映射思路</strong>:</p><p>将用户信息映射到 user 中。<br />在 user 类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist<br />在Orders中添加订单明细列表属性List<OrderDetail>orderdetials,将订单的明细映射到orderdetials<br />在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items</p><h3>定义 resultMap:</h3><pre><code><!--定义查询用户及用户购买商品信息的 resultMap-->
    <resultMap id=

映射文件

<!--查询用户及用户购买商品信息, 使用 resultMap-->
    <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
        SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id
        FROM orders, USER,orderdetail WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
    </select>

Mapper 文件

public List<User> findUserAndItemsResultMap() throws  Exception;

测试文件

@Test
    public void testFindUserAndItemsResultMap() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建OrdersMapperCustom对象,mybatis自动生成代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        //调用OrdersMapperCustom的方法
        List<User> list = ordersMapperCustom.findUserAndItemsResultMap();
        System.out.println(list);
        sqlSession.close();
    }

测试:

《通过项目逐步深入了解Mybatis<三>》” /></span></p><p>我去,竟然报错了,但是不要怕,通过查看报错信息可以知道我忘记在 User.java 中加入 orderlist 属性了,接下来我加上去,并加上 getter 和 setter 方法。</p><pre><code>//用户创建的订单列表
    private List<Orders> ordersList;
    public List<Orders> getOrdersList() {
        return ordersList;
    }
    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }</code></pre><p>再次测试就能成功了。</p><p><span><img layer-src=     原文作者:zhisheng
    原文地址: https://segmentfault.com/a/1190000007691419
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

点赞