Mybatis 示例之 Association

Posted isea533

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis 示例之 Association相关的知识,希望对你有一定的参考价值。

接下来的文章中,关于Mybatis的示例,全部来自于Mybatis代码中的单元测试代码,通过这些代码能够学习Mybatis中很有用的知识,这些内容在doc文档中可能只是简单提到了,或者有一些文字说明,通过这些单元测试能更直观的了解如何在Mybatis使用这些内容。


这一节内容为Association关联的结果查询,就是在查询出结果后,根据查询的列和resultMap定义的对应关系,来创建对象并写入值。


  • association – 一个复杂的类型关联;许多结果将包成这种类型
    • 嵌入结果映射 – 结果映射自身的关联,或者参考一个

(注:“参考一个”,这里参考一个是通过对象的Key来唯一确定的,如果Key值一样,就直接用已经存在的这个对象。)


association是resultMap中的一个配置选项,下面是用到的类的UML图:



Car对象中包含了Engine和Brakes两个对象。Mapper是接口对象。AssociationTest是该测试对象。


SQL表结构和数据:

drop table cars if exists;

create table cars (
  carid integer,
  cartype varchar(20),
  enginetype varchar(20),
  enginecylinders integer,
  brakestype varchar(20)
);

insert into cars (carid, cartype, enginetype, enginecylinders, brakestype) values(1, 'VW',   'Diesel', 4,    null);
insert into cars (carid, cartype, enginetype, enginecylinders, brakestype) values(2, 'Opel',    null,    null, 'drum');
insert into cars (carid, cartype, enginetype, enginecylinders, brakestype) values(3, 'Audi', 'Diesel', 4,    'disk');
insert into cars (carid, cartype, enginetype, enginecylinders, brakestype) values(4, 'Ford', 'Gas',    8,    'drum');

Mapper.xml文件:

<mapper namespace="org.apache.ibatis.submitted.associationtest.Mapper">

    <resultMap type="org.apache.ibatis.submitted.associationtest.Car" id="carResult">
        <id column="carid" property="id"/>
        <result column="cartype" property="type"/>
        <association property="engine" resultMap="engineResult"/>
        <association property="brakes" resultMap="brakesResult"/>
    </resultMap>
    <resultMap type="org.apache.ibatis.submitted.associationtest.Engine" id="engineResult">
        <result column="enginetype" property="type"/>
        <result column="enginecylinders" property="cylinders"/>
    </resultMap>
    <resultMap type="org.apache.ibatis.submitted.associationtest.Brakes" id="brakesResult">
        <result column="brakesType" property="type"/>
    </resultMap>

    <select id="getCars" resultMap="carResult">
    select * from cars
  </select>

    <select id="getCarsNonUnique" resultMap="carResult">
    select 1 as carid, cartype, enginetype, enginecylinders, brakestype from cars
  </select>

    <select id="getCars2" resultMap="carResult">
    select 1 as carid, cartype, enginetype, enginecylinders, brakestype from cars where carid in (1,2)
  </select>

</mapper>


其中的一个测试用例:

 @Test
  public void shouldGetAllCars() 
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try 
      Mapper mapper = sqlSession.getMapper(Mapper.class);
      List<Car> cars = mapper.getCars();
      Assert.assertEquals(4, cars.size());
      Assert.assertEquals("VW", cars.get(0).getType());
      Assert.assertNotNull(cars.get(0).getEngine());
      Assert.assertNull(cars.get(0).getBrakes());
      Assert.assertEquals("Opel", cars.get(1).getType());
      Assert.assertNull(cars.get(1).getEngine());
      Assert.assertNotNull(cars.get(1).getBrakes());
     finally 
      sqlSession.close();
    
  

cars返回值:



association是嵌套查询中最简单的一种情况,像上述例子中,一般我们都会用一个Car对面包含所有的属性,这里的例子使用了嵌套对象,使对像的结构更鲜明。不过一般情况下很少会拆分一个对象为多个,用的多的时候是多表查询的嵌套。


上面XML中的
carResult和engieResult,brakesResult都是分别定义,carResult引用了另外两个resultMap。
对于不需要重用嵌套对象的情况,还可以直接这么写,把上面的XML修改后:

    <resultMap type="org.apache.ibatis.submitted.associationtest.Car" id="carResult">
        <id column="carid" property="id"/>
        <result column="cartype" property="type"/>
        <association property="engine" javaType="org.apache.ibatis.submitted.associationtest.Engine">
            <result column="enginetype" property="type"/>
            <result column="enginecylinders" property="cylinders"/>
        </association>
        <association property="brakes" resultMap="brakesResult"/>
    </resultMap>
为了对比和区分,这里指修改了Engine,在association元素上增加了属性javaType,元素内增加了result映射。

如果有association方面问题可以参考(或在此留言):

http://mybatis.github.io/mybatis-3/zh/sqlmap-xml.html

本节源码请看官方git:

https://github.com/mybatis/mybatis-3/tree/master/src/test/java/org/apache/ibatis/submitted/associationtest

以上是关于Mybatis 示例之 Association的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis之ResultMap的association和collection标签详解(图文例子)

[mybatis]映射文件_select_resultMap_关联查询_association分步查询&延迟加载

mybatis 一对一关联 association 返回空值

mybatis 关联查询 association

MyBatis关联查询 (association) 时遇到的某些问题/mybatis映射

mybatis 查询一对多 集合中没有值为啥