前言
当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射。对于SSM的Mybatis来说,肯定也是差不多的。既然开了头了,我们就也来简单说一些Mybatis的高级映射。当然说到这些东西的时候,最简单也最常用的就是级联查询,所以我们就以几个简单的级联查询为例,分别说一下Mybatis的一对一、一对多、多对多查询。
一.一对一映射
1.需求
电商类做买卖,用户提交订单后,某宝根据订单信息和客户的姓名、地址派送,现在查询所有的订单信息,关联查询下但用户信息。
确定执行的sql语句为:
SELECT orders.*,user.username,userss.address FROM orders,user WHEREorders.user_id = user.id
2.resultType方式解决这个问题
(1)定义po类
public class OrdersCustom extends Orders { //OrdersCustom类继承Orders类后OrdersCustom类包括了Orders类的所有字段,只需要定义用户的信息字段即可。 private String username;// 用户名称 private String address;// 用户地址 public String getUsername(){ return username; } public String setUsername(String username){ this.username=username; } …… }
(2)Mapper映射文件
(3)定义mapper接口
public ListfindOrdersList() throws Exception;
(4)测试
public void testfindOrdersList()throws Exception{ //获取session SqlSession session = sqlSessionFactory.openSession(); //获限mapper接口实例 UserMapper userMapper = session.getMapper(UserMapper.class); //查询订单信息 Listlist =userMapper.findOrdersList(); System.out.println(list); //关闭session session.close(); }
3.使用resultMap解决这个问题
(1)定义resultMap
(2)调用resultMap
(3)定义mapper接口
4.一对一查询总结
个人认为啊,这种情况下使用resultType定义输出映射相对简单,因为这样只需要去添加一个po类就行了,按需求添加额外需要的属性,就可以完成映射。而相对于resultType来说,resultMap就显得稍微麻烦一些了,他需要特别定义resultMap来映射相关联表的实体属性。
二.一对多查询
1.需求
继上面的需求,查询所有订单信息及订单下的订单明细信息(一个订单信息下面或有很多商品,这个女生买护肤品的时候应该很有感触吧。所以订单信息与订单明细是一对多的关系)
(1)确定在数据库执行的sql语句
select orders.*, user.username, user.address,orderdetail.idorderdetail_id,orderdetail.items_id, orderdetail.items_num FROM orders,user,orderdetail WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id
执行结果:
public class Orders{ private Integer id; private Integer userId; private String number; private Date createtime; private String note; private User user; private ListorderDetails; //getter、setter }
(3)定义resultMap
大家可以跟上面对比一下,这两个resultMap除了对订单详细的映射定义外,其他的是完全一样的,现在问题来了,我们需要重新定义上面重复的映射信息吗?答案是不用,resultMap具有可继承特性,我们只需要继承上面的resultMap(userordermap),然后只定义别的就可以了,如下:
使用extends来继承订单信息resultmap:userordermap
(4)实现调用
(5)定义mapper接口
publicListfindOrdersDetailList () throws Exception;
(6)来测试一下
public void testfindOrdersDetailList()throws Exception{ //获取session SqlSession session = sqlSessionFactory.openSession(); //获限mapper接口实例 UserMapper userMapper =session.getMapper(UserMapper.class); //查询订单信息 Listlist =userMapper.findOrdersDetailList(); System.out.println(list); //关闭session session.close(); }
这个吧,图没有了,可是可以给大家形容一下,就是返回结果只有四个订单信息,然后每个订单信息里面有两个商品信息list压到这里面。就这样,我们就实现了一对多的查询,为什么这个例子我们不用resultType来执行,其实结果早就给大家了,上面执行sql的结果图,就是返回的信息列表,实际上只有四个订单信息,但是使用resultType会返回8条信息,也就是没有完成去重,还需要我们去手动去重,了然了吗?不是很方便。
三.多对多查询
(1)需求
查询用户购买的商品信息(一个用户可以有N个订单信息,每个订单信息可以有M个商品信息,所以我们需要查询所有的用户信息,关联查询订单及订单明细信息,订单名信息中关联查询商品信息)
(2)确定要执行的sql
SELECT orders.*, USER.username, USER.address, orderdetail.idorderdetail_id, orderdetail.items_id, orderdetail.items_num, items.nameitems_name, items.detailitems_detail FROM orders, USER, orderdetail, items WHERE orders.user_id= USER .id AND orders.id = orderdetail.orders_id ANDorderdetail.items_id = items.id
(3)po类变化
在User中添加List
(4)定义resultMap
(5)调用resultMap
到这里,相信大家能看出点端倪来了吧,我们一直都是用
(6)然后定义mapper接口
public interface UserMapper { ListfindUserItemResultMap() throws Exception; }
结果,就请大家自己去动手实验一下吧!
四.小结
到此,我们的Mybatis高级映射之一对一,一对多,多对多映射就分享完了,期间自己又有点收获,总结一下:
1.resultType:将查询结果按照sql列名pojo属性名一致性映射到pojo中。常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
2.resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。其中association见关联查询信息映射到一个pojo对象中,collection将关联查询信息映射到一个list集合中然而,使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。那就要看我们自己的判断力了。
文章来源:http://blog.csdn.net/liweizhong193516/article/details/53688995#