Mybatis第二章——多表同时插入和级联查询

Mybatis第二章——多表同时插入和级联查询

知识点一:多表同时插入,其中要插入的Blog的数据中的author_id依赖于另一个要插入的author对象的id

此时需要在mapper.xml文件中配置 useGeneratedKeys="true" keyProperty="id",只需要在被依赖的对象中配置。
    <!-- 多表插入 begin -->
    <!-- 由于addBlog中的#{author.id}依赖于addAuthor后的id,因此需要authord对象中的id自增 -->
    <insert id="addAuthor" parameterType="author" useGeneratedKeys="true" keyProperty="id">
        insert into tb_author(username,password,email,address,phone) values(#{username},#{password},#{email},#{address},#{phone});
    </insert>
    
    <insert id="addBlog" parameterType="blog" >
        insert into tb_blog(title,content,type,author_id) values(#{title},#{content},#{type},#{author.id});
    </insert>
    <!-- 多表插入 end -->   

注意:如果不写useGeneratedKeys="true" keyProperty="id",那么返回给author对象的id将为默认值'0',
而数据库的author转换成的该条记录可以自增;
useGeneratedKeys的主键自动增长,不是数据库中的数据primary key自动增长,而是让数据库主键匹配到的对象的主键自动增长。

@org.junit.Test
    public void test1(){
        
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        
        Author author = new Author("吴健红", "123456", "wjh@163.com", "甘肃", "18888888888");
        
        Blog blog = new Blog("旅游", "去上海旅游", "游玩", author);
        
        testMapper.addAuthor(author);//需要主键生成s
        
        //testMapper.addBlog(blog);  在不使用主键自动增长的情况下,只插入author对象,这样不会报错,从而来测试author对象的id
        
        sqlSession.commit();
        System.out.println(author);
        sqlSession.close();
    //运行结果:Author [id=0, username=吴健红, password=123456, email=wjh@163.com, address=甘肃, phone=18888888888]

知识点二:Mybatis 实现多表查询方式

1.1 业务装配.对两个表编写单表查询语句,在业务(Service)把查询
的两个结果进行关联.
1.2 使用 Auto Mapping 特性,在实现两表联合查询时通过别名完成
映射.
1.3 使用 MyBatis 的<resultMap>标签进行实现.

知识点三:级联一对一的查询(N+1)

N+1 查询方式,先查询出某个表的全部信息,根据这个表的信息  
查询另一个表的信息.需要使用到<resultMap>标签

pojo类——Author

package com.xtkj.pojo;

public class Author {

    private int id;
    private String username;
    private String password;
    private String email;
    private String address;
    private String phone;
    
    public Author() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Author(String username, String password, String email,
            String address, String phone) {
        super();
        this.username = username;
        this.password = password;
        this.email = email;
        this.address = address;
        this.phone = phone;
    }
    
    @Override
    public String toString() {
        return "Author [id=" + id + ", username=" + username + ", password="
                + password + ", email=" + email + ", address=" + address
                + ", phone=" + phone + "]";
    }
    
    get...
    set...

}

pojo类——blog

package com.xtkj.pojo;

import java.util.ArrayList;
import java.util.List;

public class Blog {

    private int id;
    private String title;
    private String content;
    private String type;
    private Author author;//author_id  select * from tb_author where id = author_id;-->author
    private List<Comment> comments = new ArrayList<Comment>();//id select * from tb_comment where blog_id=id;-->N  comment
    
    public Blog() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Blog(String title, String content, String type, Author author) {
        super();
        this.title = title;
        this.content = content;
        this.type = type;
        this.author = author;
    }
    
    @Override
    public String toString() {
        return "Blog [id=" + id + ", title=" + title + ", content=" + content
                + ", type=" + type + ", author=" + author + "]";
    }
    get...
    set...
    
    
}

mapper.xml

    <!-- 级联对一的查询 findBlogById返回去的 -->
    <resultMap type="blog" id="aa">   
        <id column="id" property="id"/>     
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="type" property="type"/>

        <!-- 对一的配置使用association,通过查询出的author_id调用findAuthorById将author对象查询出来并付给blog对象里的author,javaType="author"可以省略 -->
        <association column="author_id" select="findAuthorById" javaType="author" property="author"></association>
    </resultMap>
    <!-- 主查询 -->
    <select id="findBlogById" parameterType="int" resultMap="aa">
        select * from tb_blog where id=#{id}
    </select>
    <!-- 主查询 -->
    <select id="findAuthorById" parameterType="int" resultType="author">
        select * from tb_author where id=#{id}
    </select>
大前提使用 N+1 方式.时如果列名和属性名相同可
以不配置,使用 Auto mapping 特性.但是 mybatis 默认只会给列
专配一次

测试

@org.junit.Test
    public void test2(){
        
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        
        Blog blog = testMapper.findBlogById(15);
        
        System.out.println(blog);
        
        //sqlSession.commit();
        sqlSession.close();
        //结果:Blog [id=15, title=旅游, content=去上海旅游, type=游玩, author=Author [id=17, username=吴健红, password=123456, email=wjh@163.com, address=甘肃, phone=18888888888]]
    }

知识点四:级联一对多的查询(N+1方式)

mapper.xml

    <resultMap type="blog" id="aa">
        <id column="id" property="id"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="type" property="type"/>
        <!-- <result column="author_id" property="author"/> -->
        
        <!-- 对多的配置使用collection,通过查询初的blog_id将comment对象查询出来并付给blog对象中的comments集合 -->
        <collection column="id" select="findCommentByBlogId" ofType="comment" property="comments"></collection>
    </resultMap>
    
    <!-- 主查询 通过id查询blog-->
    <select id="findBlogById" parameterType="int" resultMap="aa">
        select * from tb_blog where id=#{id}
    </select>
    <!-- 级联对多的查询,通过comment中的blog_id查询出该blog下的所有comments -->
    <select id="findCommentByBlogId" parameterType="int" resultType="comment">
        select * from tb_comment where blog_id=#{blog_id}
    </select>

测试

@org.junit.Test
    public void test3(){
        
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        
        Blog blog = testMapper.findBlogById(15);
        System.out.println(blog);
        
        List<Comment> comments = blog.getComments();
        for(int i=0;i<comments.size();i++){
            System.out.println("content:"+comments.get(i).getContent());
        }
        
        //sqlSession.commit();
        sqlSession.close();
        
    }
    /* 
    结果: 
    Blog [id=15, title=旅游, content=去上海旅游, type=游玩, author=Author [id=17, username=吴健红, password=123456, email=wjh@163.com, address=甘肃, phone=18888888888]]
    content:niho
    content:lala
     */

知识点五:使用resultMap实现加载集合数据(联合查询方式)

<!-- 使用resultMap 进行联合查询 -->
    <resultMap type="blog" id="mymap">
        <id column="bid" property="id"/>
        <result column="btitle" property="title"/>
        <result column="btitle" property="title"/>
        <result column="bcontent" property="content"/>
        <result column="btype" property="type"/>
        <association column="aid" select="findAuthorById" javaType="author" property="author"></association>
        <collection property="comments" ofType="comment">
            <id column="cid" property="id"/>
            <result column="ccontent" property="content"/>
        
        </collection>
    </resultMap>
    <select id="findBlogAndComments" resultMap="mymap" parameterType="int">
        select b.id bid,b.title btitle,b.content bcontent,b.type btype,b.author_id aid,
        c.id cid,c.content ccontent from tb_blog b left join tb_comment c on b.id = c.blog_id
        where b.id=#{0}
    </select>

测试

@org.junit.Test
    public void test4(){
        
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        
        Blog blog = testMapper.findBlogAndComments(15);
        System.out.println(blog);
        
        
        List<Comment> comments = blog.getComments();
        for(int i=0;i<comments.size();i++){
            System.out.println("content:"+comments.get(i).getContent());
        }
        
        //sqlSession.commit();
        sqlSession.close();
        
    }
    /* 
     结果:
     Blog [id=15, title=旅游, content=去上海旅游, type=游玩, author=Author [id=17, username=吴健红, password=123456, email=wjh@163.com, address=甘肃, phone=18888888888]]
     content:niho
     content:lala
     */ 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,423评论 0 4
  • 在学习MyBatis3的过程中,文档上面一直在强调一个id的东西!在做这个实验的时候,也因为没有理解清楚id含义而...
    杀小贼阅读 980评论 0 6
  • MyBatis 真正的力量是在映射语句中。这里是奇迹发生的地方。对于所有的力量,SQL 映射的 XML 文件是相当...
    zhDoveLie阅读 798评论 1 0
  • MyBatis 理论篇 [TOC] 什么是MyBatis  MyBatis是支持普通SQL查询,存储过程和高级映射...
    有_味阅读 2,881评论 0 26
  • 这篇博客主要是记录Mybatis的基本用法,包括Mybatis的入参形式、返回参数形式以及resultMap的使用...
    Michaelhbjian阅读 1,154评论 2 3