【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无法实现延迟加载。