一、 一对一 resultType实现
-
通过扩展类来实现:
- 复杂查询时,表单对应的po类已不能满足输出结果集的映射。所以要根据需求建立一个扩展类来作为resultType的类型。这个扩展类是一个继承实体类,然后在这个扩展类中再写入别的表的一些字段作为属性,实现连表查询的结果可以封装入一个类中。
- 步骤
- 建立扩展类
package com.Marsoft.model; public class OrdersExt extends Orders { private String username; private String address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "OrdersExt{" + "username='" + username + '\'' + ", address='" + address + '\'' + '}' + super.toString(); } }
- 编写接口中的方法
package com.Marsoft.mapper; import com.Marsoft.model.OrdersExt; public interface OrderMapper { public OrdersExt findOrderById(int id); }
- 定义一个映射文件
<?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"> <mapper namespace="com.Marsoft.mapper.OrderMapper"> <select id="findOrderById" parameterType="int" resultType="ordersExt"> SELECT o.*,u.`username`,u.`address` FROM orders o,USER u WHERE o.`user_id` = u.`id` AND o.`id` = #{id}; </select> </mapper>
- 方法实现
/** * 一对一:写个订单类的扩展 */ @Test public void test6() { OrderMapper mapper = session.getMapper(OrderMapper.class); OrdersExt ordersExt = mapper.findOrderById(3); System.out.println(ordersExt); }
- 建立扩展类
报错:
- org.apache.ibatis.binding.BindingException: Type interface com.Marsoft.mapper.OrderMapper is not known to the MapperRegistry.
- 这个报错是因为在SQLMapConfig文件中没有配置对应的mapper接口
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not fou
- 这个报错的原因是:select标签的id写错了
-
模型里有模型
- 步骤:
- 首先还是在接口中创建一个方法
public Orders findOrderById2(int id);
- 然后在配置文件中进行配置
<!--如果模型里有模型,使用resultMap--> <resultMap id="ordersRslMap" type="orders"> <!--往orders的模型里匹配数据--> <id column="id" property="id"></id> <id column="note" property="note"></id> <id column="number" property="number"></id> <id column="createtTime" property="createtTime"></id> <!--往orders的user匹配数据--> <association property="user" javaType="user"> <!--在这里,JavaType的属性值代表的是具体的某个类--> <id column="user_id" property="id"></id> <id column="username" property="username"></id> <id column="address" property="address"></id> </association> </resultMap> <select id="findOrderById2" parameterType="int" resultMap="ordersRslMap"> SELECT o.*,u.`username`,u.`address` FROM orders o,USER u WHERE o.`user_id` = u.`id` AND o.`id` = #{id}; </select>
- id标签中column属性和property属性中的值要与实体类中的属性要严格一一对应,其中包括大小写也要对应。
- 最后在测试类中进行方法的实现。
/** * 一对一:模型里有模型 */ @Test public void test7() { OrderMapper mapper = session.getMapper(OrderMapper.class); Orders order = mapper.findOrderById2(3); System.out.println(order); System.out.println(order.getUser()); }
- 首先还是在接口中创建一个方法
- 步骤:
- 注意:如果模型里有模型,那么select标签就用resultMap属性,而不是用resultType属性
二、一对多实现
- 一对多实现【模型里有集合】
- 需求:根据订单ID查找订单信息和订单明细
- 在这里出现一对多,一对多就需要在原有的类中加入集合属性,集合属性用于一对多的实现。
*步骤- 首先是在实体类中加入多对应的那个类的集合。
/*一对多数据封装*/ private List<OrderDetail> orderDetails; public List<OrderDetail> getOrderDetails() { return orderDetails; } public void setOrderDetails(List<OrderDetail> orderDetails) { this.orderDetails = orderDetails; }
- 然后在OrderMapper.xml文件中进行映射配置。
<resultMap id="orderRslMap3" type="orders"> <!--往orders模型匹配数据--> <id column="id" property="id"></id> <id column="note" property="note"></id> <id column="number" property="number"></id> <id column="createTime" property="createTime"></id> <!--往orders的user匹配数据 模型里有模型,使用association来配置--> <association property="user" javaType="user"> <id column="user_id" property="id"></id> <id column="username" property="username"></id> <id column="address" property="address"></id> </association> <!--一对多匹配:往orders的orderdetails匹配数据 注意:集合里类型使用ofType,而不JavaType--> <collection property="orderDetails" ofType="orderDetail"> <id column="detail_id" property="id"></id> <id column="items_id" property="itemsId"></id> <id column="items_num" property="itemsNum"></id> </collection> </resultMap> <select id="findOrderById3" parameterType="int" resultMap="orderRslMap3"> SELECT o.*, u.`username`, u.`address`, od.`id` detail_id, od.`items_id`, od.`items_num` FROM orders o, USER u, `orderdetail` od WHERE o.`user_id` = u.`id` AND o.`id` = od.`orders_id` AND o.`id` = #{id}; </select>
- 在一个类中不仅包含这个类本身的属性,还包括一个集合,和一个其他类作为此类的属性,所以想要将这些东西尽数装入该类中,需要resultMap标签,以及他的子标签id表和association标签,以及collection标签。
- 在对应的接口中写方法
public Orders findOrderById3(int id);
- 在测试类中实现
/** * 一对多 */ @Test public void test8 () { OrderMapper mapper = session.getMapper(OrderMapper.class); Orders order = mapper.findOrderById3(3); System.out.println(order); System.out.println(order.getUser()); System.out.println(order.getOrderDetails()); }
- 首先是在实体类中加入多对应的那个类的集合。
三、多对多的实现
- 需求:根据订单ID查找订单信息、用户信息和订单明细信息
- 在user类型的集合中有一个Orders类型的集合,在order模型中又有OrderDetail的集合,在OrderDetail里面又有Items模型,就这样一环扣一环。
- 实现步骤:
- 在接口中写方法
/** * 多对多实现 * 查询用户信息以及用户购买的商品信息 * @return */ public List<User> findUserAndOrderInfo();
- 在实体类中加入多对多所需要的各种集合和模型
- 比如:
package com.Marsoft.model; import java.util.Date; import java.util.List; public class Orders { private Integer id; private String number; private Date createTime; private String note; private User user; /*一对多数据封装*/ private List<OrderDetail> orderDetails; public List<OrderDetail> getOrderDetails() { return orderDetails; } public void setOrderDetails(List<OrderDetail> orderDetails) { this.orderDetails = orderDetails; } 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 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; } @Override public String toString() { return "Orders{" + "id=" + id + ", number='" + number + '\'' + ", createTime=" + createTime + ", note='" + note + '\'' + '}'; } }
- 比如:
- 在映射文件中写具体的SQL语句以及传出方式
<!--通过多对多实现 查询用户信息及用户购买的商品信息--> <resultMap id="userRslMap" type="user"> <!--1.匹配user属性--> <id column="id" property="id"></id> <result column="username" property="username" /> <result column="address" property="address" /> <!--2.匹配user的orderList--> <collection property="ordersList" ofType="orders"> <id column="order_id" property="id"></id> <result column="number" property="number" /> <result column="createtime" property="createTime" /> <result column="note" property="note" /> <!--3.匹配Orders里有OrderDetails--> <collection property="orderDetails" ofType="orderDetail"> <id column="detail_id" property="id"></id> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <!--4.配置订单详情的商品--> <association property="items" javaType="items"> <id column="items_id" property="id"></id> <result column="name" property="name"/> <result column="price" property="price"/> <result column="detail" property="detail"/> </association> </collection> </collection> </resultMap> <select id="findUserAndOrderInfo" resultMap="userRslMap"> SELECT u.`id`, u.`username`, u.`address`, o.`id` order_id, o.`number`, o.`createtime`, o.`note`, od.`id` detail_id, od.`items_id`, od.`items_num`, it.`name`, it.`price`, it.`detail` FROM USER u, orders o, `orderdetail` od, items it WHERE o.`user_id` = u.`id` AND o.`id` = od.`orders_id` AND od.`items_id` = it.`id`; </select>
- 在测试类中实现具体的操作。
/** * 多对多 * 查询用户和商品信息 */ @Test public void test9 () { UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.findUserAndOrderInfo(); for (User user : users) { System.out.println("用户信息:"+user); for (Orders orders : user.getOrdersList()) { System.out.println("订单信息:"+orders); System.out.println("订单详情"); for (OrderDetail od : orders.getOrderDetails()) { System.out.println(od+":"+od.getItems()); } System.out.println("-----------------------------------"); } } }
- 在接口中写方法