resultType、resultMap用于將查詢結(jié)果映射到對(duì)象,二者不能同時(shí)使用:
- resultType可以實(shí)現(xiàn)簡(jiǎn)單的映射
- resultMap可以實(shí)現(xiàn)復(fù)雜的映射 (例如解決屬性名與字段名不匹配的情況、多表查詢映射)
resultType (映射對(duì)象類型)
resultType 定義了單條記錄映射為對(duì)象的類型
- 映射為實(shí)例類:如 User類
- 如果不定義實(shí)體類,可以使用JAVA自帶的類: map 、hashmap
- 如果不定義實(shí)體類,還可以使用第三方類如JSON
查詢(返回單條記錄:以對(duì)象方式返回)
<select id="selectByID" resultType="com.example.mybatis.entity.User">
select * from user where id = #{id}
</select>
// 接口映射
User selectByID(int id);
查詢(返回多條記錄:以對(duì)象 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 (復(fù)雜映射)
字段映射
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聯(lián)合:用來處理“一對(duì)一”的關(guān)系
假設(shè) book 表中,有user_id字段(關(guān)聯(lián)到 user 表的 id) ,表示書的作者。
在查詢中構(gòu)建Book對(duì)象時(shí),同時(shí)構(gòu)建關(guān)聯(lián)的作者 (User對(duì)象):
association有兩種實(shí)現(xiàn)方式:
- select方式: 首先查詢Book表,然后通過select調(diào)用User的查詢方式進(jìn)行查詢。 這種方式通常用于查詢Book表的1條記錄(或較少的記錄); 如果查詢的 Book記錄較多,性能會(huì)很差,因?yàn)闀?huì)針對(duì) Book的每條記錄,查詢關(guān)聯(lián)User表(即會(huì)多次訪問數(shù)據(jù)庫(kù))。
- resultMap方式:使用 join關(guān)聯(lián)查詢 SQL方式
association聯(lián)合(select方式):
創(chuàng)建Book表
create table book(
id bigint not null AUTO_INCREMENT comment '主鍵' primary key,
book_name varchar(60) null comment '書名',
user_id bigint comment '作者ID'
);
創(chuàng)建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 +
'}';
}
}
創(chuàng)建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);
}
創(chuàng)建BookMapper.xml (定義SQL映射)
注意:創(chuàng)建該xml后,需要在mybatis-config.xml文件中進(jìn)行注冊(cè)。
<?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"/>
<!-- 定義一對(duì)一關(guān)聯(lián)對(duì)象 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>
測(cè)試代碼
BookMapper mapper = session.getMapper(BookMapper.class);
List<Book> list = mapper.selectAll();
System.out.println(list);
//在輸出結(jié)果中可以看到,Book對(duì)象中的User對(duì)象也被構(gòu)造出來的。
association聯(lián)合(resultMap方式)
在BookMapper.xml中定義SQL及ResultMap
注意:
- 定義User對(duì)象的ResultMap(id=userResultMap):注意ID字段用的是user_id( 這是因?yàn)镾QL查詢用的是select * ,而兩個(gè)表中都有id字段,為避免沖突,使用user_id字段) 【也可以將該ResultMap定義在UserMapper.xml中:這時(shí)SQL中由于兩個(gè)表有同名字段,因此不使用*號(hào),而是列出相關(guān)字段即可】
- 定義Book對(duì)象的ResultMap (id=bookWithAuthorResultMap),該對(duì)象會(huì)引用userResultMap
- 定義查詢SQL:這里用的是join關(guān)聯(lián)查詢
<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"/>
<!-- 定義一對(duì)一關(guān)聯(lián)對(duì)象 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();
測(cè)試
BookMapper mapper = session.getMapper(BookMapper.class);
List<Book> list = mapper.selectBookWithAuthor();
System.out.println(list);
collection聚集(用于一對(duì)多關(guān)聯(lián))
如果關(guān)聯(lián)查詢 User、 Book,則一個(gè)User可對(duì)應(yīng)多個(gè)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 +
'}';
}
一對(duì)多映射,同樣有兩種方式:
- select方式
- resultMap方式
collection聚集(select方式)
修改BookMapper.java
先刪除其他的接口,并添加如下接口
//查詢指定作者的所有Book 【刪除其他接口,是避免在查詢Book時(shí),又去查詢作者】
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>
測(cè)試
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.selectUsersWithBook();
System.out.println(list);
// 輸出結(jié)果中,User對(duì)象包含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>
<!--【注意】 由于兩個(gè)表的ID字段沖突,因此列出字段名。同時(shí)保證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>