mybatis(Spring boot集成原生mybatis)-02(resultType|resultMap)

resultType、resultMap用于将查询结果映射到对象,二者不能同时使用:

  • resultType可以实现简单的映射
  • resultMap可以实现复杂的映射 (例如解决属性名与字段名不匹配的情况、多表查询映射)

resultType (映射对象类型)

resultType 定义了单条记录映射为对象的类型

  1. 映射为实例类:如 User类
  2. 如果不定义实体类,可以使用JAVA自带的类: map 、hashmap
  3. 如果不定义实体类,还可以使用第三方类如JSON

查询(返回单条记录:以对象方式返回)

    <select id="selectByID" resultType="com.example.mybatis.entity.User">
        select * from user where id = #{id}
    </select>
 // 接口映射
    User selectByID(int id);

查询(返回多条记录:以对象 List方式返回)

    <select id="selectAll" resultType="com.example.mybatis.entity.User">
        select * from user
    </select>
 // 接口映射
    List<User> selectAll();

查询(返回单条记录:以Map方式返回)

    <select id="selectByID_map" resultType="hashmap">
        select * from user where id = #{id}
    </select>
 // 接口映射
    Map selectByID_map(int id);

查询(返回多条记录:以List<Map>方式返回)

    <select id="selectAll_map" resultType="hashmap">
        select * from user
    </select>
 // 接口映射
        List<Map> selectAll_map();

查询(返回单条记录:以JSONObject方式返回)

    <select id="selectByID_json" resultType="com.alibaba.fastjson.JSONObject">
        select * from user where id = #{id}
    </select>
 // 接口映射
    JSONObject selectByID_json(int id);

查询(返多单条记录:以JSONArray/JSONObject方式返回)

    <select id="selectAll_json" resultType="com.alibaba.fastjson.JSONObject">
        select * from user
    </select>
 // 接口映射
    JSONArray selectAll_json();

resultMap (复杂映射)

字段映射

    List<User> selectUsers();
    <resultMap id="userResultMap" type="com.example.mybatis.entity.User">
        <id property="id" column="user_id"/>
        <result property="username" column="user_name"/>
        <result property="password" column="user_password"/>
    </resultMap>

    <select id="selectUsers" resultMap="userResultMap">
        select id as user_id,
            username as user_name,
            password as user_password,
            age,
            sex
        from user
    </select>

association联合:用来处理“一对一”的关系

假设 book 表中,有user_id字段(关联到 user 表的 id) ,表示书的作者。
在查询中构建Book对象时,同时构建关联的作者 (User对象):
association有两种实现方式:

  1. select方式: 首先查询Book表,然后通过select调用User的查询方式进行查询。 这种方式通常用于查询Book表的1条记录(或较少的记录); 如果查询的 Book记录较多,性能会很差,因为会针对 Book的每条记录,查询关联User表(即会多次访问数据库)。
  2. resultMap方式:使用 join关联查询 SQL方式

association联合(select方式):

创建Book表
create table book(
    id bigint not null AUTO_INCREMENT comment '主键' primary key,
    book_name varchar(60) null comment '书名',
    user_id bigint comment '作者ID'
);
创建Book.java
package com.example.mybatis.entity;
public class Book {
    private int id;
    private String bookName;    //书名
    private User author;        //作者(在book表中,使用user_id做为外键)

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public User getAuthor() {
        return author;
    }
    public void setAuthor(User author) {
        this.author = author;
    }
    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", bookName='" + bookName + '\'' +
                ", author=" + author +
                '}';
    }
}
创建BookMapper.java (定义接口)
package com.example.mybatis.mapper;
import com.example.mybatis.entity.Book;
import java.util.List;
public interface BookMapper {
    List<Book> selectAll();
    Book selectByID(int id);
}
创建BookMapper.xml (定义SQL映射)

注意:创建该xml后,需要在mybatis-config.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.example.mybatis.mapper.BookMapper">

    <resultMap id="bookResultMap" type="com.example.mybatis.entity.Book">
        <id property="id" column="id"/>
        <result property="bookName" column="book_name"/>
       <!-- 定义一对一关联对象  select方式 -->
        <association property="author" column="user_id" select="com.example.mybatis.mapper.UserMapper.selectByID"/>
    </resultMap>

    <select id="selectAll" resultMap="bookResultMap">
        select * from book
    </select>

    <select id="selectByID" resultMap="bookResultMap">
        select * from book where id = #{id}
    </select>
</mapper>
测试代码
            BookMapper mapper = session.getMapper(BookMapper.class);
            List<Book> list = mapper.selectAll();
            System.out.println(list);
           //在输出结果中可以看到,Book对象中的User对象也被构造出来的。

association联合(resultMap方式)

在BookMapper.xml中定义SQL及ResultMap

注意:

  1. 定义User对象的ResultMap(id=userResultMap):注意ID字段用的是user_id( 这是因为SQL查询用的是select * ,而两个表中都有id字段,为避免冲突,使用user_id字段) 【也可以将该ResultMap定义在UserMapper.xml中:这时SQL中由于两个表有同名字段,因此不使用*号,而是列出相关字段即可】
  2. 定义Book对象的ResultMap (id=bookWithAuthorResultMap),该对象会引用userResultMap
  3. 定义查询SQL:这里用的是join关联查询
    <resultMap id="userResultMap" type="com.example.mybatis.entity.User">
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
    </resultMap>

    <resultMap id="bookWithAuthorResultMap" type="com.example.mybatis.entity.Book">
        <id property="id" column="id"/>
        <result property="bookName" column="book_name"/>
        <!-- 定义一对一关联对象  userResultMap方式(引用UserMapper.xml中定义的userResultMap) -->
        <association property="author" column="user_id"
                     resultMap="userResultMap"/>
    </resultMap>

    <select id="selectBookWithAuthor" resultMap="bookWithAuthorResultMap">
        SELECT * FROM
        book b LEFT JOIN user u ON b.user_id=u.id
    </select>
在BookMapper.java中定义查询接口
    List<Book> selectBookWithAuthor();
测试
            BookMapper mapper = session.getMapper(BookMapper.class);
            List<Book> list = mapper.selectBookWithAuthor();
            System.out.println(list);

collection聚集(用于一对多关联)

如果关联查询 User、 Book,则一个User可对应多个Book.

首先在User.java中添加 List<Book>

    private List<Book> bookList;
    public List<Book> getBookList() {
        return bookList;
    }
    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }

首先在User.java重写 toString方法:以打印bookList

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", books=" + bookList +
                '}';
    }

一对多映射,同样有两种方式:

  1. select方式
  2. resultMap方式

collection聚集(select方式)

修改BookMapper.java

先删除其他的接口,并添加如下接口

    //查询指定作者的所有Book 【删除其他接口,是避免在查询Book时,又去查询作者】
    List<Book> selectByAuthor(int userID);
修改BookMapper.xml

同样,先删除其他所有的SQL映射,并添加如下SQL映射

    <resultMap id="bookWithAuthorResultMap" type="com.example.mybatis.entity.Book">
        <id property="id" column="id"/>
        <result property="bookName" column="book_name"/>
    </resultMap>
    <!-- 查询指定作者的所有Book -->
    <select id="selectByAuthor" resultMap="bookWithAuthorResultMap">
        select * from book where user_id = #{userID}
    </select>
修改UserMapper.java

添加如下接口

   //查询用户
    List<User> selectUsersWithBook();
修改UserMapper.xml
    <resultMap id="usersResultMap" type="com.example.mybatis.entity.User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <collection property="bookList" column="id" javaType="ArrayList" ofType="com.example.mybatis.entity.Book"
                    select="com.example.mybatis.mapper.BookMapper.selectByAuthor"/>
    </resultMap>

    <select id="selectUsersWithBook" resultMap="usersResultMap">
        SELECT * FROM user
    </select>
测试
            UserMapper mapper = session.getMapper(UserMapper.class);
            List<User> list = mapper.selectUsersWithBook();
            System.out.println(list);
            // 输出结果中,User对象包含books列表。

collection聚集(resultMap方式)

修改UserMapper.java

添加如下接口

   //查询用户
     List<User> selectUsersWithBook2();
修改UserMapper.xml
    <resultMap id="usersResultMap2" type="com.example.mybatis.entity.User">
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <collection property="bookList" javaType="ArrayList" ofType="com.example.mybatis.entity.Book"
                    resultMap="com.example.mybatis.mapper.BookMapper.bookResultMap"/>
    </resultMap>
<!--【注意】 由于两个表的ID字段冲突,因此列出字段名。同时保证book表的字段名不变,否则需要修改BookMapper.xml中的配置。-->
    <select id="selectUsersWithBook2" resultMap="usersResultMap2">
        SELECT u.id user_id,u.username,u.age,u.sex,
        b.id id,b.book_name
        FROM user u LEFT JOIN book b on u.id=b.user_id
    </select>
修改BookMapper.xml
    <resultMap id="bookResultMap" type="com.example.mybatis.entity.Book">
        <id property="id" column="id"/>
        <result property="bookName" column="book_name"/>
     </resultMap>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容