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进行关联查询

一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息,则为一对多查询,一个用户可以下多个订单。

resultType封装属性 @resulttype_主键

一对一查询

一对一数据模型:订单用户

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的属性名。