1. 程式人生 > >mybatis ---- 級聯查詢 一對多 (集合對映)

mybatis ---- 級聯查詢 一對多 (集合對映)

關聯有巢狀查詢和巢狀結果兩種方式,本文是按照巢狀結果這種方式來說明的

上一章介紹了多對一的關係,用到了<association></association>,這是一個複雜型別的關聯。我們選擇一個示例來回顧下,比如:一個部落格有一個使用者,關聯對映就工作於這種結果之上。首先看下,我們在本文中要用到的表結構欄位:

部落格
blog :  id  title  author_id 

作者
author:  id  username password email  bio favourite_section

文章
post :id  blog_id  author_id  created_on  section  subject  draft  body  

評論
comment : id   post_id  name  comment  

標籤
T : id name 
我們把一個部落格和一個使用者關聯在一起,就像:
   <select id="selectBlog" parameterType="int" resultMap="blogResult">
              select 
                  b.id as blog_id,
                  b.title as blog_title,
                  b.author_id as blog_author_id
                  a.id as author_id,
                  a.username as author_username,
                  a.password as author_passowrd,
                  a.email as auhtor_email,
                  a.bio as author_bio
               from  blog b left outer join author a on b.author_id=a.id
                    where b.id=#{id}
       </select>

注意這個聯合查詢,以及所有結果被唯一而清晰的名字而重新命名。這使得對映非常簡單。現在我們可以對映這個結果:

<resultMap id="blogResult" type="Blog">
     <id property="id" column="blog_id"/>
      <result property="title" column="blog_title"/>
      
      <!-- 和一個使用者關聯,Blog 類裡面屬性時author,關聯的列是原先的blog.author_id-->
      <association property="author"  column="blog_author_id" javaType="Author"  resultMap="authorResult"/>
</resultMap>

<resultMap id="authorResult" type="Author">
          <id property="id" column="author_id"/>
          <result property="username" column="author_username"/>
          <result property="password" column="author_password"/>
          <result property="email" column="author_email"/>
          <result property="bio" column="author_bio"/>
</resultMap>

在上面的例子中,你可以看到部落格的作者關聯authorResult 結果對映來載入作者例項。  上面的例項中,用了外部的結果對映元素來對映關聯。這使得Author結果對映可以重用。然而,你不需要重用它的話,或者你僅僅引用你所有的結果對映到一個單獨描述的結果對映中。你可以巢狀結果對映。這裡給出使用這種方式的相同示例:
<resultMap id="blogResult" type="Blog">
     <id property="id" column="blog_id"/>
      <result property="title" column="blog_title"/>
      
      <!-- 和一個使用者關聯,Blog 類裡面屬性時author,關聯的列是原先的blog.author_id-->
      <association property="author"  column="blog_author_id" javaType="Author" >
	          <id property="id" column="author_id"/>
	          <result property="username" column="author_username"/>
	          <result property="password" column="author_password"/>
	          <result property="email" column="author_email"/>
	          <result property="bio" column="author_bio"/>
      </association>
</resultMap>

上面你已經看到了如何處理有一個型別的關聯.但是“有很多個”是怎樣的呢?,也就是集合型別,本文的主要工作是來說這個的

集合

相對於關聯來說,集合對映多了一個屬性”ofType“.這個屬性用來區分JavaBean(或欄位)屬性型別集合包含的型別來說是很重要的. ,ofType用來表示集合包含型別。
     <collection property="posts"  ofType="Post">
            <id property="id" column="post_id"/>
            <result property="subject" column="post_subject"/>
            <result property="body" column="post_body"/>
      </collection>
集合元素的作用和關聯幾乎是相同的。我們來繼續上面的示例,一個部落格只有一個作者。但是部落格有很多文章,在部落格類中,這可以由下面的寫法來表示:
private List<Post> posts; 
這一次聯合部落格表和文章表(一個blog_id可以對應很多的文章)SQL如下:
<select id="selectBlog" parameterType="int" resultMap="blogResult">
         select 
             b.id as blog_id ,
             b.title as blog_title,
             b.author_id as blog_author_id,
             p.id as post_id,
             p.subject as post_subject,
             p.body as post_body
           from blog b
               left outer join  post p on b.id=p.blog_id
               where b.id=#{id}  
</select>
現在用“文章對映集合”來對映 “部落格“,可以簡單寫為:
<resultMap id="blogResult" type="Blog">
    <id property="id" column="blog_id"/>
    <result property="title" column="blog_title"/>
    <collection property="posts" ofType="Post">
        <id property="id" column="post_id"/>
        <result property="subject" column="post_subject"/>
        <result property="body" column="post_body"/>
    </collection>
</resultMap>
高階關聯和集合對映還有很多要琢磨的地方。就讓面介紹的集合對映,稍微的整理下(一個部落格下面,有很多文章). 首先建立下,需要用到的表格,以及向其中插入一些資料. 
create table author(id int (11) not null auto_increment,
                    username varchar(20) not null,
                    password varchar(20) not null, 
                    email varchar(20) not null,
                    bio varchar(20) not null,
                    favourite_section varchar(20) not null,
                     primary key(id)
                  )ENGINE=InnoDB DEFAULT CHARSET=utf8;
                  

insert into author(id,username,password,email,bio,favourite_section) 
values(1001,'林楓','123456','[email protected]','合肥的小男孩','旅遊');

        
        
create table blog (id int (11) not null auto_increment,
                    title varchar(20) not null,
                     author_id int(11) not null,
                      primary key(id))
                     ENGINE=InnoDB DEFAULT CHARSET=utf8;  
 
 insert into blog(id,title,author_id) values(1,'小說部落格',1001);                    
                     
create table post(id int (11) not null auto_increment,
                  blog_id int(11) not null,
                  author_id int(11) not null,
                  created_on date not null,
                  section varchar(20) not null,
                  subject varchar(20) not null,
                  draft varchar(20) not null,
                  body varchar(20) not null,
                   primary key(id)
                    )ENGINE=InnoDB DEFAULT CHARSET=utf8;       
                    
                    
insert into post(id,blog_id,author_id,created_on,section,subject,draft,body)
values(1,1,1001,now(),'旅遊','玄幻','草稿','絕世武神');  
  
insert into post(id,blog_id,author_id,created_on,section,subject,draft,body)
values(2,1,1001,now(),'旅遊','玄幻','草稿','大主宰');

insert into post(id,blog_id,author_id,created_on,section,subject,draft,body)
values(3,1,1001,now(),'旅遊','玄幻','草稿','靈域');     

在貼JAVA程式碼之前,先看下目錄結構吧:
作者類 Author.java
package com.mybatis.model;
/**
 * 作者類
 * @author Administrator
 *
 */
public class Author {
	
	private int id;
	private String username;
	private String password;
	private String email;
	private String bio; //個人資料
	private String favourite_section; //最喜歡的。。
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getBio() {
		return bio;
	}
	public void setBio(String bio) {
		this.bio = bio;
	}
	public String getFavourite_section() {
		return favourite_section;
	}
	public void setFavourite_section(String favouriteSection) {
		favourite_section = favouriteSection;
	}
	
}
Blog.java
package com.mybatis.model;

import java.util.List;

/**
 * 部落格類
 * @author Administrator
 *
 */
public class Blog {
	private int id;
	private String title;
	private Author author;
	private List<Post> posts; //部落格類有很多文章, 與post表中的blog_id對應
	
	public List<Post> getPosts() {
		return posts;
	}
	public void setPosts(List<Post> posts) {
		this.posts = posts;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public Author getAuthor() {
		return author;
	}
	public void setAuthor(Author author) {
		this.author = author;
	}
	
}

文章類Post.,java
package com.mybatis.model;

import java.util.Date;

/**
 * 文章類
 * @author Administrator
 *
 */
public class Post {
	private int id;
	private int blog_id;
	private int author_id;
	private Date created_on;
	private String section;
	private String subject;
	private String draft;
	private String body;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getBlog_id() {
		return blog_id;
	}
	public void setBlog_id(int blogId) {
		blog_id = blogId;
	}
	public int getAuthor_id() {
		return author_id;
	}
	public void setAuthor_id(int authorId) {
		author_id = authorId;
	}
	public Date getCreated_on() {
		return created_on;
	}
	public void setCreated_on(Date createdOn) {
		created_on = createdOn;
	}
	public String getSection() {
		return section;
	}
	public void setSection(String section) {
		this.section = section;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getDraft() {
		return draft;
	}
	public void setDraft(String draft) {
		this.draft = draft;
	}
	public String getBody() {
		return body;
	}
	public void setBody(String body) {
		this.body = body;
	}
	
}
總配置檔案
<?xml version="1.0" encoding="UTF-8" ?>   
<!DOCTYPE configuration   
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"   
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <typeAliases>
    <!-- 給實體類去一個別名  -->
        <typeAlias type="com.mybatis.model.Blog" alias="Blog"/> 
        <typeAlias type="com.mybatis.model.Post" alias="Post"/>
  </typeAliases>
  
  <!-- 資料來源配置,這裡用MySQL資料庫 -->
  <environments default="development">
     <environment id="development">
         <transactionManager type="JDBC"/>
         <dataSource type="POOLED">
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
               <property name="username" value="root"/>
               <property name="password" value="123456"/>
         </dataSource>
     </environment>
  </environments>
  
  <mappers>
        <mapper resource="com/mybatis/model/Blog.xml"/>
  </mappers>
  
</configuration>

Blog.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC 
    "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
<mapper namespace="com.mybatis.dao.IBlogDao">

<!-- 用文章對映集合來對映部落格 -->
<resultMap id="blogResult" type="Blog">
    <id property="id" column="blog_id"/>
    <result property="title" column="blog_title"/>
    
    <!--文章集合 -->
    <collection property="posts" ofType="Post">
        <id property="id" column="post_id"/>
        <result property="subject" column="post_subject"/>
        <result property="body" column="post_body"/>
    </collection>
</resultMap>

<select id="selectBlog" parameterType="int" resultMap="blogResult">
         select 
             b.id as blog_id ,
             b.title as blog_title,
             b.author_id as blog_author_id,
             p.id as post_id,
             p.subject as post_subject,
             p.body as post_body
           from blog b
               left outer join  post p on b.id=p.blog_id
               where b.id=#{id}  
</select>
</mapper>

測試類Test.java
package com.mybatis.test;

import java.io.IOException;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.mybatis.dao.IBlogDao;
import com.mybatis.model.Blog;
import com.mybatis.model.Post;

public class Test {
	
	/***
	 * 獲得MyBatis SqlSessionFactory
	 * SqlSessionFactory 負責建立SqlSession ,一旦建立成功,就可以用SqlSession例項來執行對映語句
	 * ,commit,rollback,close等方法
	 * @return
	 */
	private static SqlSessionFactory getSessionFactory(){
		SqlSessionFactory sessionFactory=null;
		String resource="configuration.xml";
		 try {
			sessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sessionFactory;
	}
	
	/**
	 * main 方法
	 * @param args
	 */
	public static void main(String[] args) {
		
          SqlSession session=getSessionFactory().openSession();
     try {
    	 IBlogDao blogDao=session.getMapper(IBlogDao.class);
    	 Blog blog=blogDao.selectBlog(1);
         List<Post> postList=blog.getPosts();
         for(Post post:postList){
        	 System.out.println(post.getBody());
         }
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			session.close();
		}
	}
}
執行後結果如下:
DEBUG [com.mybatis.dao.IBlogDao.selectBlog] - ooo Using Connection [[email protected]]
DEBUG [com.mybatis.dao.IBlogDao.selectBlog] - ==>  Preparing: select b.id as blog_id , b.title as blog_title, b.author_id as blog_author_id, p.id as post_id, p.subject as post_subject, p.body as post_body from blog b left outer join post p on b.id=p.blog_id where b.id=? 
DEBUG [com.mybatis.dao.IBlogDao.selectBlog] - ==> Parameters: 1(Integer)
絕世武神
大主宰
靈域


相關推薦

mybatis ---- 查詢 一對 集合對映

關聯有巢狀查詢和巢狀結果兩種方式,本文是按照巢狀結果這種方式來說明的 上一章介紹了多對一的關係,用到了<association></association>,這是一個複雜型別的關聯。我們選擇一個示例來回顧下,比如:一個部落格有一個使用者,關聯對映就工

十七Mybatis自關聯查詢一對查詢

注:程式碼已託管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,專案是mybatis-13-oneself-one2many,需要自取,需要配置maven環境以及mysql環境(sql語句在resource下的test.s

mybatis查詢,分步查詢和延遲加載

enabled 4.2 res 標簽 mapper last pac mes 方式 級聯查詢: 1.Employee表: id;lastName;email; gender;d_id(外鍵關聯Department的ID) 2.Department表: id;deptNa

Mybatis查詢

username tac 實現 數據 配置 級聯查詢 builder java 3.0 轉自:http://blog.csdn.net/yulei_qq/article/details/22039815 工程的目錄結構: 有兩個表,一個文章表article ,一個用戶表u

mybatis之一對的關係

一對多的級聯mybatis一對多的級聯,這裡舉例班級和學生的例子,一個班級有多個學生,屬於一對多的關係,一個學生只屬於一個班級,屬於多對一的關係。 建立資料庫檔案 CREATE TABLE f_class( c_id INT PRIMARY KEY AUTO

mybatis-一對一/一對自關聯配置檔案

實體類: public class Department implements Serializable { private Integer id; private String name; private Set<Department>

hibernate的關聯,一對新增,查詢,普通刪除

一、什麼是關聯(association) 1、關聯指的是類之間的引用關係。如果類A與類B關聯,那麼被引用的類B將被定義為類A的屬性。 2、關聯的分類:關聯可以分為一對一、一對多/多對一、多對多關聯 關聯是有方向的 關聯的關鍵點都在外來鍵上 二、如何建立一對多雙向

一對新增,查詢,刪除

1. 什麼是關聯(association)   1.1 關聯指的是類之間的引用關係。如果類A與類B關聯,那麼被引用的類B將被定義為類A的屬性。例如:       public class A{         private B b = new B;         publ

效能優化總結一對join的查詢

最近在對一個已經運行了4年的老專案進行效能優化,這是一個app,我主要還是從後臺優化。這個專案後臺提供的API並不多,只有十幾個,但是效能非常差。有些API連每分鐘2000的request都扛不住,雖然後臺的併發node已經增加到8個。一看程式碼就知道為什麼了,原來這些AP

【JPA 儲存/刪除】@OneToMany 雙向 一對【轉】

【http://blog.sina.com.cn/s/blog_625d79410101dbdd.html】   看過前兩篇幫助文件 【JPA】 @OneToOne 單向 和 【JPA】@OneToOne 雙向 想必大家對級聯操作已經充

hiberbate一對新增和查詢刪除

1. 什麼是關聯(association) 1.1 關聯指的是類之間的引用關係。如果類A與類B關聯,那麼被引用的類B將被定義為類A的屬性。例如: public class A{ private B b = new B; public A(){} } 1.2 關聯

MyBatis查詢兩種方式

https://blog.csdn.net/zhupengqq/article/details/78575767 與上次唯一不同的一下幾個類 Department.java package com.cn.zhu.bean;   public class Department

pg資料庫查詢inner查詢

一、資料庫的多表連線查詢,inner的不同用法在pg資料庫中建立兩張表:t_a和t_b如下所示:t_a:t_b:1、inner join(內連線)inner join就是根據on欄位標示出來的條件,查詢關聯的表中符合條件的資料,並把他前部都顯示出來,形成一個結果集。執行如下語

MyBatis】resultMap的一對查詢,結果中的list只有一條資料size=1

問題:定義好resultMap之後,查詢結果中的list,其size都是1。(相當於“一對多”變成了“多對一”) 原因:因為返回的列沒有用於區分許可權的id,導致mybatis不知道如何區分,於是把每

springboot極簡使用mybatis實現一對一,一對查詢

繁重的mybatis配置經常讓人頭痛,今天總結一下簡單地使用mybatis 先建好表 CREATE TABLE IF NOT EXISTS `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nick_name` varchar(50)

javaEE Mybatis,一對一、一對關聯查詢,resultMap配置關聯屬性的對映

OrderMapper.xml(實體類的Sql配置檔案,resultMap配置一對一、一對多關聯屬性的對映): <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//

mybatis xml中實現一對查詢時, 子查詢個引數

1、mapper檔案中: List<Object> getXXXXX(@Param("taskId")String taskId,@Param("taskType")String taskType); 2、xml檔案中 <select id="" resultMap

hibernate查詢執行n+1次sqlt語句問題內含解決辦法,優化方式

如果當SQL資料庫中select語句數目過多,就會影響資料庫的效能,如果需要查詢n個Customer物件,那麼必須執行n+1次select查詢語句,下文就將為您講解這個n+1次select查詢問題。 在Session的快取中存放的是相互關聯的物件圖。預設情況下,

MyBatis】資料庫的一對查詢:關於resultMap的使用

利用resultMap,能夠將查詢到的複雜資料(比如查詢到幾個表中資料)對映到一個結果集當中。 (1)如下圖所示,在進行一對多查詢時: (2)通常要求不能出現重複記錄,因此需要對結果資料可以進行整合 (3)解決方案:利用resultMap。程式碼如下: i

mybatis對一++一對部分

1.com.dao(customerMapper+shopMapper) public interface CustomerMapper { List<Customer> many2many(); } ——————————————————————