标签:
这篇文章延续订单商品数据模型,这张讲述的是一对多的查询。(用resultMap)
给出几张表的内容:
User表:
orders表:
orderdetail表:
orders表:
items表:
在SQLyog中写一个sql语句 (先验证成功):
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
结果是:
其实我们要做的就是:把上面查出来的那个数据表每个字段映射好!!!
好,现在开始:
先给出需求:
查询订单及订单明细的信息。
我们由前面的文章知道查询订单及订单明细的信息是一对多的关系。
我们还是按照:1.sql 2.pojo映射类3.mapper.xml和mapper.java接口这种顺序。
1.sql语句:
确定主查询表:订单表
确定关联查询表:订单明细表
在一对一查询基础上添加订单明细表关联即可。
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,//别名orderdetail_id
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
这种sql查询出来的结果是:
很明显查询出来的结果是重复的(两个id为3的数据,两个id为4的数据,为什么会出现这样的结果,原因是:
我们知道一张订单表会对应多个订单明细表,这样的话就是说一个用户有一张订单表,那么一张订单表上肯定有很多的订单信息表
)
但是上面的这样结果如果用resultType来做的:使用resultType将上边的 查询结果映射到pojo中,订单信息的就是重复。我们采用的是resultMap.
但是我们的需求是:对orders映射不能出现重复记录。
在orders.java类中添加List<orderDetail> orderDetails属性。
最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中。
映射成的orders记录数为两条(orders信息不重复)
每个orders中的orderDetails属性存储了该 订单所对应的订单明细。
效果如下:
上面图Orders只有两条信息,每个Orders中的各有两条orderDetails信息。这样就刚好一一对应了。一对多——完美!
2.根据上面的思路来创建pojo类:
package cn.itcast.mybatis.po; import java.util.Date; import java.util.List; public class Orders { private Integer id; private Integer user_id; private String number; private Date createtime; private String note; //用户信息,新增了一个User属性,为了保存查询得到的关联的User表的信息(一对一) private User user; //订单明细。order关联多个orderdetails,(一对多) private List<Orderdetail> orderdetails; public List<Orderdetail> getOrderdetail() { return orderdetails; } public void setOrderdetail(List<Orderdetail> orderdetail) { this.orderdetails = orderdetail; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } 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; } }
3.创建mapper.xml和mapper.java接口。
OrdersMapperCustom.xml代码如下:
OrdersMapperCustom.xm写法一:
<?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"> <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离 注意:使用mapper代理方式,namespace有特殊重要的作用 --> <mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom"> <!-- 配置映射的订单信息 --> <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id 就是说id要能唯一的标识出数据库中的Order表。 column:订单信息的唯 一标识 列 property:订单信息的唯 一标识 列所映射到Orders中哪个属性 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id --> <id column="id" property="id"/> <!-- 以下的几行result column就是表中的字段 property就是对应到相应pojo类中的属性--> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 配置映射的关联的用户信息 --> <!-- association:用于映射关联查询单个对象的信息 property:要将关联查询的用户信息映射到Orders中哪个属性 --> <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中 <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <!-- <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表 --> <id column="user_id" property="id"/> <!-- 接下来的result property什么的都是为了把user表中的字段能匹配到 cn.itcast.mybatis.po.User这个类的属性中 --> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrderAndOrderDetailResultMap"> <!-- 订单和用户的设置 --> <id column="id" property="id"/> <!-- 以下的几行result column就是表中的字段 property就是对应到相应pojo类中的属性--> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 配置映射的关联的用户信息 --> <!-- association:用于映射关联查询单个对象的信息 property:要将关联查询的用户信息映射到Orders中哪个属性 --> <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中 <association property="user"这里的user指的是orders类中的user属性,对应的是cn.itcast.mybatis.po.User --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <!-- <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表 --> <id column="user_id" property="id"/> <!-- 接下来的result property什么的都是为了把user表中的字段能匹配到 cn.itcast.mybatis.po.User这个类的属性中 --> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> <!-- 订单明细信息 一个订单关联查询出了多条明细,要使用collection进行映射 collection:对关联查询到多条记录映射到集合对象中 property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性 ofType:指定映射到list集合属性中pojo的类型 --> <!-- 其是要理解collection的话对比上面的association,association是一对一的映射,而collection是一对多的映射 <collection property="orderdetails" 这里的orderdetails是Orders中一个属性:private List<Orderdetail> orderdetails; ofType="cn.itcast.mybatis.po.Orderdetail"这里的 cn.itcast.mybatis.po.Orderdetail是List<Orderdetail>里面的Orderdetail类型。 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <!-- id:订单明细唯 一标识 property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性 --> <!-- 这里的<id column="orderdetail_id" property="id"/> orderdetail_id是要唯一能标识orderdetail表的字段,所以选了orderdetail的主键,为什么是orderdetail_id 而不是id呢,原因是为了避免和orders表的id造成冲突,所以取的别名。property="id"是cn.itcast.mybatis.po.Orderdetail 中的属性 --> <id column="orderdetail_id" property="id"/> <!-- 这里的result 中column都是orderdetail表中的字段,property是Orderdetail中的属性,要一一映射过去 --> <result column="items_id" property="items_id"/> <result column="items_number" property="items_num"/> <result column="orders_id" property="orders_id"/> </collection> </resultMap> <select id="findOrdersUser" resultType="cn.itcast.mybatis.po.OrdersCustom"> SELECT ORDERS.* , user.`username`, user.`sex`, user.`address` FROM orderS,USER WHERE ORDERS.`user_id`=USER.`id` </select> <select id="findOrdersUseResultMap" resultMap="OrdersUserResultMap"> SELECT ORDERS.* , user.`username`, user.`sex`, user.`address` FROM orderS,USER WHERE ORDERS.`user_id`=USER.`id` </select> <select id="findOrdersandOrderDetailResultMap" resultMap="OrderAndOrderDetailResultMap"> SELECT ORDERS.* , user.`username`, user.`sex`,user.`address`, orderdetail.`id` orderdetail_id , orderdetail.`items_id`, orderdetail.`items_num` FROM orderS,USER ,orderdetail WHERE ORDERS.`user_id`=USER.`id`AND orderdetail.`orders_id`=Orders.`id` </select> </mapper>
OrdersMapperCustom.xm写法二:
发现上面的写法有点复杂,有些代码重复了,我们可以用extends这种做法来避免写重复代码。
<?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"> <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离 注意:使用mapper代理方式,namespace有特殊重要的作用 --> <mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom"> <!-- 配置映射的订单信息 --> <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id 就是说id要能唯一的标识出数据库中的Order表。 column:订单信息的唯 一标识 列 property:订单信息的唯 一标识 列所映射到Orders中哪个属性 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id --> <id column="id" property="id"/> <!-- 以下的几行result column就是表中的字段 property就是对应到相应pojo类中的属性--> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 配置映射的关联的用户信息 --> <!-- association:用于映射关联查询单个对象的信息 property:要将关联查询的用户信息映射到Orders中哪个属性 --> <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中 <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <!-- <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表 --> <id column="user_id" property="id"/> <!-- 接下来的result property什么的都是为了把user表中的字段能匹配到 cn.itcast.mybatis.po.User这个类的属性中 --> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap>
<!-- 用extends OrdersUserResultMap 的话上面的重复代码就不用谢了 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrderAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 订单明细信息 一个订单关联查询出了多条明细,要使用collection进行映射 collection:对关联查询到多条记录映射到集合对象中 property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性 ofType:指定映射到list集合属性中pojo的类型 --> <!-- 其是要理解collection的话对比上面的association,association是一对一的映射,而collection是一对多的映射 <collection property="orderdetails" 这里的orderdetails是Orders中一个属性:private List<Orderdetail> orderdetails; ofType="cn.itcast.mybatis.po.Orderdetail"这里的 cn.itcast.mybatis.po.Orderdetail是List<Orderdetail>里面的Orderdetail类型。 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <!-- id:订单明细唯 一标识 property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性 --> <!-- 这里的<id column="orderdetail_id" property="id"/> orderdetail_id是要唯一能标识orderdetail表的字段,所以选了orderdetail的主键,为什么是orderdetail_id 而不是id呢,原因是为了避免和orders表的id造成冲突,所以取的别名。property="id"是cn.itcast.mybatis.po.Orderdetail 中的属性 --> <id column="orderdetail_id" property="id"/> <!-- 这里的result 中column都是orderdetail表中的字段,property是Orderdetail中的属性,要一一映射过去 --> <result column="items_id" property="items_id"/> <result column="items_number" property="items_num"/> <result column="orders_id" property="orders_id"/> </collection> </resultMap> <select id="findOrdersUser" resultType="cn.itcast.mybatis.po.OrdersCustom"> SELECT ORDERS.* , user.`username`, user.`sex`, user.`address` FROM orderS,USER WHERE ORDERS.`user_id`=USER.`id` </select> <select id="findOrdersUseResultMap" resultMap="OrdersUserResultMap"> SELECT ORDERS.* , user.`username`, user.`sex`, user.`address` FROM orderS,USER WHERE ORDERS.`user_id`=USER.`id` </select> <select id="findOrdersandOrderDetailResultMap" resultMap="OrderAndOrderDetailResultMap"> SELECT ORDERS.* , user.`username`, user.`sex`,user.`address`, orderdetail.`id` orderdetail_id , orderdetail.`items_id`, orderdetail.`items_num` FROM orderS,USER ,orderdetail WHERE ORDERS.`user_id`=USER.`id`AND orderdetail.`orders_id`=Orders.`id` </select> </mapper>
OrdersMapperCustom.java接口如下:
package cn.itcast.mybatis.mapper; import java.util.List; import cn.itcast.mybatis.po.Orders; import cn.itcast.mybatis.po.OrdersCustom; public interface OrdersMapperCustom { //函数的名字OrdersMapperCustom.xml中select中的id名一样 public List<OrdersCustom> findOrdersUser(); public List<Orders> findOrdersUseResultMap(); public List<Orders> findOrdersandOrderDetailResultMap(); }
Junit测试代码:
Mybatis_mappertest.java代码如下:
package cn.itcast.mybatis.test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import cn.itcast.mybatis.mapper.OrdersMapperCustom; import cn.itcast.mybatis.mapper.userMapper; import cn.itcast.mybatis.po.Orders; import cn.itcast.mybatis.po.User; import cn.itcast.mybatis.po.UserCustom; import cn.itcast.mybatis.po.UserQueryVo; public class Mybatis_mappertest { private SqlSessionFactory sqlSessionFactory; @Before public void setup() throws IOException { String resource="SqlMapConfig.xml"; InputStream inputStream= Resources.getResourceAsStream(resource); //主要是生成SqlsessionFactory。 this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testMaper() { SqlSession sqlSession=null; sqlSession=sqlSessionFactory.openSession(); //生成代理类 OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class); @SuppressWarnings("unused") //List<Orders>list=orderMapper.findOrdersUseResultMap(); List<Orders> list=orderMapper.findOrdersandOrderDetailResultMap(); } }
一对多总结:
mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。
21Mybatis_订单商品数据模型_一对多查询——resultMap方式
标签:
原文地址:http://www.cnblogs.com/shenxiaoquan/p/5786088.html