`

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。
分享到:
评论

相关推荐

    mybaits一对一, 一对多,原生直接sql

    mybaits 一对一 一对多 原生 sql 配置 方法 &lt;/association&gt;

    mybatis一对一与一对多

    在实际开发中,我们常常会遇到一对一(One-to-One)和一对多(One-to-Many)的关系映射,这两种关系在数据库设计中非常常见。本篇文章将详细探讨 MyBatis 如何处理一对一和一对多的映射,以及在 Oracle 数据库中如何...

    Mybaits-one2many

    在本案例 "Mybaits-one2many" 中,我们将探讨如何实现一对多的关系查询,并且通过实践来理解这种映射关系。 首先,我们需要了解一对多关系的基本概念。在数据库设计中,如果一个表(如用户表)的某一行可以与另一个...

    mybaits 的多表查询.zip

    springboot 整和 mybaits 里边包括 一对一,一对多,多对多的多表联查 环境搭建请参考 https://blog.csdn.net/Insist___/article/details/104219471

    mybatis系列三:一对多双向关联

    在MyBatis系列的第三部分,我们将深入探讨“一对多双向关联”的概念及其实现方法。 首先,理解“一对多”关联是关键。在数据库设计中,这种关系表示一个实体(如订单)可以与多个其他实体(如订单中的商品)相关联...

    mybaits实例项目

    它可以处理复杂的结果集,包括一对一、一对多、多对多等关系映射。 6. **参数映射**: MyBatis支持两种参数映射方式:#{}和${}。#{}是预编译的,可以防止SQL注入;${}则会原样替换,通常用于动态SQL。 7. **事务...

    mybaits demo程序

    可以使用`resultMap`元素定义复杂的结果映射,包括关联的一对一、一对多、多对一关系。 5. **参数映射**: - MyBatis通过`@Param`注解或命名参数(如`#{paramName}`)来处理方法参数,支持简单类型、JavaBean和...

    mybaits springmvc注解,事务、一对多配置 oracle11g 存储过程 汉字拼音首字母

    这是一个完整的mybaits3.0+springmvc+oracle11g项目,包括sql,存储过程等,下载修改数据库连接 即可运行,包括数据增删改查,一对多查询,调用存储过程。完整的配置文件注释,绝对是入门级教材!另附有根据汉字获取...

    2018mybaits_plugin

    这里的"mybatis_plus"可能就是一种针对MyBatis的增强工具,MyBatis Plus(简称MP)是一个MyBatis的扩展插件,它对MyBatis的功能进行了轻量级的封装,简化了很多常见的数据库操作。 MyBatis Plus 主要特点包括: 1. ...

    mybatis实现多对一的实例

    在实体类和Mapper接口中,可以通过注解@One、@Many等来声明多对一或一对多的关系。 9. **测试验证**:描述中提到这个实例已经过测试,意味着所有的配置和SQL查询都是有效的,并且可以在实际项目中使用。测试通常...

    mybaits 多线程 实现数据批量插入 (运用CountDownLatch实现闭锁)

    在MyBatis中,可以通过编写动态SQL或者设置Mapper接口参数来实现分页查询,然后在多线程环境中对每一批数据进行处理。 进入主题,`多线程`与`闭锁`的运用。在Java并发编程中,`CountDownLatch`是一个同步辅助类,它...

    mybaits多个经典例子

    9. **插件机制**:MyBatis 提供了插件扩展机制,可以自定义拦截器,对 SQL 的执行过程进行拦截和修改,比如常见的 PageHelper 分页插件就是利用这一机制实现的。 通过学习并实践这些实例,你可以深入理解 MyBatis ...

    sspring +mybaits+redis

    标题 "sspring +mybaits+redis" 涉及的是一个使用Spring、MyBatis和Redis这三种技术进行整合的示例项目。这个例子旨在展示如何在Java Web开发中结合这三个流行框架来构建高效、可扩展的应用。下面将详细阐述这三者的...

    mybaits学习DEMO

    6. 一对一、一对多映射:通过`@One`和`@Many`注解,或者在XML中配置`association`和`collection`实现复杂关联查询。 7. 缓存机制:MyBatis提供了本地缓存和二级缓存,可以提高查询效率。可以通过配置启用和自定义...

    idea插件mybaits log 打印sql语句

    MyBatis是一个流行的Java持久层框架,它简化了数据库操作,而这个插件则增强了MyBatis的调试能力,尤其是在处理复杂的动态SQL和多数据源时,能够提供清晰的SQL执行日志。 在实际使用中,该插件可能会提供以下功能:...

    ext extjs4学习经典实例 guice mybaits 简单权限 (全量包)更新一

    MyBatis通过XML或注解的方式定义SQL语句,可以实现一对一、一对多、多对多等各种复杂关系的映射。同时,MyBatis还支持事务管理,使得数据库操作更加安全可靠。 这个“ext js4学习经典实例 guice mybaits 简单权限”...

    mybaits mysql

    总的来说,"mybaits mysql"的配置和使用涉及了数据库管理、Java开发环境、项目构建工具和ORM框架等多个方面。掌握这些技能对于Java后端开发人员来说是非常重要的,它们能帮助你更好地实现数据存储和业务逻辑的处理。

    spring多数据源的处理_mybatis实现跨库查询

    在大型应用中,为了提高系统的水平伸缩性,需要对数据进行切分,并且采用多个数据库实例进行管理。为了实现这种方案,我们需要在程序运行时根据当前的请求及系统状态来动态地决定将数据存储在哪个数据库实例中,以及...

    Mybatis实现多表联合查询和批量插入

    在 mapper.xml 文件中,需要配置 association 针对的是一对一、Collection 针对的是一对多关系。 ```xml ``` 4. Employees 表操作接口 在 Employees 表操作接口中,需要提供查询方法,以便在...

    mybaits分页

    - 当使用PageHelper时,避免在同一个事务中开启多个分页查询,因为这可能导致分页结果错误。 - 分页插件可能与某些特定的MyBatis特性有冲突,如动态SQL,使用时需要注意兼容性问题。 - 为了性能考虑,尽量减少OFFSET...

Global site tag (gtag.js) - Google Analytics