【Mybatis】---高级映射之一对一查询

   在上一篇mybatis的博客中介绍了mybatis+mysql+IDEA如何搭建框架以及一个简单的例子.【Mybatis】---mybatis+mysql+ IntelliJ IDEA框架搭建+实例讲解,接下来要讲解的是mybatis的高级映射.mybatis的高级映射包括一对一查询,一对多,多对多查询.本篇文章将要介绍使用ResultType和ResultMap的一对一查询.将通过这两种方式进行实例讲解.

数据模型

本文将通过订单商品的数据模型来进行讲解.共包含四张表

user(用户表)记录了购买商品的用户信息

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

orderdetail(订单详情表)记录了订单的详细信息即购买商品的信息

items(商品表)记录了商品信息



/*
SQLyog v10.2 
MySQL - 5.1.72-community : Database - mybatis
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Table structure for table `items` */

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;

/*Table structure for table `orderdetail` */

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;

/*Table structure for table `orders` */

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=6 DEFAULT CHARSET=utf8;

/*Table structure for table `user` */

CREATE TABLE `user` (
  `id` int(11) 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`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

附加上各个表之间的对应关系.

需求:

   查询订单信息,关联查询创建订单的用户信息

ResultType

sql语句

在使用sql语句查询的时候,使用了内连接,由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条数据.确定查询的主表为:订单表,关联表为用户表.
SELECT 
  orders.*,
  USER.username,
  USER.sex,
  USER.address 
FROM
  orders,
  USER 
WHERE orders.user_id = user.id

创建pojo

package cn.itcast.mybatis.po;

/**
 * Created by CXC on 2017/2/26.
 */
//通过此类映射订单和用户查询的结果,让此类继承字段较多的pojo类
public class OrderCustom extends Orders{

    private  String username;

    private  String sex;

    private  String address;

    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;
    }
}

mapper.xml


<!-- 查询订单关联查询用户信息-->
    <select id="findOrderUser"  resultType="cn.itcast.mybatis.po.OrderCustom">
  SELECT
    orders.*,
    USER.username,
    USER.sex,
    USER.address
  FROM
    orders,
    USER
  WHERE orders.user_id = user.id


  </select>

mapper.java

package cn.itcast.mybatis.mapper;

import cn.itcast.mybatis.po.OrderCustom;
import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.User;

import java.util.List;

/**
 * Created by CXC on 2017/2/26.
 */
public interface OrdersMapperCustomer {
    //根据订单关联查询用户信息
    public List<OrderCustom> findOrderUser() throws  Exception;
    
}

ResultMap

   使用ResultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中.

sql语句

同resultType实现的sql语句

修改pojo

在Orders类中添加user属性

    //用户信息
    private User user;

mapper.xml
<!-- 订单查询关联用户的resultMap
	将整个查询的结果映射到cn.itcast.mybatis.po.Orders中
	 -->
	<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
		<!-- 配置映射的订单信息 -->
		<!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
			column:订单信息的唯 一标识 列
			property:订单信息的唯 一标识 列所映射到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/>
		
		<!-- 配置映射的关联的用户信息 -->
		<!-- association:用于映射关联查询单个对象的信息
		property:要将关联查询的用户信息映射到Orders中哪个属性
		 -->
		<association property="user"  javaType="cn.itcast.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="address" property="address"/>
		
		</association>
	</resultMap>

<!-- 查询订单关联查询用户信息,使用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.java
   //查询订单关联查询用户使用resultMap
    public List<Orders> findOrdersUserResultMap() throws Exception;


总结:

resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。

resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。resultMap可以实现延迟加载,resultType无法实现延迟加载。

posted @ 2017-02-28 11:52  陈晓婵  阅读(310)  评论(0编辑  收藏  举报