MyBatis的映射

     转载文章,格式全乱了,转载地址:https://blog.csdn.net/qq_21963133/article/details/79766445。 话说CSDN什么时候能搞一个分享到自己博客的功能啊。
前面的章节使用的都是对单张表的操作,但是在实际开发当中,很多时候需要关联多张表,这时就需要用到我们的高级映射,包括一对一,一对多和多对多。

下面先来分析一个简单的业务场景。

有四张表:

用户表:user保存用户相关信息。


 
 
  1. CREATE TABLE `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) DEFAULT NULL COMMENT '用户名',
    `birthday` date DEFAULT NULL COMMENT '出生年月',
    `sex` varchar(255) DEFAULT NULL COMMENT '性别',
    `addr` varchar(255) DEFAULT NULL COMMENT '地址',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加测试数据:


商品表:items保存商品相关的信息。


 
 
  1. CREATE TABLE `items` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(32) NOT NULL,
    `price` decimal(10,2) NOT NULL,
    `detail` varchar(255) DEFAULT NULL,
    `pic` varchar(255) DEFAULT NULL,
    `createtime` datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加测试数据:


订单表:orders保存订单的信息,关联用户表user,一个订单对应一个user用户。


 
 
  1. CREATE TABLE `orders` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单号',
    `user_id` int(11) NOT NULL,
    `number` int(32) NOT NULL,
    `createtime` datetime NOT NULL,
    `note` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `user_id` (`user_id`),
    CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加测试数据:


订单明细表:orderdetail一个订单当中包含多个商品。


 
 
  1. CREATE TABLE `orderdetail` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `orders_id` int(11) NOT NULL,
    `items_id` int(11) NOT NULL,
    `items_num` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `orders_id` (`orders_id`),
    KEY `items_id` (`items_id`),
    CONSTRAINT `orderdetail_ibfk_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`),
    CONSTRAINT `orderdetail_ibfk_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加测试数据:


第一个需求,查询订单并关联用户的信息。

创建orders类,


 
 
  1. public class Orders {
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public Integer getUserId() {
    return userId;
    }
    public void setUserId(Integer userId) {
    this.userId = userId;
    }
    public String getNumber() {
    return number;
    }
    public void setNumber(String number) {
    this.number = number;
    }
    public Date getCreatetime() {
    return createtime;
    }
    public void setCreatetime(Date createtime) {
    this.createtime = createtime;
    }
    public String getNote() {
    return note;
    }
    public void setNote(String note) {
    this.note = note;
    }
    }

sql语句

 
select orders.*,user.username,user.sex,user.addr from orders,user WHERE orders.user_id=user.id
 
 

1:使用resultType作映射。

 

 
 
  1. <!-- 查询订单关联查询用户 -->
    <select id="findOrdersUser" resultType="OrdersCustom">
    select orders.*,user.username,user.sex,user.addr from orders,user WHERE orders.user_id=user.id
    </select>
由于orders类中没有用户的相关信息,所以这里需要使用一个扩展类继承orders,并添加用户的属性。
 

 
 
  1. /**
    * @author:kevin
    * @description: 订单的扩展类
    * 通过此类映射订单和用户查询的结果,让此类继承包括字段较多的pojo类
    * @create 2018-03-31 9:40
    */
    public class OrdersCustom extends Orders{
    //添加属性
    private String username;
    private String sex;
    private String addr;
    public String getUsername() {
    return username;
    }
    public void setUsername(String username) {
    this.username = username;
    }
    public String getSex() {
    return sex;
    }
    public void setSex(String sex) {
    this.sex = sex;
    }
    public String getAddr() {
    return addr;
    }
    public void setAddr(String addr) {
    this.addr = addr;
    }
    }
在当前包下新建一个接口OrdersMapperCustom和xml OrdersMapperCustom.xml
将xml中的namespace改成接口的路径
com.beyond.mybatis.mapper.OrdersMapperCustom

 
 
  1. <!-- 查询订单关联查询用户 -->
    <select id="findOrdersUser" resultType="OrdersCustom">
    select orders.*,user.username,user.sex,user.addr from orders,user WHERE orders.user_id=user.id
    </select>

在接口中添加对应的方法。


 
 
  1. //查询订单关联查询用户信息
    List <OrdersCustom> findOrdersUser() throws Exception;
测试:
 

 
 
  1. @Test
    public void testfindOrdersUser() throws Exception{
    SqlSession sqlSession = factory.openSession();
    //通过反射拿到UserMapper的代理对象
    OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
    List <OrdersCustom> list = ordersMapperCustom.findOrdersUser();
    System.out.println(list);
    }
通过断点调试,查看list中的值:
查询到了三条记录:

2:使用resultMap进行映射

在orders类中添加一个属性User。


 
 
  1. <!-- 查询订单关联查询用户,使用resultMap -->
    <select id="findOrdersUserResultMap" resultMap="ordersUserResultMap">
    select orders.*,user.username,user.sex,user.addr from orders,user WHERE orders.user_id=user.id
    </select>

 
 
  1. <!-- 订单查询关联用户的resultMap -->
    <resultMap id="ordersUserResultMap" type="Orders">
    <!-- 配置映射的订单信息 -->
    <!-- id:指定查询列中的唯一标识,如果多个列组成唯一标识,配置多个id -->
    <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"/>
    <!-- 配置映射的关联的用户信息 -->
    <!-- association:用于映射关联查询单个对象的信息
    property:要将关联查询的用户信息映射到Orders中的哪个属性
    -->
    <association property="user" javaType="com.beyond.mybatis.po.User">
    <!-- id:关联查询用户的唯一标识
    column:指定唯一标识用户信息的列
    javaType:映射到user的哪个属性
    -->
    <id column="user_id" property="id"/>
    <result column="username" property="username"/>
    <result column="sex" property="sex"/>
    <result column="addr" property="addr"/>
    </association>
    </resultMap>

 
 
  1. //查询订单关联查询用户信息,resultMap
    List <Orders> findOrdersUserResultMap() throws Exception;
测试:

 
 
  1. @Test
    public void testfindOrdersUser() throws Exception{
    SqlSession sqlSession = factory.openSession();
    //通过反射拿到UserMapper的代理对象
    OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
    List <Orders> list = ordersMapperCustom.findOrdersUserResultMap();
    System.out.println(list);
    }
对其进行断点调试:
 
 

实现一对一查询时的resultType和resultMap的小结:

resultType:使用非常简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射,

如果没有查询结果的特殊要求,建议使用resultType。

resultMap:需要单独定义resultMap,实现有点麻烦,如果有对查询结果的特殊要求,使用resultMap可完成将

关联查询映射到pojo属性中。

resultMap可以实现延迟加载,resultType不能实现延迟加载。

第二个需求,查询订单及订单明细,一对多的查询

主表:orders

关联表:orderdetail

sql语句:


 
 
  1. <!-- 查询订单关联查询用户及订单明细,使用resultMap -->
    <select id="findOrdersAndOrderDetailResultMap" resultMap="ordersAndOrderDetailResultMap">
    select
    orders.*,
    user.username,
    user.sex,
    user.addr,
    orderdetail.id orderdetail_id,
    orderdetail.items_id,
    orderdetail.items_num,
    orderdetail.orders_id
    from
    orders,
    user,
    orderdetail
    where
    orders.user_id=user.id
    and
    orders.id=orderdetail.orders_id
    </select>


然后需在orders类中添加一个orderDetails属性,并生成get和set方法。
 

定义resultMap:

由于前面定义了订单及用户的信息,这里可以直接继承;


 
 
  1. <!-- 查询订单及订单明细的resultMap -->
    <resultMap id="ordersAndOrderDetailResultMap" type="orders" extends="ordersUserResultMap">
    <!-- 订单信息,通过继承得到 -->
    <!-- 用户信息,通过继承得到 -->
    <!-- 订单明细信息
    collection:对关联查询的到的多条记录映射到集合中
    property:orders中要映射的哪个属性
    ofType:集合属性中pojo的类型
    -->
    <collection property="orderDetails" ofType="com.beyond.mybatis.po.OrderDetail">
    <!-- 主键 -->
    <id column="orderdetail_id" property="id"/>
    <!--普通列-->
    <result column="items_id" property="itemsId"/>
    <result column="items_num" property="itemsNum"/>
    <result column="orders_id" property="orderId"/>
    </collection>
    </resultMap>
添加接口方法:
 

 
 
  1. //查询订单关联查询订单明细信息
    List <Orders> findOrdersAndOrderDetailResultMap() throws Exception;
测试:
 

 
 
  1. @Test
    public void testfindOrdersAndOrderDetailResultMap() throws Exception{
    SqlSession sqlSession = factory.openSession();
    //通过反射拿到UserMapper的代理对象
    OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
    List <Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();
    System.out.println(list);
    }
利用断点调试,观察list集合。
一共有两个订单,第一个订单属于id为的用户,且包含三个订单明细(即包含三件商品)。
 
 

第三个需求,查询用户及用户购买的商品,多对多

主表:user

思路:在user中添加订单列表的属性,List<Orders> orders

在orders中添加订单明细列表的属性,List<OrderDetail> orderDetails;

在orderDetail中添加商品属性,Items items,

sql语句:


 
 
  1. <!-- 查询用户及用户购买的商品信息,使用resultMap -->
    <select id="findUsersAndItemsResultMap" resultMap="usersAndItemsResultMap">
    select
    orders.*,
    user.username,
    user.sex,
    user.addr,
    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
    orders.id=orderdetail.orders_id
    and
    orderdetail.items_id=items.id
    </select>
User类中添加:private List<Orders> orders;生成get和set方法。
Orders类中在上面已经添加,

Orders类中在上面已经添加,在OrderDetail中添加Items属性同样生成get和set方法。

    编写resultMap:

    


 
 
  1. <!-- 查询用户及用户所购买的商品信息 -->
    <resultMap id="usersAndItemsResultMap" type="user">
    <!-- 用户信息 -->
    <id column="user_id" property="userId"/>
    <result column="username" property="username"/>
    <result column="sex" property="sex"/>
    <result column="addr" property="addr"/>
    <!-- 一个用户对应多个订单信息 -->
    <collection property="orders" ofType="com.beyond.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="orderDetails" ofType="com.beyond.mybatis.po.OrderDetail">
    <!-- 主键 -->
    <id column="orderdetail_id" property="id"/>
    <!--普通列-->
    <result column="items_id" property="itemsId"/>
    <result column="items_num" property="itemsNum"/>
    <result column="orders_id" property="orderId"/>
    <!-- 一个订单明细对应一条商品信息 -->
    <association property="items" javaType="com.beyond.mybatis.po.Items">
    <id column="items_id" property="id"/>
    <result column="items_name" property="name"/>
    <result column="items_detail" property="detail"/>
    <result column="items_price" property="price"/>
    </association>
    </collection>
    </collection>
    </resultMap>

编写接口方法:


 
 
  1. //查询用户及用户购买的商品信息
    List <User> findUsersAndItemsResultMap() throws Exception;

测试:


 
 
  1. @Test
    public void testfindUsersAndItemsResultMap() throws Exception{
    SqlSession sqlSession = factory.openSession();
    //通过反射拿到UserMapper的代理对象
    OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
    List <User> list = ordersMapperCustom.findUsersAndItemsResultMap();
    System.out.println(list);
    }

断点调试查看list的信息:

一共有两个用户有订单,

一个用户购买了三件商品:华硕、联想和神州


另外一个用户购买了两件商品:华硕和苹果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值