resultType、resultMap用于将查询结果映射到对象,二者不能同时使用:
- resultType可以实现简单的映射
- resultMap可以实现复杂的映射 (例如解决属性名与字段名不匹配的情况、多表查询映射)
resultType (映射对象类型)
resultType 定义了单条记录映射为对象的类型
- 映射为实例类:如 User类
- 如果不定义实体类,可以使用JAVA自带的类: map 、hashmap
- 如果不定义实体类,还可以使用第三方类如JSON
查询(返回单条记录:以对象方式返回)
// 接口映射
User selectByID(int id);
查询(返回多条记录:以对象 List方式返回)
// 接口映射
List selectAll();
查询(返回单条记录:以Map方式返回)
// 接口映射
Map selectByID_map(int id);
查询(返回多条记录:以List
// 接口映射
List
查询(返回单条记录:以JSONObject方式返回)
// 接口映射
JSONObject selectByID_json(int id);
查询(返多单条记录:以JSONArray/JSONObject方式返回)
// 接口映射
JSONArray selectAll_json();
resultMap (复杂映射)
字段映射
List selectUsers();
association联合:用来处理“一对一”的关系
假设 book 表中,有user_id字段(关联到 user 表的 id) ,表示书的作者。
在查询中构建Book对象时,同时构建关联的作者 (User对象):
association有两种实现方式:
- select方式: 首先查询Book表,然后通过select调用User的查询方式进行查询。 这种方式通常用于查询Book表的1条记录(或较少的记录); 如果查询的 Book记录较多,性能会很差,因为会针对 Book的每条记录,查询关联User表(即会多次访问数据库)。
- 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 selectAll();
Book selectByID(int id);
}
创建BookMapper.xml (定义SQL映射)
注意:创建该xml后,需要在mybatis-config.xml文件中进行注册。
测试代码
BookMapper mapper = session.getMapper(BookMapper.class);
List list = mapper.selectAll();
System.out.println(list);
//在输出结果中可以看到,Book对象中的User对象也被构造出来的。
association联合(resultMap方式)
在BookMapper.xml中定义SQL及ResultMap
注意:
- 定义User对象的ResultMap(id=userResultMap):注意ID字段用的是user_id( 这是因为SQL查询用的是select * ,而两个表中都有id字段,为避免冲突,使用user_id字段) 【也可以将该ResultMap定义在UserMapper.xml中:这时SQL中由于两个表有同名字段,因此不使用*号,而是列出相关字段即可】
- 定义Book对象的ResultMap (id=bookWithAuthorResultMap),该对象会引用userResultMap
- 定义查询SQL:这里用的是join关联查询
在BookMapper.java中定义查询接口
List selectBookWithAuthor();
测试
BookMapper mapper = session.getMapper(BookMapper.class);
List list = mapper.selectBookWithAuthor();
System.out.println(list);
collection聚集(用于一对多关联)
如果关联查询 User、 Book,则一个User可对应多个Book.
首先在User.java中添加 List
private List bookList;
public List getBookList() {
return bookList;
}
public void setBookList(List bookList) {
this.bookList = bookList;
}
首先在User.java重写 toString方法:以打印bookList
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", age=" + age +
", sex=" + sex +
", books=" + bookList +
'}';
}
一对多映射,同样有两种方式:
- select方式
- resultMap方式
collection聚集(select方式)
修改BookMapper.java
先删除其他的接口,并添加如下接口
//查询指定作者的所有Book 【删除其他接口,是避免在查询Book时,又去查询作者】
List selectByAuthor(int userID);
修改BookMapper.xml
同样,先删除其他所有的SQL映射,并添加如下SQL映射
修改UserMapper.java
添加如下接口
//查询用户
List selectUsersWithBook();
修改UserMapper.xml
测试
UserMapper mapper = session.getMapper(UserMapper.class);
List list = mapper.selectUsersWithBook();
System.out.println(list);
// 输出结果中,User对象包含books列表。
collection聚集(resultMap方式)
修改UserMapper.java
添加如下接口
//查询用户
List selectUsersWithBook2();
修改UserMapper.xml
修改BookMapper.xml