resultType、resultMap用于将查询结果映射到对象,二者不能同时使用:
- resultType可以实现简单的映射
- resultMap可以实现复杂的映射 (例如解决属性名与字段名不匹配的情况、多表查询映射)
resultType (映射对象类型)
resultType 定义了单条记录映射为对象的类型
- 映射为实例类:如 User类
- 如果不定义实体类,可以使用JAVA自带的类: map 、hashmap
- 如果不定义实体类,还可以使用第三方类如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有两种实现方式:
- 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<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
注意:
- 定义User对象的ResultMap(id=userResultMap):注意ID字段用的是user_id( 这是因为SQL查询用的是select * ,而两个表中都有id字段,为避免冲突,使用user_id字段) 【也可以将该ResultMap定义在UserMapper.xml中:这时SQL中由于两个表有同名字段,因此不使用*号,而是列出相关字段即可】
- 定义Book对象的ResultMap (id=bookWithAuthorResultMap),该对象会引用userResultMap
- 定义查询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 +
'}';
}
一对多映射,同样有两种方式:
- select方式
- 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>
网友评论