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

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

有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等。这些查询是如何处理的呢,这一讲就讲这个问题。我们首先创建一个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 看定义如下:
	
	
	    
	    
	    
	    
	    
	        
	        
	        	        
	    	    
	



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

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

        
        
        
        
    

		
	
	    
	    
	    	    
	    	         
	
	
	

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

好了,现在在Test 类中写测试代码:
public void getUserArticles(int userid){
    	SqlSession session = sqlSessionFactory.openSession();
    	try {
    	    IUserOperation userOperation=session.getMapper(IUserOperation.class);    	   
    	    List
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
getUserArticles(int id);

然后运行就可以测试。

整个程序下载:
点击下载此文件

====2017-7月更新==================
一个用mybatis, spring mvc, 百度 ueditor构建的简单的例子,内容算比较丰富了,有演示地址, 这里下载代码及查看演示: http://www.yihaomen.com/article/java/665.htm

上一篇: mybatis实战教程(mybatis in action)之二:以接口的方式编程
下一篇: python 命令行参数实例

Avatar

Lion 评论于: 2016-12-23

[quote=dengfeng] 引用来自 dengfeng 引用来自 doris只查到一条数据的原因是 user表和article表中主键id的名字一样的。两张表中的主键id字段名要唯一,不能都写id,不然的话,在一对多查询的时候就会出现级联出来的article项只有一条记录。
我仅仅只是把两张表的id分别改成了uid和aid,然后再修改下相应的配置文件,就查出来多条记录。
共大家参考
可以了[/quote]
这个不是解决问题的根本方法,建表的时候我们公司要求的主键必须一致,你这样是没法操作的,经查询,只需要为其中一个表的sql 的主键起一个别名,然后将映射的字段column属性改成新起的别名就可以了

Avatar

学习一下 评论于: 2016-08-16

[face08]

Avatar

dengfeng 评论于: 2016-02-12

[quote=dengfeng] 引用来自 doris只查到一条数据的原因是 user表和article表中主键id的名字一样的。两张表中的主键id字段名要唯一,不能都写id,不然的话,在一对多查询的时候就会出现级联出来的article项只有一条记录。
我仅仅只是把两张表的id分别改成了uid和aid,然后再修改下相应的配置文件,就查出来多条记录。
共大家参考
可以了[/quote]

Avatar

dengfeng 评论于: 2016-02-12

[quote=doris]只查到一条数据的原因是 user表和article表中主键id的名字一样的。两张表中的主键id字段名要唯一,不能都写id,不然的话,在一对多查询的时候就会出现级联出来的article项只有一条记录。
我仅仅只是把两张表的id分别改成了uid和aid,然后再修改下相应的配置文件,就查出来多条记录。
共大家参考[/quote]
不行啊

Avatar

numberOne 评论于: 2015-05-08

需要为Article 加别名,其他都正常[face01]

Avatar

doris 评论于: 2014-11-28

只查到一条数据的原因是 user表和article表中主键id的名字一样的。两张表中的主键id字段名要唯一,不能都写id,不然的话,在一对多查询的时候就会出现级联出来的article项只有一条记录。
我仅仅只是把两张表的id分别改成了uid和aid,然后再修改下相应的配置文件,就查出来多条记录。
共大家参考

Avatar

小强 评论于: 2014-08-19

你在Article里再插入一条userid为2的数据,看看去掉可以吗?[quote=zhumengxiaoqi] 引用来自 xixi
博主,请问
select user.id,user.userName,user.userAddress,article.id,article.title,article.content
        from user,article
        where  user.id=article.userid and user.id=1
为什么放在数据库里是正确,程序中是一条呢


去掉user.id=article.userid 就行[/quote]

Avatar

zhumengxiaoqi 评论于: 2014-07-24

[quote=xixi]博主,请问
select user.id,user.userName,user.userAddress,article.id,article.title,article.content
        from user,article
        where  user.id=article.userid and user.id=1
为什么放在数据库里是正确,程序中是一条呢[/quote]

去掉user.id=article.userid 就行

Avatar

xixi 评论于: 2013-12-27

博主,请问
select user.id,user.userName,user.userAddress,article.id,article.title,article.content
    	from user,article
    	where  user.id=article.userid and user.id=1
为什么放在数据库里是正确,程序中是一条呢

Avatar

xixi 评论于: 2013-12-27

不用去掉user.id,不是一条的

Avatar

HeHe 评论于: 2013-12-13

是的呢……[face09]
[quote=小Y]还漏了一点,要在Configuration.xml里注册那个Article类啊[/quote]

Avatar

xiaochen 评论于: 2013-12-08

select user.id,user.userName,user.userAddress,article.id
,article.title,article.content from user,article
		where
		user.id=article.userid and user.id=#{id}

为什么只打印出一条结果,我把column="aid"改成column="id", 把article.id aid改成article.id

Avatar

1234 评论于: 2013-10-12

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}

将user.id去掉,就都可以查询出来
[reply=轻舞肥羊,2013-10-13 04:48 PM]感谢指出。[/reply]

Avatar

chuyuan_china 评论于: 2013-08-08

SQL 放在数据库执行可以得到正确结果,但是用你的代码只出来一条

Avatar

345 评论于: 2013-05-22

sql语句里select 后面只写Article的字段,不写user的字段就可以都查出来了

Avatar

1234 评论于: 2013-05-22

我也是只查出来一条数据啊 怎么回事

Avatar

vigiles 评论于: 2013-04-19

博主你好!
根据你的例子做出来,我只能查到一条结果,就是id的User和Articles的第一条记录。
List
articles = userOperation.getUserArticles(userid); 这里articles.size()是1,为什么啊?

Avatar

小Y 评论于: 2013-03-22

还漏了一点,要在Configuration.xml里注册那个Article类啊
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号