zoukankan      html  css  js  c++  java
  • 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','824156593@qq.com','合肥的小男孩','旅游');
    
            
            
    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 [com.mysql.jdbc.Connection@e00ed0]
    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)
    绝世武神
    大主宰
    灵域
    







  • 相关阅读:
    报表图片不显示的问题(一)
    数据库时区问题
    变色
    给div加滚动条,当内容超过它的范围的时候
    Apple Style Effect
    easyui发生重叠现象的原因
    mysql 获取字符串长度
    纯css的带下拉菜单的导航条
    jQuery验证控件jquery.validate.js使用说明+中文API
    background-position 用法详细介绍
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300374.html
Copyright © 2011-2022 走看看