Mybatis--13Mybatis的高级映射

Mybatis的高级映射

  • 以订单数据模型为例进行分析
  • 一对一映射
  • 一对多映射
  • 多对多映射
  • ResultMap和ResultType的总结

在多表联合查询操作时,存在一对一、一对多、多对多的关系

以订单数据模型为例进行分析

每张表中的数据内容
每张表的主要字段:外键字段,非空字段
表与表之间的业务关系

数据库表:
Mybatis--13Mybatis的高级映射_第1张图片
user(用户表):记录购买商品的用户信息
orders(订单表):记录用户创建的所有订单
orderdetail(订单明细表):记录订单的详细的购买信息
items(商品表):记录商品信息

 CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8  


 CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) 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 `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8


 CREATE TABLE `orderdetail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orders_id` int(11) NOT NULL COMMENT '订单id',
  `items_id` int(11) NOT NULL COMMENT '商品id',
  `items_num` int(11) 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
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8


 CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` 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`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

数据库模型分析
Mybatis--13Mybatis的高级映射_第2张图片

一对一映射

需求:通过订单号查询订单及用户信息
分析:通过分析:订单号是在订单表中,通过订单表中的user_id字段可以查询到用户信息
主表:orders 从表:user
SQL:select * from orders o,user u where o.user_id=u.id and o.number=?

pojo类中添加User类型的属性:

public class Orders {
    private int id;
    private int userId;
    private long number;
    private Date createtime;
    private String note;
    
    // 增加一个User类型
    private User user;
    private String createTime;

	//Getter和Setter方法
}

接口:

    public Orders getOrdersByNumber(String number);

Mapper的XML文件

使用resultType配置一对一映射:

    <select id="getOrdersByNumber" parameterType="java.lang.String" resultType="com.tulun.maventest.pojo.Orders">
        select o.*,u.id "user.id",u.username "user.username",u.sex "user.sex",u.address "user.address" from orders o,user u where o.user_id=u.id and o.number=#{number}
    </select>

使用resultMap配置一对一映射:

    <resultMap id="OrderUserResultMap" type="com.tulun.maventest.pojo.Orders">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
        <result column="note" property="note"/>
        <!--user配置-->
        <result column="u_id" property="user.id"/>
        <result column="u_username" property="user.username"/>
        <result column="u_sex" property="user.sex"/>
        <result column="u_address" property="user.address"/>
    </resultMap>

    <select id="getOrdersByNumber" parameterType="java.lang.String" resultMap="OrderUserResultMap">
        select o.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.user_id=u.id and o.number=#{number}
    </select>

使用resultMap提供的association配置一对一映射:

    <resultMap id="OrderUserResultMap" type="com.tulun.maventest.pojo.Orders">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
        <result column="note" property="note"/>
        <!--
        association:用于映射关联查询单个对象的信息
        property:关联查询映射到对应的自定义的对象属性
        javaType:映射的Java属性的全限定名
        -->
        <association property="user" columnPrefix="u_" javaType="com.tulun.maventest.pojo.User">
            <!--user配置-->
            <result column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>
    
    <select id="getOrdersByNumber" parameterType="java.lang.String" resultMap="OrderUserResultMap">
        select o.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.user_id=u.id and o.number=#{number}
    </select>

优化1:使用extends属性继承当前的主类

    <!--优化1:使用association关联映射对象,extends继承主类-->
    <!--association配置-->
    <resultMap id="OrderUserResultMap" extends="OrdersResultMap" type="com.tulun.maventest.pojo.Orders">
        <association property="user" columnPrefix="u_" javaType="com.tulun.maventest.pojo.User">
            <!--user配置-->
            <result column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>

优化2:使用association中的resultMap属性

    <!--优化2:使用association关联映射对象,extends继承主类,使用association标签下resultMap的属性-->
    <!--association配置-->
    <resultMap id="OrderUserResultMap" extends="OrdersResultMap" type="com.tulun.maventest.pojo.Orders">
        <!--association的resultMap属性指向已存在Mapper的全路径名-->
        <association property="user" columnPrefix="u_" resultMap="com.tulun.maventest.dao.UserMapper.ResultUserMapper"/>
    </resultMap>
一对一映射中,使用到resultMap的association标签。

resultMap和resultType的区别?

一对多映射

需要关联的映射是一个List结果

需求:查询用户的订单信息(例如:通过用户ID)
分析:通过用户(主表:user)的关键信息查询所有相关的订单(从表:orders)

SQL:select u.*,o.* from user u,orders o where u.id =o.user_id and u.id=?

映射对象:

public class User {
    private int id;
    private String username;
    private String sex;
    private String address;
    //增加一个Order类型的集合
    private List<Orders> orders;
    }

Mybatis的XML文件中SQL片段的复原示例:
Mybatis--13Mybatis的高级映射_第3张图片
XML文件配置:

       <!--
    使用resultMap中的Collection配置一对多关系
    Collection:将关联查询的多条记录映射到集合对象中
    property:将关联查询的多条记录映射到的属性名:orders
    ofType:指定映射的集合属性中的自定义类型
    extends:继承主类
    -->
    <resultMap id="ResultUserOrdersMapper" extends="ResultUserMapper" type="com.tulun.maventest.pojo.User">
        <!--orders的结果集-->
        <collection property="orders" columnPrefix="order_" ofType="com.tulun.maventest.pojo.Orders">
            <result 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>
    </resultMap>

    <sql id="selectId">
        u.id,
        u.username,
        u.sex,
        u.address,
        o.id order_id,
        o.user_id order_user_id,
        o.number order_number,
        o.createtime order_createtime,
        o.note order_note
    </sql>

    <select id="getUserOrdersById" parameterType="int" resultMap="ResultUserOrdersMapper">
        select
            <include refid="selectId"/>
        from user u, orders o where u.id=o.user_id and u.id=#{uid}
    </select>
一对多的映射:使用到resultMap下的Collection标签

多对多映射

需求:查询用户及用户的商品信息
分析:主表是user
存在用户对象User,存在订单表对象Orders,存在订单明细表对象OrderDetail,商品表对象Items
映射的对象为User对象,在User对象中添加一个订单列表的属性:Lise,将用户创建的订单映射到orderlist,
在Orders中添加订单明细的属性List,将订单明细映射到OrderDetails属性,
在订单明细中OrderDetail中添加Items的属性,将订单明细所对应的商品映射到item

ResultMap和ResultType的总结

resultType:
作用:将查询结果的SQL列名和pojo类的属性名完成一致性的映射
缺点:若SQL结果列名和pojo类属性名不一致,则无法自动完成映射

resultMap:
使用association和Collection完成一对一和一对多的高级映射(对结果有特殊要求的映射对象 )
作用:将关联查询的信息映射到一个pojo对象中
使用resultType无法将查询结果映射到pojo对象的pojo属性中时,选择resultMap来处理(association)

Collection:
作用:将关联查询映射到一个List集合中
使用resultType无法将查询结果映射到pojo对象的List类型的pojo属性时,使用resultMap的Collection标签来处理

你可能感兴趣的:(java,mysql)