Mybatis高级映射本质上来说是多个表的联合查询过程
订单数据模型分析思路
数据表:
用户表user:记录了购买商品的用户信息
订单表orders:记录了用户创建的订单(购买商品的订单)
订单明细表orderdatail:记录了订单的详细信息即购买商品的信息
商品表items:记录了商品信息
drop table if exists `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 DEFAULT CHARSET=utf8;
/*Table structure for table `user` */
drop table if exists `user`;
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 DEFAULT CHARSET=utf8;
/*Table structure for table `orders` */
drop table if exists `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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `orderdetail` */
drop table if exists `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`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
关注点:
每张表记录的内容
每张表的重要字段
表与表之间的关联:外键
数据模型分析:
表与表之间的业务关系:
用户表user和订单表order的关系:(一对多关系)
user->orders:一个用户可以创建多个订单,一对多
orders->user:一个订单只能由一个用户创建,一对一
订单表orders和订单明细表orderdatail关系:(一对多关系)
orders->orderdatail:一个订单可以包括多个订单明细,一对多
orderdatail->orders:一个订单明细只能包括在一个订单中,一对一
订单明细表orderdatail和商品表items关系:(一对多关系)
items->orderdatail:一个商品可以存在于多个订单明细中,一对多
orderdatail->items:一个订单明细只能包括一个商品,一对一
用户表user和商品表items关系:(多对多关系)
user->items:一个用户可以购买多个商品,多对多
items->user:一个商品可以被多个用户购买,多对多
一对一映射:
需求:通过订单号查询订单和用户信息
select * from orders o,user u where o.number =? and o.user_id=u.id;
分析:
通过orders表作为主表来查询,user表是辅助表
在orders的pojo类上添加上user属性
public class Orders {
private Integer id;
private Integer userId;
private String number;
private Date createTime;
private String note;
//新增属性
private User user;
}
接口方法:
Orders selectOrdersByNumber(String number);
返回结果通过resultType返回:
<select id="selectOrdersByNumber" parameterType="String" resultType="com.wrj.maventest.Mybatis.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.number =#{number} and o.user_id=u.id
</select>
返回结果通过resultMap返回:
<resultMap id="orderUserType" type="com.wrj.maventest.Mybatis.pojo.Orders">
<id property="id" column="id"/>
<result property="userId" column="User_id"/>
<result property="number" column="number"/>
<result property="createTime" column="createtime"/>
<result property="note" column="note"/>
<!--user属性配置-->
<result property="user.id" column="u_id"/>
<result property="user.username" column="u_username"/>
<result property="user.sex" column="u_sex"/>
<result property="user.address" column="u_address"/>
</resultMap>
<select id="selectOrdersByNumber" parameterType="String" resultMap="orderUserType">
select 0.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.number =#{numner} and o.user_id=u.id
</select>
优化1:
使用resultMap中提供的association配置一对一关系
association:用于配置关联查询的单个对象
property属性:要映射到pojo类中的对象的属性
javaType属性:要映射的pojo属性的全限定名
columnPrefix属性:针对数据库别名的相同前缀
<resultMap id="orderUserType1" type="com.wrj.maventest.Mybatis.pojo.Orders">
<id property="id" column="id"/>
<result property="userId" column="User_id"/>
<result property="number" column="number"/>
<result property="createTime" column="createtime"/>
<result property="note" column="note"/>
<association property="user" columnPrefix="u_" javaType="com.wrj.maventest.Mybatis.pojo.User">
<result property="id" column="id"/>
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
</association>
</resultMap>
<select id="selectOrdersByNumber" parameterType="String" resultMap="orderUserType1">
select 0.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.number =#{numner} and o.user_id=u.id
</select>
优化2:
<resultMap id="orderType" type="com.wrj.maventest.Mybatis.pojo.Orders">
<id property="id" column="id"/>
<result property="userId" column="User_id"/>
<result property="number" column="number"/>
<result property="createTime" column="createtime"/>
<result property="note" column="note"/>
</resultMap>
<!--
extends属性:继承自主类
association的resultMap使用一个已经存在的mapper类
-->
<resultMap id="orderUserType2" extends="orderType" type="com.wrj.maventest.Mybatis.pojo.Orders">
<association property="user" columnPrefix="u_" resultMap="com.wrj.maventest.Mybatis.mapper.UserMapper.userMap"/>
</resultMap>
注:一对一映射使用resultMap下的association来配置映射关系
一对多映射:
将关联的列映射为List
需求:查询用户的订单信息
select * from user u,orders o where u.id=o.user_id and u.id=?;
分析:主表是用户user表,订单orders表是辅助表
使用resultMap下提供的Collection来配置 一对多的关系
1.映射pojo类配置
public class User {
private Integer id;
private String username;
private String sex;
private String address;
//添加orders属性
private List<Orders> orders;
}
2.配置文件
<resultMap id="userMap" type="com.wrj.maventest.Mybatis.pojo.User">
<id property="user.id" column="id"/>
<result property="user.username" column="username"/>
<result property="user.sex" column="sex"/>
<result property="user.address" column="address"/>
<collection property="orders" ofType="com.wrj.maventest.Mybatis.pojo.Orders" columnPrefix="0_">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createTime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="selectUserById" parameterType="int" resultMap="userMap">
select u.*,o.id o_id,o.user_id o_user_id,o.number o_number,
o.craatetime o_createtime,o.note o_note from user u,orders o where u.id=o.user_id and u.id=#{id};
</select>
使用resultMap标签下提供的collection配置一对多的关系
collection:对关联查询的多条记录映射到集合对象中
property属性:将关联查询到的多条记录信息映射到orders属性中
oftype:指定映射的集合属性中的类型全限定名
columnPrefix属性:针对数据库别名的相同前缀
多对多映射
需求:查询用户及购买的商品信息
分析:查询用户是主表:user表
关联表:订单orders表 订单orderdatiles明细表 商品items表
将结果要映射到user属性中,在user类上添加订单列表属性 List<Orders> orderList,用户创建的订单映射到orderList中
Orders类中添加订单明细列表属性 List<OrderDetails>,将订单明细映射到orderDetails中
OrderDetails类中添加商品属性item,将商品映射到item上
resultType和resultMap
resultType:
将数据库中的数据映射到pojo类上,自动将字段完成映射,减少映射的编码,不能映射对于数据库字段和pojo类属性不一致的情况,如果所有字段都不匹配,则无法映射一个pojo对象
1.映射自动化,如果字段较少且保持一致优先选择resultType
2.对于多表的映射只能进行一对一映射
resultMap:
手动显性实现映射,可以映射数据库字段和pojo类属性不一致的情况,还可以使用association和collection来完成一对一和一对多的高级映射
association:
将关联的查询信息映射到一个pojo类中
collection:
将关联的查询信息映射到一个list集合中