首页 > 代码库 > 多对多
多对多
先给出需求:查询用户及用户购买商品信息。
我们由之前的文章知道,这个需求是多对多的。
还是那个终止我们的mybatis所做的不管是之前的一对一还是一对多还是多对多,都只是为了把查询出来的结果(每个字段)做好映射。
好,我们现在sqlyong上把数据查出来,然后做映射。
给出几张表的内容:
User表:
orderdetail表:
orders表:
items表:
我们根据需求(查询用户及用户购买商品信息)把sql语句写出来:
sql:
SELECT ORDERS.* ,
user.`username`,
user.`sex`,
user.`address`,
orderdetail.`id` orderdetail_id ,
orderdetail.`items_id`,
orderdetail.`items_num`,
items.`name` items_name,
items.`detail` items_detail ,
items.`price` items_price
FROM orderS,USER ,orderdetail,items
WHERE ORDERS.`user_id`=USER.`id`
AND orderdetail.`orders_id`=Orders.`id`
AND items.`id`=orderdetail.`items_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.`items_id`,
orderdetail.`items_num`,
items.`name` items_name,
items.`detail` items_detail ,
items.`price` items_price
FROM orderS,USER ,orderdetail,items
WHERE ORDERS.`user_id`=USER.`id`
AND orderdetail.`orders_id`=Orders.`id`
AND items.`id`=orderdetail.`items_id`
2.创建pojo类:
Items类:
package cn.itcast.mybatis.po; import java.util.Date; public class Items { private Integer id; private String name; private float price; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getPic() { return pic; } public void setPic(String pic) { this.pic = pic; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } private String detail; private String pic; private Date createtime; }
Orderdetail.java类:
package cn.itcast.mybatis.po; public class Orderdetail { private int id; private int orders_id; private int items_id; private int items_num; //商品(一个明细对应一个商品) private Items items; public int getItems_num() { return items_num; } public void setItems_num(int items_num) { this.items_num = items_num; } public Items getItems() { return items; } public void setItems(Items items) { this.items = items; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getOrders_id() { return orders_id; } public void setOrders_id(int orders_id) { this.orders_id = orders_id; } public int getItems_id() { return items_id; } public void setItems_id(int items_id) { this.items_id = items_id; } }
Orders.java类:
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; } }
User.java类:
package cn.itcast.mybatis.po; import java.util.Date; import java.util.List; public class User { private int id;//对应数据库中主键 private String username;//对应数据库中用户的名称 private Date birthday;//对应数据库中的生日 private String sex;//性别 private String address;//地址 //一个用户对应多个订单表 private List<Orders> ordersList; public List<Orders> getOrdersList() { return ordersList; } public void setOrdersList(List<Orders> ordersList) { this.ordersList = ordersList; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } 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; } }
3.OrdersMapperCustom.xml:
<?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"> <!-- 这个很有意思, resultMap里面套collection1,collection1里面再套collection2,collection2里面再套association--> <resultMap type="cn.itcast.mybatis.po.User" id="UserAndItemsResultMap"> <!-- 用户信息 <id 要确定User表的唯一性,user_id是来自order表中的user_id字段, property="id"表示映射到cn.itcast.mybatis.po.User中的id属性 我们做的只是再给数据库查出来的数据做映射,所以这一次的一切的依据就是查出来的表,我们要给查出来的表 的每一个字段做好映射 --> <id column="user_id" property="id"/> <!-- result是我们需要的数据 对它映射 --> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> <!-- 订单信息 一个用户对应多个订单,使用collection映射 --> <collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders"> <id column="id" property="id"/> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 订单明细 一个订单包括 多个明细 使用collection映射 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <id column="orderdetail_id" property="id"/> <result column="items_id" property="items_id"/> <result column="items_num" property="items_num"/> <result column="orders_id" property="orders_id"/> <!-- 商品信息 一个订单明细对应一个商品 使用association映射 --> <association property="items" javaType="cn.itcast.mybatis.po.Items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_detail" property="detail"/> <result column="items_price" property="price"/> </association> </collection> </collection> </resultMap> <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap"> SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.name items_name, items.detail items_detail, items.price items_price FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.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; import cn.itcast.mybatis.po.User; public interface OrdersMapperCustom { //函数的名字OrdersMapperCustom.xml中select中的id名一样 public List<OrdersCustom> findOrdersUser(); public List<Orders> findOrdersUseResultMap(); public List<Orders> findOrdersandOrderDetailResultMap(); public List<User> findUserAndItemsResultMap(); }
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); //创建包装对象,设置查询条件 //orderMapper.findOrdersUser(); @SuppressWarnings("unused") List<User> list=orderMapper.findUserAndItemsResultMap(); } }
运行结果:
多对多查询总结
将查询用户购买的商品信息明细清单,(用户名、用户地址、购买商品名称、购买商品时间、购买商品数量)
针对上边的需求就使用resultType将查询到的记录映射到一个扩展的pojo中,很简单实现明细清单的功能。
一对多是多对多的特例,如下需求:
查询用户购买的商品信息,用户和商品的关系是多对多关系。
需求1:
查询字段:用户账号、用户名称、用户性别、商品名称、商品价格(最常见)
企业开发中常见明细列表,用户购买商品明细列表,
使用resultType将上边查询列映射到pojo输出。
需求2:
查询字段:用户账号、用户名称、购买商品数量、商品明细(鼠标移上显示明细)
使用resultMap将用户购买的商品明细列表映射到user对象中。
总结:
使用resultMap是针对那些对查询结果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多个list。
多对多