MyBatis——关联操作

来源:互联网 发布:php中split函数用法 编辑:程序博客网 时间:2024/06/01 10:01

在使用mybatis的时候,碰到了多表关联的操作,现记录下来

  1. 查询
    查询操作是遇到最多的情况,常见的是一对一,一对多,多对多

一对一的查询操作

      *准备工作        你需要两张用来测试的表,搭好的框架,环境 的配置等 ,表对应的实体类,如下,现有表typea,typeb,b表维护关系

这里写图片描述
这里写图片描述
对应的实体类,无非就是get,set方法,在Typeb需要有一个Typea类型作为属性

    public class Typeb {    private String bname;    private int bid;    private String bicon;    private Typea typea;    }    省略get,set...
public class Typea {private String name;private int id;private String img;}省略get,set...

*映射文件的配置

 <select id="selb" parameterType="int" resultMap="br">        select             b.id as bid,            b.name as bname,            b.icon as bicon,            a.id as aid,            a.name as aname,            a.img as aimg        From typeb b left outer join typea a on b.typea=a.id        where b.id=#{id}      </select>     <resultMap type="com.siyu.vo.Typeb" id="br">        <id property="bid" column="bid"/>        <result property="bname" column="bname"/>         <result property="bicon" column="bicon"/>        <association property="typea" column="typea" resultMap="ar"/>     </resultMap>       <resultMap type="com.siyu.vo.Typea" id="ar">        <id property="id" column="aid"/>        <result property="name" column="aname"/>        <result property="img" column="aimg"/>     </resultMap>

简单说明一下,这里有两种方法可以,一是嵌套查询,会有N+1的问题,至于什么是N+1,就是执行了一条SQL语句获取了结果列表(+1)。对列表每一条记录执行查询获取细节(N)。另一种就是上面这样,嵌套结果,看一下配置。
先写上联合查询,对每一条查询记录都有清晰的重命名,接下来是映射这个结果, 使用resultMap,在映射typeb时使用association来关联typea,我将typeb分离出来可以重用,但用作简单例子时,也可以简单来写。

  <resultMap type="com.siyu.vo.Typeb" id="br">         <id property="bid" column="bid"/>         <result property="bname" column="bname"/>         <result property="bicon" column="bicon"/>         <association property="typea" column="typea" javaType="com.siyu.vo.Typea">             <id property="id" column="aid"/>            <result property="name" column="aname"/>            <result property="img" column="aimg"/>         </association>       </resultMap>

这样的写法只不过是将通过id引用,写成直接嵌套,务必要加上javaType否则会抛出ReflectionException: Error instantiating null with invalid types () or values (). Cause: java.lang.NullPointerException该异常
*测试
借着SSM的框架测试一下

   @RequestMapping(value="/abc.app")public @ResponseBody Object test(){        return tyservice.find(1);//传入的参数为1} 

请求该方法后,返回结果如下
这里写图片描述
可以看到typea和typeb表中的数据都查出来了

一对多的查询

 *准备 还是用上面两个表,这次我们把typea表作为1端,typeb作为n的一端,在表中插入几条数据, 然后修改实体类,在typea中加入List<Typeb> typebs属性
 public class Typea {  private String name;  private int id;  private String img;  private List<Typeb> typebs;   省略get,set...}

*配置
仍然通过嵌套结果的方式查询,因为a表中用的是list所以配置的时候用collection,他们的作用是一样的,只是为了区分,我这边直接将两个表的映射写到一个resultMap,当然也可以分开写通过id引用

     <select id="sela" parameterType="int" resultMap="ar">        select             b.id as bid,            b.name as bname,            b.icon as bicon,            b.typea as typeas,            a.id as aid,            a.name as aname,            a.img as aimg        From typea a left outer join typeb b on a.id=b.typea        where a.id=#{id}   </select>      <resultMap type="com.siyu.vo.Typea" id="ar">          <id property="id" column="aid"/>          <result property="name" column="aname"/>          <result column="img" property="aimg"/>          <collection property="typebs" ofType="com.siyu.vo.Typeb">                <id column="bid" property="bid"/>                <result column="bname" property="bname"/>                <result column="bicon" property="bicon"/>          </collection>      </resultMap>  

简单测试一下

@RequestMapping(value="/abc.app")public @ResponseBody Object test(){        return tyabc.find(1)//传入的参数为1;}

请求的结果如下,可以看到数据都显示出来了

[{"name":"英语类","id":1,"img":null,"typebs":[{"bname":"零基础自学英语","bid":1,"bicon":"img/english_image.png"},{"bname":"商务英语","bid":2,"bicon":"img/english_image.png"}]}]
  1. 修改.删除.添加后续补上