mybaits 一对多,一对一查询

原地址:http://blog.csdn.net/evankaka

一、创建表、分析

下面是两表,一个是顾客表,一个是车票表。一个顾客可以对应多张车票,但是一张车票只能对应一个顾客

 t_customer:顾客表,一个顾客可以对应多张车票

t_ticket:车票表,一张车票只能对应一个顾客

1、创建数据表及插入初始数据

创建数据表

  1. use test;  
  2. DROP TABLE IF EXISTS t_customer;  
  3. CREATE TABLE t_customer(  
  4. customerId INT PRIMARY KEY AUTO_INCREMENT,  
  5. customerName VARCHAR(20) NOT NULL,  
  6. customerTel INT NOT NULL  
  7. )ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  8.   
  9. DROP TABLE IF EXISTS t_ticket;  
  10. CREATE TABLE t_ticket(  
  11. ticketId INT PRIMARY KEY  AUTO_INCREMENT,  
  12. ticketAddress VARCHAR(50) NOT NULL,  
  13. ticketPrice INT NOT NULL,  
  14. ticketCId INT NOT NULL  
  15. )ENGINE=InnoDB DEFAULT CHARSET=utf8;  


插入数据:

[java] view plain copy
  1. use test;  
  2.   
  3. insert into t_customer values(1,'小王',1888327654);  
  4. insert into t_customer values(2,'天天',3456546354);  
  5. insert into t_customer values(3,'阿大',123345566);  
  6.   
  7. insert into  t_ticket values(1,'武汉到重庆',100,1);  
  8. insert into  t_ticket values(2,'北京到上海',200,1);  
  9. insert into  t_ticket values(3,'深圳到广州',50,1);  


传统的联合查询的方法

  1. select c.*,t.* from t_customer c  JOIN t_ticket t ON (c.customerId=t.ticketCId) where c.customerName ='小王';  

结果如下:

二、工程创建

1、新建Java工程,导入需要的包,最后整个工程目录 如下:

2、创建表对应的类:

Customer.java:

[java] view plain copy
  1. package com.mucfc.model;  
  2. import java.util.List;  
  3. /** 
  4.  *顾客信息类 
  5.  *@author linbingwen 
  6.  *@2015年5月13日8:30:12 
  7.  */  
  8. public class Customer {  
  9.     private Integer customerId;  
  10.     private String customerName;  
  11.     private Integer customerTel;  
  12.     private List<Ticket> tickets;//使用一个List来表示车票  
  13.   
  14.     public List<Ticket> getTickets() {  
  15.         return tickets;  
  16.     }  
  17.   
  18.     public void setTickets(List<Ticket> tickets) {  
  19.         this.tickets = tickets;  
  20.     }  
  21.   
  22.     public Integer getCustomerId() {  
  23.         return customerId;  
  24.     }  
  25.   
  26.     public void setCustomerId(Integer customerId) {  
  27.         this.customerId = customerId;  
  28.     }  
  29.   
  30.     public String getCustomerName() {  
  31.         return customerName;  
  32.     }  
  33.   
  34.     public void setCustomerName(String customerName) {  
  35.         this.customerName = customerName;  
  36.     }  
  37.   
  38.     public Integer getCustomerTel() {  
  39.         return customerTel;  
  40.     }  
  41.   
  42.     public void setCustomerTel(Integer customerTel) {  
  43.         this.customerTel = customerTel;  
  44.     }  
  45.   
  46.     @Override  
  47.     public String toString() {  
  48.         return "Customer [customerId=" + customerId + ", customerName="  
  49.                 + customerName + ", customerTel=" + customerTel+"]";  
  50.     }  
  51.   
  52.   
  53.   
  54. }  

Ticket.java:

[java] view plain copy
  1. package com.mucfc.model;  
  2. /** 
  3.  *车票信息类 
  4.  *@author linbingwen 
  5.  *@2015年5月13日8:30:12 
  6.  */  
  7. public class Ticket {  
  8.     private Integer ticketId;  
  9.     private String ticketAddress;  
  10.     private Integer ticketPrice;  
  11.     private Integer ticketCId;  
  12.     private Customer customer;//使用一个customer来表示顾客  
  13.   
  14.     public Customer getCustomer() {  
  15.         return customer;  
  16.     }  
  17.   
  18.     public void setCustomer(Customer customer) {  
  19.         this.customer = customer;  
  20.     }  
  21.   
  22.     public Integer getTicketId() {  
  23.         return ticketId;  
  24.     }  
  25.   
  26.     public void setTicketId(Integer ticketId) {  
  27.         this.ticketId = ticketId;  
  28.     }  
  29.   
  30.     public String getTicketAddress() {  
  31.         return ticketAddress;  
  32.     }  
  33.   
  34.     public void setTicketAddress(String ticketAddress) {  
  35.         this.ticketAddress = ticketAddress;  
  36.     }  
  37.   
  38.     public Integer getTicketPrice() {  
  39.         return ticketPrice;  
  40.     }  
  41.   
  42.     public void setTicketPrice(Integer ticketPrice) {  
  43.         this.ticketPrice = ticketPrice;  
  44.     }  
  45.   
  46.     public Integer getTicketCId() {  
  47.         return ticketCId;  
  48.     }  
  49.   
  50.     public void setTicketCId(Integer ticketCId) {  
  51.         this.ticketCId = ticketCId;  
  52.     }  
  53.   
  54.     @Override  
  55.     public String toString() {  
  56.         return "Ticket [ticketId=" + ticketId + ", ticketAddress="  
  57.                 + ticketAddress + ", ticketPrice=" + ticketPrice  
  58.                 + ", ticketCId=" + ticketCId + "]";  
  59.     }  
  60.   
  61.   
  62. }  

注意Customer.java:中有个list,list来存放车票,Ticket.java中有一个 customer。

3、定义sql映射文件

(1)首先是一对多关联:

MyBatis中使用collection标签来解决一对一的关联查询,collection标签可用的属性如下:

  • property:指的是集合属性的值
  • ofType:指的是集合中元素的类型
  • column:所对应的外键字段名称
  • select:使用另一个查询封装的结果
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  4. <mapper namespace="com.mucfc.model.CustomerMapper">  
  5.  <!-- 定义数据库字段与实体对象的映射关系 -->  
  6.     <resultMap type="Customer" id="customerBean">  
  7.         <id column="customerId" property="customerId"/>  
  8.         <result column="customerName" property="customerName"/>  
  9.         <result column="customerTel" property="customerTel"/>       
  10.         <!-- 一对多的关系 -->  
  11.         <!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->  
  12.         <collection property="tickets" ofType="Ticket">  
  13.             <id column="ticketId" property="ticketId"/>  
  14.             <result column="ticketAddress" property="ticketAddress"/>  
  15.             <result column="ticketPrice" property="ticketPrice"/>  
  16.             <result column="ticketCId" property="ticketCId"/>  
  17.         </collection>  
  18.     </resultMap>    
  19.       
  20.     <!-- 根据id查询Person, 关联将Orders查询出来 -->  
  21.     <select id="selectCustomerByName" parameterType="string" resultMap="customerBean">  
  22.         select c.*,t.* from t_customer c,t_ticket t  where  c.customerId=t.ticketCId and c.customerName =#{customerName};  
  23.     </select>  
  24.       
  25.  </mapper>  


(2)接着是一对一关联:

MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:

  • property:对象属性的名称
  • javaType:对象属性的类型
  • column:所对应的外键字段名称
  • select:使用另一个查询封装的结果
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  4. <mapper namespace="com.mucfc.model.TicketMapper">  
  5.     <!-- 定义数据库字段与实体对象的映射关系  -->  
  6.     <resultMap type="Ticket" id="ticketBean">  
  7.         <id column="ticketId" property="ticketId" />  
  8.         <result column="ticketAddress" property="ticketAddress" />  
  9.         <result column="ticketPrice" property="ticketPrice" />  
  10.         <result column="ticketCId" property="ticketCId" />  
  11.         <!-- 一对一的关系 -->  
  12.         <!-- property: 指的是属性的值, javaType:指的是元素的类型 -->  
  13.         <association property="customer" javaType="Customer">  
  14.             <id column="customerId" property="customerId" />  
  15.             <result column="customerName" property="customerName" />  
  16.             <result column="customerTel" property="customerTel" />  
  17.         </association>  
  18.     </resultMap>  
  19.     <!-- 根据id查询ticket, 关联将Customer查询出来 -->  
  20.     <select id="selectTicketById" parameterType="int" resultMap="ticketBean">  
  21.         select c.*,t.* from t_customer c,t_ticket t where  
  22.         c.customerId=t.ticketCId and t.ticketId =#{ticketId}  
  23.     </select>  
  24. </mapper>  


4、总配置文件

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE configuration  
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">  
  5. <!-- 这是根标签  -->  
  6. <configuration>  
  7.     <!-- 设置别名  -->  
  8.     <typeAliases>  
  9.         <typeAlias alias="Customer" type="com.mucfc.model.Customer"/>  
  10.         <typeAlias alias="Ticket" type="com.mucfc.model.Ticket" />  
  11.     </typeAliases>  
  12.       
  13.     <!-- 配置数据源相关的信息  -->  
  14.     <environments default="development">  
  15.         <environment id="development">  
  16.             <transactionManager type="JDBC" />  
  17.             <dataSource type="POOLED">  
  18.             <property name="driver" value="com.mysql.jdbc.Driver"/>  
  19.              <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>   
  20.             <property name="username" value="root"/>   
  21.             <property name="password" value="christmas258@"/>    
  22.             </dataSource>  
  23.         </environment>  
  24.     </environments>  
  25.       
  26.     <!-- 列出映射文件 -->  
  27.     <mappers>  
  28.         <mapper resource="com/mucfc/model/CustomerMapper.xml" />  
  29.         <mapper resource="com/mucfc/model/TicketMapper.xml" />   
  30.     </mappers>  
  31. </configuration>  


5、测试

[java] view plain copy
  1. package com.mucfc.test;  
  2.   
  3. import java.io.Reader;  
  4. import java.util.List;  
  5.   
  6. import org.apache.ibatis.io.Resources;  
  7. import org.apache.ibatis.session.SqlSession;  
  8. import org.apache.ibatis.session.SqlSessionFactory;  
  9. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  10.   
  11. import com.mucfc.model.Customer;  
  12. import com.mucfc.model.Ticket;  
  13.   
  14. public class Test {  
  15.     private static SqlSessionFactory sqlSessionFactory;  
  16.     private static Reader reader;  
  17.     static {  
  18.         try {  
  19.             reader = Resources.getResourceAsReader("mybatis-config.xml");  
  20.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);  
  21.         } catch (Exception e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.     }  
  25.   
  26.     /* 
  27.      * 一对一关联查询 
  28.      */  
  29.     public static void selectTicketById(int id) {  
  30.         SqlSession session = null;  
  31.         try {  
  32.             session = sqlSessionFactory.openSession();  
  33.             Ticket ticket = (Ticket) session.selectOne(  
  34.                     "com.mucfc.model.TicketMapper.selectTicketById", id);  
  35.             if (ticket == null)  
  36.                 System.out.println("null");  
  37.             else {  
  38.                 System.out.println(ticket);  
  39.                 System.out.println(ticket.getCustomer());  
  40.             }  
  41.         } finally {  
  42.             session.close();  
  43.         }  
  44.     }  
  45.   
  46.     /* 
  47.      * 一对多关联查询 
  48.      */  
  49.     public static void selectCustomerByName(String string) {  
  50.         SqlSession session = null;  
  51.         try {  
  52.             session = sqlSessionFactory.openSession();  
  53.             Customer customer = (Customer) session  
  54.                     .selectOne(  
  55.                             "com.mucfc.model.CustomerMapper.selectCustomerByName",  
  56.                             string);  
  57.             if (customer == null)  
  58.                 System.out.println("null");  
  59.             else {  
  60.                 System.out.println(customer);  
  61.                 List<Ticket> tickets = customer.getTickets();  
  62.                 for (Ticket ticket : tickets) {  
  63.                     System.out.println(ticket);  
  64.                 }  
  65.             }  
  66.         } finally {  
  67.             session.close();  
  68.         }  
  69.     }  
  70.   
  71.     public static void main(String[] args) {  
  72.         System.out.println("==============一对一查询,根据车票来查顾客===============");  
  73.         selectTicketById(1);  
  74.         System.out.println("==============多对一查询,根据顾客来查车票===============");  
  75.         selectCustomerByName("小王");  
  76.   
  77.     }  
  78.   
  79. }  


结果:

结果显示,查询正确。

三、ResultMap标签                        

          MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。在MyBatis进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,因为Map不能很好表示领域模型,我们就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用。

当Java接口与XML文件在一个相对路径下时,可以不在myBatis配置文件的mappers中声明:

[html] view plain copy
  1. <!-- 列出映射文件 -->  
  2. <mappers>  
  3.     <mapper resource="com/mucfc/model/CustomerMapper.xml" />  
  4.     <mapper resource="com/mucfc/model/TicketMapper.xml" />   
  5. </mappers>  


SQL 映射XML 文件一些初级的元素:

  1. 1. cache – 配置给定模式的缓存  
  2. 2. cache-ref – 从别的模式中引用一个缓存  
  3. 3. resultMap – 这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象  
  4. 4. sql – 一个可以被其他语句复用的SQL 块  
  5. 5. insert – 映射INSERT 语句  
  6. 6. update – 映射UPDATE 语句  
  7. 7. delete – 映射DELEETE 语句  
  8. 8. select - 映射SELECT语句  


resultMap 是MyBatis 中最重要最强大的元素了。你可以让你比使用JDBC 调用结果集省掉90%的代码,也可以让你做许多JDBC 不支持的事。现实上,要写一个等同类似于交互的映射这样的复杂语句,可能要上千行的代码。ResultMaps 的目的,就是这样简单的语句而不需要多余的结果映射,更多复杂的语句,除了只要一些绝对必须的语句描述关系以外,再也不需要其它的。
resultMap属性:type为java实体类;id为此resultMap的标识。
resultMap可以设置的映射:

  1. 1. constructor – 用来将结果反射给一个实例化好的类的构造器  
  2. a) idArg – ID 参数;将结果集标记为ID,以方便全局调用  
  3. b) arg –反射到构造器的通常结果  
  4. 2. id – ID 结果,将结果集标记为ID,以方便全局调用  
  5. 3. result – 反射到JavaBean 属性的普通结果  
  6. 4. association – 复杂类型的结合;多个结果合成的类型  
  7. a) nested result mappings – 几resultMap 自身嵌套关联,也可以引用到一个其它上  
  8. 5. collection –复杂类型集合a collection of complex types  
  9. 6. nested result mappings – resultMap 的集合,也可以引用到一个其它上  
  10. 7. discriminator – 使用一个结果值以决定使用哪个resultMap  
  11. a) case – 基本一些值的结果映射的case 情形  
  12. i. nested result mappings –一个case 情形本身就是一个结果映射,因此也可以包括一些相同的元素,也可以引用一个外部resultMap。

猜你喜欢

转载自1193355343.iteye.com/blog/2368376