mybatis的一对多(转)

一 建表,提供初始数据。

表说明:t_customer为客户信息表;t_orders为订单表。一个客户可以有多个订单,一个订单只属于一个客户。多方使用外键(t_orders表的customer_id)来约束。这里并没有建立强制的外键约束,做更新,删除操作时会很麻烦。

Sql代码   收藏代码
  1. CREATE TABLE `t_customer` (  
  2.   `id` int(10) NOT NULL AUTO_INCREMENT,  
  3.   `namevarchar(30) NOT NULL,  
  4.   `cell_phone` varchar(30) NOT NULL,  
  5.   PRIMARY KEY (`id`)  
  6. );  
  7. INSERT INTO `t_customer` VALUES ('1''bing''652346543');  
  8. INSERT INTO `t_customer` VALUES ('2''jade''76345');  
  9.   
  10. CREATE TABLE `t_orders` (  
  11.   `id` int(10) NOT NULL AUTO_INCREMENT,  
  12.   `number` varchar(40) NOT NULL,  
  13.   `address` varchar(40) NOT NULL,  
  14.   `customer_id` int(10) NOT NULL,  
  15.   PRIMARY KEY (`id`)  
  16. );  
  17. INSERT INTO `t_orders` VALUES ('1''GASDF235''北京朝阳''1');  
  18. INSERT INTO `t_orders` VALUES ('2''JHGFVSD34''河南郑州''1');  
  19. INSERT INTO `t_orders` VALUES ('3''KJHGFDC234''北京海淀''2');  

 表模型如下

二 实体类

  Customer

Java代码   收藏代码
  1. package com.alex.app.entity;  
  2.   
  3. import java.util.List;  
  4.   
  5. /** 
  6.  * 客户信息 
  7.  * @author leileiyuan 
  8.  * 
  9.  */  
  10. public class Customer {  
  11.     private Integer id;  
  12.     private String name;  
  13.     private String cellPhone;  
  14.       
  15.     //一对多  
  16.     private List<Orders> orders;  
  17.       
  18.     public List<Orders> getOrders() {  
  19.         return orders;  
  20.     }  
  21.     public void setOrders(List<Orders> orders) {  
  22.         this.orders = orders;  
  23.     }  
  24.     // 略 getter setter方法  
  25.     @Override  
  26.     public String toString() {  
  27.         return "Customer [id=" + id + ", name=" + name + ", cellPhone=" + cellPhone + "]";  
  28.     }  
  29.       
  30. }  

 Orders

Java代码   收藏代码
  1. package com.alex.app.entity;  
  2.   
  3. /** 
  4.  * 客户订单信息 
  5.  * @author leileiyuan 
  6.  * 
  7.  */  
  8. public class Orders {  
  9.     private Integer id;  
  10.     private String number;  
  11.     private String address;  
  12.       
  13.     // 多对一  
  14.     private Customer customer;  
  15.       
  16.     public Customer getCustomer() {  
  17.         return customer;  
  18.     }  
  19.     public void setCustomer(Customer customer) {  
  20.         this.customer = customer;  
  21.     }  
  22.     //  略 getter setter方法  
  23.     @Override  
  24.     public String toString() {  
  25.         return "Orders [id=" + id + ", number=" + number + ", address=" + address + ", customer="  
  26.                 + customer + "]";  
  27.     }  
  28.   
  29. }  

  

三 多对一映射

1)问题简单分析

从orders 到 customer 多对一的关联关联。

就是说 我们要查询orders的信息,然后经该orders可以导航到它对应的customer

扫描二维码关注公众号,回复: 263355 查看本文章

考虑这个sql

Sql代码   收藏代码
  1. select o.*, c.* from t_orders o  
  2.   join t_customer c  
  3.     on o.customer_id = c.id  
  4.  where o.id = 2  

 查询是没有问题的
  
 映射文件配置时可以。

Xml代码   收藏代码
  1. <select id="selectById" parameterType="int" resultMap="???????">  
  2.     select  
  3.            c.id           cid,  
  4.            c.name         name,  
  5.            c.cell_phone   cellPhone,  
  6.            o.id           oid,  
  7.            o.number       number,  
  8.            o.address      address   
  9.       from t_orders o  
  10.       join t_customer c  
  11.         on o.customer_id = c.id  
  12.      where o.id = #{id}  
  13. </select>  

  因为我们查询的结果集中包含的是orders和customer的所有列,所以返回的结果集应该使用resultMap而不是resultType(也可以也写一个VO,来封装结果中的列,那么就可以使用resultType指向那个VO)。

 2)映射结果集

我们来写个resultMap 来封装这个复杂结果集
Orders.xml的映射文件如下。t_orders和t_customer的id列,要使用别名来区分

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <mapper namespace="com.alex.app.dao.OrdersDao">  
  6.     <resultMap type="Orders" id="OrdersResultMap">  
  7.         <id property="id" column="oid"/>  
  8.         <result property="number" column="number"/>  
  9.         <result property="address" column="address"/>  
  10.     </resultMap>  
  11.     <select id="selectById" parameterType="int" resultMap="OrdersResultMap">  
  12.         select  
  13.                c.id           cid,  
  14.                c.name         name,  
  15.                c.cell_phone   cellPhone,  
  16.                o.id           oid,  
  17.                o.number       number,  
  18.                o.address      address   
  19.           from t_orders o  
  20.           join t_customer c  
  21.             on o.customer_id = c.id  
  22.          where o.id = #{id}  
  23.     </select>  
  24. </mapper>  

 定义了一个resultMap,id为OrdersResultMap,查询的结果集指向这个resultMap。

来测试下

Java代码   收藏代码
  1. @Test  
  2. public void test() {  
  3.     SqlSession session = null;  
  4.     try {  
  5.         session = MyBatisUtil.openSession();  
  6.         OrdersDao ordersDao = session.getMapper(OrdersDao.class);  
  7.         Orders orders = ordersDao.selectById(1);  
  8.         System.out.println(orders);  
  9.     } catch (Exception e) {  
  10.         e.printStackTrace();  
  11.         session.rollback();  
  12.     }finally{  
  13.         MyBatisUtil.coloseSession(session);  
  14.     }  
  15. }  

 结果如下

Html代码   收藏代码
  1. Orders [id=1number=GASDF235address=北京朝阳, customer=null]  

  customer为null。

 

 3)表达关联关系

我们还需要把orders到customer多对一,这个一方,也表示在resultMap里。使用association 标签。

t_orders和t_customer的id列,要使用别名来区分

Xml代码   收藏代码
  1. <resultMap type="Orders" id="OrdersResultMap">  
  2.     <id property="id" column="oid"/>  
  3.     <result property="number" column="number"/>  
  4.     <result property="address" column="address"/>  
  5.     <association property="customer" javaType="Customer">  
  6.         <id property="id" column="cid"/>  
  7.         <result property="name" column="name"/>  
  8.         <result property="cellPhone" column="cell_phone"/>  
  9.     </association>  
  10. </resultMap>  

 

 association解释

属性:property,当然是Orders实体中定义的属性名customer;

          javaType,是customer所要映射成那个Java对象,这可以使用别名

子标签:

         id,表示主键,property是实体类的属性名,column是对应表的字段列名

         result,表示普通属性

4)再运行上面的测试代码,得到结果

Html代码   收藏代码
  1. Orders [id=1number=GASDF235address=北京朝阳, customer=Customer [id=1name=bingcellPhone=nullorders=null]]  

 看到我们已经关联上了,也返回了正确的结果。

5)Orders.xml完整内容。t_orders和t_customer的id列,要使用别名来区分

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <mapper namespace="com.alex.app.dao.OrdersDao">  
  6.     <resultMap type="Orders" id="OrdersResultMap">  
  7.         <id property="id" column="oid"/>  
  8.         <result property="number" column="number"/>  
  9.         <result property="address" column="address"/>  
  10.         <association property="customer" javaType="Customer">  
  11.             <id property="id" column="cid"/>  
  12.             <result property="name" column="name"/>  
  13.             <result property="cellPhone" column="cell_phone"/>  
  14.         </association>  
  15.     </resultMap>  
  16.     <select id="selectById" parameterType="int" resultMap="OrdersResultMap">  
  17.         select  
  18.                c.id           cid,  
  19.                c.name         name,  
  20.                c.cell_phone   cellPhone,  
  21.                o.id           oid,  
  22.                o.number       number,  
  23.                o.address      address   
  24.           from t_orders o  
  25.           join t_customer c  
  26.             on o.customer_id = c.id  
  27.          where o.id = #{id}  
  28.     </select>  
  29. </mapper>  

 四  一对多关联映射

从customer到orders一对多的关联关系。一个客户对多个订单信息

1)问题分析

  考虑这个sql

Sql代码   收藏代码
  1. select c.*, o.* from t_customer c  
  2.   join t_orders o  
  3.     on c.id = o.customer_id  
  4.  where c.id = 1  

  查询结果bing这个客户拥有两个订单
  
 2)映射结果集

映射文件的sql

Xml代码   收藏代码
  1. <select id="selectById" parameterType="int" resultMap="CustomerResultMap">  
  2.     select  
  3.           c.id          cid,  
  4.           c.name        name,  
  5.           c.cell_phone  cellPhone,  
  6.           o.id          oid,  
  7.           o.number      number,  
  8.           o.address     address  
  9.      from t_customer c, t_orders o  
  10.     where c.id = o.customer_id   
  11.     and   c.id = #{id}  
  12. </select>  

3)一对多关联

上面我们需要提供一个resultMap="CustomerResultMap"。t_orders和t_customer的id列,要使用别名来区分

Xml代码   收藏代码
  1. <resultMap type="Customer" id="CustomerResultMap">  
  2.     <id property="id" column="cid" />  
  3.     <result property="name" column="name" />  
  4.     <collection property="orders" javaType="ArrayList" ofType="Orders">  
  5.         <id property="id" column="oid" />  
  6.         <result property="number" column="number" />  
  7.     </collection>  
  8. </resultMap>  

  一对多关联,多的一方使用collection表示

collection 属性 解释:

      property,是实体类中的属性orders;

      javaType,这里的JavaType代表的是实体类中的属性orders的类型是ArrayList

Java代码   收藏代码
  1. //一对多  
  2. private List<Orders> orders;  

     ofType,是集合中的放置的内容的类型,这里集合放的东西是Orders对象

  4)测试下

Java代码   收藏代码
  1. @Test  
  2. public void testSelectCustomer() {  
  3.     SqlSession session = null;  
  4.     try {  
  5.         session = MyBatisUtil.openSession();  
  6.         CustomerDao customerDao = session.getMapper(CustomerDao.class);  
  7.         Customer customer = customerDao.selectById(1);  
  8.         System.out.println(customer);  
  9.         List<Orders> orders = customer.getOrders();  
  10.         System.out.println(orders);  
  11.     } catch (Exception e) {  
  12.         e.printStackTrace();  
  13.     }finally{  
  14.         MyBatisUtil.coloseSession(session);  
  15.     }  
  16. }  

 结果

Html代码   收藏代码
  1. DEBUG 2015-05-10 08:59:28,640 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select c.id cid, c.name name, c.cell_phone cellPhone, o.id oid, o.number number, o.address address from t_customer c, t_orders o where c.id = o.customer_id and c.id = ?   
  2. DEBUG 2015-05-10 08:59:28,687 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1(Integer)  
  3. DEBUG 2015-05-10 08:59:28,718 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 2  
  4. Customer [id=1name=bingcellPhone=nullorders=[Orders [id=1number=GASDF235address=nullcustomer=null], Orders [id=2number=JHGFVSD34address=nullcustomer=null]]]  
  5. [Orders [id=1number=GASDF235address=nullcustomer=null], Orders [id=2number=JHGFVSD34address=nullcustomer=null]]  

5)Customer.xml完整内容。t_orders和t_customer的id列,要使用别名来区

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <mapper namespace="com.alex.app.dao.CustomerDao">  
  6.     <resultMap type="Customer" id="CustomerResultMap">  
  7.         <id property="id" column="cid" />  
  8.         <result property="name" column="name" />  
  9.         <collection property="orders" javaType="ArrayList" ofType="Orders">  
  10.             <id property="id" column="oid" />  
  11.             <result property="number" column="number" />  
  12.         </collection>  
  13.     </resultMap>  
  14.     <select id="selectById" parameterType="int" resultMap="CustomerResultMap">  
  15.         select  
  16.               c.id          cid,  
  17.               c.name        name,  
  18.               c.cell_phone  cellPhone,  
  19.               o.id          oid,  
  20.               o.number      number,  
  21.               o.address     address  
  22.          from t_customer c, t_orders o  
  23.         where c.id = o.customer_id   
  24.         and   c.id = #{id}  
  25.     </select>  
  26.   
  27. </mapper>  

猜你喜欢

转载自zzuwangkun.iteye.com/blog/2351257