resultType可以把查询的结果分装到pojo类型对象中,但pojo类的属性名和查询到的数据库表的字段名必须保持一致。如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中。
数据库表的结构:
create table sys_user(
user_id int(5) auto_increment primary_key,
user_name nvarchar(20),
user_sex nvarchar(2),
user_age int(3),
user_address nvarchar(50)
);
而pojo下的User类
public class User {
private int id;
private String name;
private String sex;
private int age;
private String address;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
UserMapper.xml
<mapper namespace="com.company.mapper.UserMapper">
<!--resultMap:填入配置resultMap标签的id值-->
<select id="queryUserById" resultMap="userResultMap" parameterType="int">
select * from sys_user where user_id=#{id}
</select>
<!--
配置resultMap 映射不同的字段名和属性名
id属性:resultMap唯一标识
type属性:指定映射到哪一个pojo中
-->
<resultMap id="userResultMap" type="com.company.pojo.User">
<!--
id标签定义主键,非常重要,如果是多个字段,则定义多个id标签
column属性:主键在数据库中的列名
property属性:主键在pojo中的属性名
-->
<id column="user_id" property="id"></id>
<!--
result标签定义普通属性
column属性:非主键列名在数据库中的列名
property属性:非主键列名在pojo中对应的属性名
-->
<result column="user_name" property="name"></result>
<result column="user_sex" property="sex"></result>
<result column="user_age" property="age"></result>
<result column="user_address" property="address"></result>
</resultMap>
</mapper>
这样结果就可以封装到pojo中。
使用resultMap进行关联查询
一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息,则为一对多查询,一个用户可以下多个订单。
一对一查询
一对一数据模型:订单用户
1)改动pojo类
在订单类中添加User属性,User属性是一个引用类型,用于存储关联查询的用户信息,因为关联关系是一对一,所以只需要添加单个属性即可。
Orders.java
public class Orders {
//订单id
private int id;
//用户id
private int userId;
//订单号
private String number;
//订单创建时间
private Date createTime;
//备注
private String remark;
//关联用户信息
private User user;
@Override
public String toString() {
return "Orders{" +
"id=" + id +
", userId=" + userId +
", number='" + number + '\'' +
", createTime=" + createTime +
", remark='" + remark + '\'' +
", user=" + user +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
2)配置Mapper.xml文件
先使用id和result属性,映射orders类的结果集,然后使用association映射关联对象User的结果集
OrdersMapper.xml
<mapper namespace="com.company.mapper.OrdersMapper">
<select id="queryOrdersUserList" resultMap="ordersResultMap">
select * from orders as a
left join sys_user as b
on a.user_id=b.user_id
</select>
<resultMap id="ordersResultMap" type="com.company.pojo.Orders">
<id property="id" column="id"></id>
<result property="userId" column="user_id"></result>
<result property="number" column="number"></result>
<result property="createTime" column="createtime"></result>
<result property="remark" column="remark"></result>
<!--
association:配置一对一关系
property属性:关联对象在Orders里面的属性名
javaType属性:关联对象类型
-->
<association property="user" javaType="com.company.pojo.User">
<id property="id" column="user_id"></id>
<result property="name" column="user_name"></result>
<result property="sex" column="user_sex"></result>
<result property="age" column="user_age"></result>
<result property="address" column="user_address"></result>
</association>
</resultMap>
</mapper>
3)测试
@Test
public void test() throws Exception{
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
inputStream.close();
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> ordersList = ordersMapper.queryOrdersUserList();
ordersList.forEach(System.out::println);
sqlSession.close();
}
一对多查询
查询所有用户信息及相关订单
1)修改pojo类,在pojo类添加订单集合属性
User.java
public class User {
//用户id
private int id;
//姓名
private String name;
//性别
private String sex;
//年龄
private int age;
//地址
private String address;
private List<Orders> orders;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", address='" + address + '\'' +
", orders=" + orders +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Orders> getOrders() {
return orders;
}
public void setOrders(List<Orders> orders) {
this.orders = orders;
}
}
2)修改Mapper.xml文件
先使用id和result配置映射User类的结果,然后使用一对多关系的collection标签配置orders结果
UserMapper.xml
<mapper namespace="com.company.mapper.UserMapper">
<select id="queryUserOrdersList" resultMap="userOrdersResultMap">
select * from sys_user as a
left join orders as b
on a.user_id=b.user_id
</select>
<resultMap id="userOrdersResultMap" type="com.company.pojo.User">
<id column="user_id" property="id"></id>
<result column="user_name" property="name"></result>
<result column="user_sex" property="sex"></result>
<result column="user_age" property="age"></result>
<result column="user_address" property="address"></result>
<!--
collection:配置一对多关系
property属性:关联对象在Users里面的属性名
ofType属性:集合中pojo对象类型
-->
<collection property="orders" ofType="com.company.pojo.Orders">
<id property="id" column="id"></id>
<result property="userId" column="user_id"></result>
<result property="number" column="number"></result>
<result property="createTime" column="createtime"></result>
<result property="remark" column="remark"></result>
</collection>
</resultMap>
</mapper>
3)测试
@Test
public void test() throws Exception{
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
inputStream.close();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.queryUserOrdersList();
userList.forEach(System.out::println);
sqlSession.close();
}
resultMap包含的元素
<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
<id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
<result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
<association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
<id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/>
<result column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
</association>
<!-- 集合中的property须为oftype定义的pojo对象的属性-->
<collection property="pojo的集合属性" ofType="集合中的pojo对象">
<id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
<result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />
</collection>
</resultMap>
如果collection标签是使用嵌套查询,格式如下:
<collection column="传递给嵌套查询语句的字段参数" property="pojo对象中集合属性" ofType="集合属性中的pojo对象" select="嵌套的查询语句" >
</collection>
注意:<collection>标签中的column:要传递给select查询语句的参数,如果传递多个参数,格式为column="{参数名1=表字段1,参数名2=表字段2}"
当两张表含有相同的字段名时,需要在sql语句查询结果中指定别名,然后在resultMap中映射到对应的pojo的属性名。