有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等。这些查询是如何处理的呢,这一讲就讲这个问题。我们首先创建一个Article 这个表,并初始化数据.

 程序代码


Drop TABLE IF EXISTS `article`;

Create TABLE `article` (

  `id` int(11) NOT NULL auto_increment,

  `userid` int(11) NOT NULL,

  `title` varchar(100) NOT NULL,

  `content` text NOT NULL,

  PRIMARY KEY  (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;



-- ----------------------------

-- 添加几条测试数据

-- ----------------------------

Insert INTO `article` VALUES ('1', '1', 'test_title', 'test_content');

Insert INTO `article` VALUES ('2', '1', 'test_title_2', 'test_content_2');

Insert INTO `article` VALUES ('3', '1', 'test_title_3', 'test_content_3');

Insert INTO `article` VALUES ('4', '1', 'test_title_4', 'test_content_4');

你应该发现了,这几个文章对应的userid都是1,所以需要用户表user里面有id=1的数据。可以修改成满足自己条件的数据.按照orm的规则,表已经创建了,那么肯定需要一个对象与之对应,所以我们增加一个 Article 的class

 程序代码


package com.yihaomen.mybatis.model;



public class Article {

    

    private int id;

    private User user;

    private String title;

    private String content;

    

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    

    public User getUser() {

        return user;

    }

    public void setUser(User user) {

        this.user = user;

    }

    public String getTitle() {

        return title;

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getContent() {

        return content;

    }

    public void setContent(String content) {

        this.content = content;

    }



}


注意一下,文章的用户是怎么定义的,是直接定义的一个User对象。而不是int类型。



多对一的实现

场景:在读取某个用户发表的所有文章。当然还是需要在User.xml 里面配置 select 语句, 但重点是这个 select 的resultMap 对应什么样的数据呢。这是重点,这里要引入 association 看定义如下:

 程序代码


< !-- User 联合文章进行查询 方法之一的配置 (多对一的方式)  -->    

    <resultMap id="resultUserArticleList" type="Article">

        <id property="id" column="aid" />

        <result property="title" column="title" />

        <result property="content" column="content" />

        

        <association property="user" javaType="User">

            <id property="id" column="id" />

            <result property="userName" column="userName" />

            <result property="userAddress" column="userAddress" />            

        </association>        

    </resultMap>



< select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList">

       select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article

              where user.id=article.userid and user.id=#{id}

    </select>

这样配置之后,就可以了,将select 语句与resultMap 对应的映射结合起来看,就明白了。用association 来得到关联的用户,这是多对一的情况,因为所有的文章都是同一个用户的。



还有另外一种处理方式,可以复用我们前面已经定义好的 resultMap ,前面我们定义过一个 resultListUser ,看这第二种方法如何实现:

 程序代码


<resultMap type="User" id="resultListUser">

        <id column="id" property="id" />

        <result column="userName" property="userName" />

        <result column="userAge" property="userAge" />

        <result column="userAddress" property="userAddress" />

    </resultMap>



    <!-- User 联合文章进行查询 方法之二的配置 (多对一的方式) -->    

    <resultMap id="resultUserArticleList-2" type="Article">

        <id property="id" column="aid" />

        <result property="title" column="title" />

        <result property="content" column="content" />        

        <association property="user" javaType="User" resultMap="resultListUser" />            

    </resultMap>

    

    <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList">

       select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article

              where user.id=article.userid and user.id=#{id}

    </select>

将 association  中对应的映射独立抽取出来,可以达到复用的目的。



好了,现在在Test 类中写测试代码:

 程序代码


public void getUserArticles(int userid){

        SqlSession session = sqlSessionFactory.openSession();

        try {

            IUserOperation userOperation=session.getMapper(IUserOperation.class);          

            List<Article> articles = userOperation.getUserArticles(userid);

            for(Article article:articles){

                System.out.println(article.getTitle()+":"+article.getContent()+

                        ":作者是:"+article.getUser().getUserName()+":地址:"+

                         article.getUser().getUserAddress());

            }

        } finally {

            session.close();

        }

    }

漏掉了一点,我们一定要在 IUserOperation 接口中,加入 select 对应的id 名称相同的方法:

public List<Article> getUserArticles(int id);



然后运行就可以测试。

Mybatis学习(4)实现关联数据的查询的更多相关文章

  1. myBatis系列之四:关联数据的查询

    myBatis系列之三:增删改查是基于单表的查询,如果联表查询,返回的是复合对象,需要用association关键字来处理. 如User发表Article,每个用户可以发表多个Article,他们之间 ...

  2. mybatis 使用resultMap实现关联数据的查询(association 和collection )

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  3. MyBatis:学习笔记(3)——关联查询

    MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统, ...

  4. mybatis实战教程(mybatis in action)之四:实现关联数据的查询

    有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等.这些查询是如何处理的呢,这一讲就讲这个问题.我们首先创建一个Article 这个表 ...

  5. 4. mybatis实战教程(mybatis in action)之四:实现关联数据的查询

    转自:https://www.cnblogs.com/shanheyongmu/p/5653599.html 有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如 ...

  6. mybatis实战教程(mybatis in action)之四:实现关联数据的查询

    有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等.这些查询是如何处理的呢,这一讲就讲这个问题.我们首先创建一个Article 这个表 ...

  7. hibernate的基础学习--多表关联数据查询

    Hibernate共提供4种多表关联数据查询方式 OID数据查询+OGN数据查询方式 HQL数据查询方式 QBC数据查询方式 本地SQL查询方式(hibernate很少用) 1.OID数据查询+OGN ...

  8. MYSQL数据库学习十 单表数据记录查询

    10.1 简单数据记录查询 SELECT field1,field2,...fieldn FROM table_name; “*” ——查询所有记录 SELECT * FROM table_name; ...

  9. MyBatis学习总结——实现关联表查询(转)

    原文链接:孤傲苍狼 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关 ...

随机推荐

  1. scala :: , +:, :+ , ::: , ++ 的区别

    4 种操作符的区别和联系 :: 该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表.用法为 x::list,其中x为加入到头部的元素,无论x是列表与否,它都只将成为新生成列表的第一个元 ...

  2. Modbus RTU CRC校验码计算方法

    在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算. CRC计算方法是: 1.  加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器. 2.   ...

  3. 在fragment的onViewCreated里observe livedata的变化的原因

    Fragment.onViewCreated()是在Fragment.onCreateView()函数之后调用的,调用到它时 表明fragment视图层级结构已创建完毕.在onViewCreated( ...

  4. 如何优雅的做参数校验-JSR330

    前言: 本文不是讲@Validate.@Valid是如何使用的.区别是什么,想看这些内容的请换篇文章. 背景: 当前端传过来的参数是进行对称性加密.base64加密等处理后过的参数时,在control ...

  5. 本地软件仓库配置及NFS安装

    [root@localhost ~]# mount /dev/cdrom /mnt mount: /dev/sr0 is write-protected, mounting read-only [ro ...

  6. Wide & Deep的OneFlow网络训练

    Wide & Deep的OneFlow网络训练 HugeCTR是英伟达提供的一种高效的GPU框架,专为点击率(CTR)估计训练而设计. OneFlow对标HugeCTR搭建了Wide & ...

  7. MindSpore基准性能

    MindSpore基准性能 本文介绍MindSpore的基准性能.MindSpore网络定义可参考Model Zoo. 训练性能 ResNet 以上数据基于华为云AI开发平台ModelArts测试获得 ...

  8. Numba实时变量分析

    Numba实时变量分析 Numba使用引用计数进行垃圾回收,这是一种需要编译器配合的技术.Numba IR对必须插入decref的位置进行编码.这些位置通过实时变量分析确定.相应的源代码是https: ...

  9. 从PyTorch到ONNX的端到端AlexNet

    从PyTorch到ONNX的端到端AlexNet 这是一个简单的脚本,可将Torchvision中定义的经过预训练的AlexNet导出到ONNX中.运行一轮推理Inference,然后将生成的跟踪模型 ...

  10. CUDA 7 Stream流简化并发性

    CUDA 7 Stream流简化并发性 异构计算是指高效地使用系统中的所有处理器,包括 CPU 和 GPU .为此,应用程序必须在多个处理器上并发执行函数. CUDA 应用程序通过在 streams  ...