Mybatis学习总结——高级映射(一对一,一对多,多对多)

Posted 平凡希

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习总结——高级映射(一对一,一对多,多对多)相关的知识,希望对你有一定的参考价值。

一、订单商品数据模型

1、数据库执行脚本

创建数据库表代码:

/*Table structure for table `t_user` */
CREATE TABLE t_user (
  id INT NOT NULL AUTO_INCREMENT,
  username VARCHAR(32) NOT NULL COMMENT \'用户名称\',
  birthday DATE DEFAULT NULL COMMENT \'生日\',
  sex CHAR(1) DEFAULT NULL COMMENT \'性别\',
  address  VARCHAR(256) DEFAULT NULL COMMENT \'地址\',
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

/*Table structure for table `items` */
CREATE TABLE items (
  id INT NOT NULL  AUTO_INCREMENT,
  itemsname VARCHAR(32) NOT NULL COMMENT \'商品名称\',
  price FLOAT(10,1) NOT NULL COMMENT \'商品定价\',
  detail TEXT COMMENT \'商品描述\',
  pic VARCHAR(64) DEFAULT NULL COMMENT \'商品图片\',
  createtime DATETIME NOT NULL COMMENT \'生产日期\',
  PRIMARY KEY (id)
)  DEFAULT CHARSET=utf8;

/*Table structure for table `orders` */
CREATE TABLE orders (
  id INT NOT NULL AUTO_INCREMENT,
  user_id INT NOT NULL COMMENT \'下单用户id\',
  number VARCHAR(30) NOT NULL COMMENT \'订单号\',
  createtime DATETIME NOT NULL COMMENT \'创建订单时间\',
  note VARCHAR(100) DEFAULT NULL COMMENT \'备注\',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
)  DEFAULT CHARSET=utf8;

/*Table structure for table `orderdetail` */
CREATE TABLE orderdetail (
  id INT NOT NULL AUTO_INCREMENT,
 orders_id INT NOT NULL COMMENT \'订单id\',
  items_id INT NOT NULL COMMENT \'商品id\',
  items_num INT  DEFAULT NULL COMMENT \'商品购买数量\',
  PRIMARY KEY (id),
  KEY `FK_orderdetail_1` (`orders_id`),
  KEY `FK_orderdetail_2` (`items_id`),
  CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
)  DEFAULT CHARSET=utf8;

测试数据:

/*Data for the table `user` */
INSERT  INTO `t_user`(`username`,`birthday`,`sex`,`address`) VALUES 
(\'王五\',NULL,\'2\',NULL),
(\'张三\',\'2014-07-10\',\'1\',\'北京市\'),
(\'张小明\',NULL,\'1\',\'河南郑州\'),
(\'陈小明\',NULL,\'1\',\'河南郑州\'),
(\'张三丰\',NULL,\'1\',\'河南郑州\'),
(\'陈小东\',NULL,\'1\',\'河南郑州\'),
(\'王五\',NULL,NULL,NULL),
 (\'小A\',\'2015-06-27\',\'2\',\'北京\'),
(\'小B\',\'2015-06-27\',\'2\',\'北京\'),
(\'小C\',\'2015-06-27\',\'1\',\'北京\'),
(\'小D\',\'2015-06-27\',\'2\',\'北京\');

/*Data for the table `items` */
INSERT  INTO items(itemsname,price,detail,pic,createtime) VALUES 
(\'台式机\',3000.0,\'该电脑质量非常好!\',NULL,\'2015-07-07 13:28:53\'),
(\'笔记本\',6000.0,\'笔记本性能好,质量好!\',NULL,\'2015-07-08 13:22:57\'),
(\'背包\',200.0,\'名牌背包,容量大质量好!\',NULL,\'2015-07-010 13:25:02\');

/*Data for the table `orders` */
INSERT  INTO `orders`(`user_id`,`number`,`createtime`,`note`) VALUES 
(1,\'1000010\',\'2015-06-04 13:22:35\',NULL),
(1,\'1000011\',\'2015-07-08 13:22:41\',NULL),
(2,\'1000012\',\'2015-07-17 14:13:23\',NULL),
(3,\'1000013\',\'2015-07-16 18:13:23\',NULL),
(4,\'1000014\',\'2015-07-15 19:13:23\',NULL),
(5,\'1000015\',\'2015-07-14 17:13:23\',NULL),
(6,\'1000016\',\'2015-07-13 16:13:23\',NULL);

/*Data for the table `orderdetail` */
INSERT  INTO `orderdetail`(`orders_id`,`items_id`,`items_num`) VALUES
 (1,1,1),
 (1,2,3),
 (2,3,4),
 (3,2,3);

2、数据模型分析思路

(1).每张表记录的数据内容:分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程;

(2).每张表重要的字段设置:非空字段、外键字段;

(3).数据库级别表与表之间的关系:外键关系;

(4).表与表之间的业务关系:在分析表与表之间的业务关系时一定要建立在某个业务意义基础上去分析。

3、针对订单商品模型的数据库思路分析:

用户表:t_user-->记录了购买商品的用户信息

订单表:orders-->记录了用户所创建的订单(购买商品的订单)

订单明细表:orderdetail-->记录了订单的详细信息即购买商品的信息

商品表:items-->记录了商品信息

表与表之间的业务关系:

  在分析表与表之间的业务关系时需要建立 在某个业务意义基础上去分析。

  先分析数据级别之间有关系的表之间的业务关系:

t_userorders

  t_user---->orders:一个用户可以创建多个订单,一对多

  orders--->t_user:一个订单只由一个用户创建,一对一

orders和orderdetail

  orders--->orderdetail:一个订单可以包括多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系

  orderdetail--> orders:一个订单明细只能包括在一个订单中,一对一

orderdetail和items

  orderdetail--->itesms:一个订单明细只对应一个商品信息,一对一

  items--> orderdetail:一个商品可以包括在多个订单明细 ,一对多

再分析数据库级别没有关系的表之间是否有业务关系:

orders和items

  ordersitems之间可以通过orderdetail表建立关系。

4、分析之后画出对应的图,方便直观的了解业务关系

二、一对一查询

2.1、需求:查询订单信息,关联查询用户信息。

2.2、resultType实现

2.2.1、sql语句   

   确定查询的主表:订单表,确定查询的关联表:用户表。

SELECT    t1.*,t2.username,t2.sex,t2.address
FROM  orders t1,t_user t2
WHERE t1.user_id=t2.id

2.2.2、创建entity实体

用户实体:User.java

package com.mybatis.entity;

import java.util.Date;
import java.util.List;

/**
 * @ClassName: User
 * @Description: TODO(用户实体)
 * @author lixiaoxi
 * @date 2015-6-27 下午1:56:02
 * 
 */
public class User {
    // 属性名称和数据库字段名称保持一致
    private Integer id;
    // 姓名
    private String username;
    // 性别
    private String sex;
    // 地址
    private String address;
    // 生日
    private Date birthday;
    // 用户创建的订单列表
    private List<Orders> ordersList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
    public List<Orders> getOrdersList() {
        return ordersList;
    }

    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", address=" + address + ", birthday=" + birthday + "]";
    }

}

订单实体:Orders.java

package com.mybatis.entity;

import java.util.Date;
import java.util.List;

/**
 * @ClassName: Orders
 * @Description: TODO(订单实体)
 * @author lixiaoxi 
 */
public class Orders {
    
    /** 主键订单Id */
    private Integer id;
    /** 下单用户id */
    //private Integer userid;
    /** 订单号 */
    private String number;
    /** 创建订单时间 */
    private Date createTime;
    /** 备注 */
    private String note;
    // 用户信息
    private User user;
    // 订单明细
    private List<OrderDetail> orderdetails;
    
    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;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public List<OrderDetail> getOrderdetails() {
        return orderdetails;
    }
    public void setOrderdetails(List<OrderDetail> orderdetails) {
        this.orderdetails = orderdetails;
    }

}

商品实体:Items.java

package com.mybatis.entity;

import java.util.Date;

/**
 * @ClassName: Items
 * @Description: TODO(商品实体类)
 * @author lixiaoxi 
 */
public class Items {
    
    /** 商品表主键Id */
    private Integer id;
    /** 商品名称 */
    private String itemsName;
    /** 商品定价 */
    private float price;
    /** 商品描述 */
    private String detail;
    /** 商品图片 */
    private String picture;
    /** 生产日期 */
    private Date createTime;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getItemsName() {
        return itemsName;
    }
    public void setItemsName(String itemsName) {
        this.itemsName = itemsName;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    public String getDetail() {
        return detail;
    }
    public void setDetail(String detail) {
        this.detail = detail;
    }
    public String getPicture() {
        return picture;
    }
    public void setPicture(String picture) {
        this.picture = picture;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

}

订单明细实体:OrderDetail.java

package com.mybatis.entity;

/**
 * @ClassName: OrderDetail
 * @Description: TODO(订单明细实体)
 * @author lixiaoxi 
 */
public class OrderDetail {

    /** 主键,订单明细表Id */
    private Integer id;
    /** 订单Id */
    private Integer ordersId;
    /** 商品id */
    private Integer itemsId;
    /** 商品购买数量 */
    private Integer itemsNum;
    // 明细对应的商品信息
    private Items items;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getOrdersId() {
        return ordersId;
    }
    public void setOrdersId(Integer ordersId) {
        this.ordersId = ordersId;
    }
    public Integer getItemsId() {
        return itemsId;
    }
    public void setItemsId(Integer itemsId) {
        this.itemsId = itemsId;
    }
    public Integer getItemsNum() {
        return itemsNum;
    }
    public void setItemsNum(Integer itemsNum) {
        this.itemsNum = itemsNum;
    }
    public Items getItems() {
        return items;
    }
    public void setItems(Items items) {
        this.items = items;
    }
}

创建一个包装类,将查询到的信息可以全部映射到此类:OrdersCustom.java 

/**
 * @ClassName: OrdersCustom
 * @Description: TODO(订单的扩展类,通过此类映射订单和用户的查询结果,让此类继承字段较多的实体类)
 * @author: 阿赫瓦里
 */
public class OrdersCustom extends Orders {
    // 添加用户的属性
    private String username;
    private String sex;
    private String address;
        // getter and setter......
}

2.2.3、创建OrdersCustomMapper.java

package com.mybatis.mapper;

import java.util.List;
import com.mybatis.entity.OrdersCustom;

public interface OrdersCustomMapper {
    
    /** 查询订单,关联查询用户信息 */
    public List<OrdersCustom> findOrdersUser();

}

 2.2.4、创建OrdersCustomMapper.xml和上面对应的接口名称一致,以便通过mapper接口加载配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.mybatis.mapper.OrdersCustomMapper">

    <!-- 查询订单,关联查询用户信息 -->
    <select id="findOrdersUser" resultType="com.mybatis.entity.OrdersCustom">
        select t1.*,t2.username,t2.sex,t2.address from orders t1,t_user t2
        where t1.user_id = t2.id
    </select>
    
</mapper>

2.3、resultMap实现

2.3.1、sql语句同上

2.3.2、resultMap映射思路:

使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中(上面orders实体中已经添加)。

2.3.3、ordersCustomMapper.xml

1、定义resultMap

<!-- 定义查询订单关联用户的 resultMap,将整个的查询结果映射到com.mybatis.entity.Orders中 -->
<resultMap type="com.mybatis.entity.Orders" id="OrdersUserResultMap">
    <!-- 1.配置映射的订单信息 -->
    <!-- id:查询列中的唯一标识,订单信息中的唯一标识,如果多列组成唯一标识(如:一般数据库设计中的字典表 使用联合主键),
        就需要配置多个id. 
        column:订单信息的唯一标识 列
        property:订单信息的唯一标识列所映射到orders中的那个属性(假如:数据库中orders表中的主键为orders_id,而实体属性名称
            为ordersId,则这个配置应为<id column="orders_id" property="ordersId"/>,类似hibernate实体映射文件配置)。
    -->
    <id column="id" property="id"/>
    <result column="number" property="number"/>
    <result column="createtime"以上是关于Mybatis学习总结——高级映射(一对一,一对多,多对多)的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis总结之高级映射一对多查询

Mybatis 高级映射,一对一,一对多,多对多映射

Mybatis学习笔记—高级映射,延迟加载

mybatis映射 一对一,一对多,多对多高级映射

MyBatis从入门到精通:MyBatis高级结果映射之一对多映射

四:MyBatis基于XML的详细使用——高级结果映射