MyBatis复习(五):获取多表关联查询结果


Map保存查询结果

<select id="selectBlogMap" resultType="java.util.Map">
    select b.* , u.nick_name from t_blog b , t_user u
    where b.user_id = u.user_id
</select>
package com.cd.blog.config;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * @Author: 落叶无痕
 * @Date: 2020/5/15 16:45
 */
public class MyBatisUtils {
    
    

    /*MyBatisUtils工具类,目的是创建全局唯一的SqlSessionFactory对象*/


    //static属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;

    //利用静态块在初始化类时初始化SqlSessionFactory
    static {
    
    
        InputStream input = null;
        try {
    
    
			// 使用字节流方式加载classpath下的mybatis-config.xml核心配置文件
            input = Resources.getResourceAsStream("mybatis-config.xml");
			// 初始化SqlSessionFactory对象,并解析mybatis-config.xml文件
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            //初始化错误时,抛出ExceptionInInitializerError异常通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }

	// 创建SqlSession对象(SqlSession是JDBC的扩展类,专门用于与数据库交互)
    public static SqlSession openSession(){
    
    
        return sqlSessionFactory.openSession();
    }

	// 释放一个有效的SqlSession对象
    public static void closeSession(SqlSession sqlSession){
    
    
        if(sqlSession != null){
    
    
            sqlSession.close();
        }
    }

}
package com.cd.blog.config;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;
import java.util.Map;

/**
 * @Author: 落叶无痕
 * @Date: 2020/5/17 21:42
 */
public class TestMyBatisUtils {
    
    

    @Test
    public void demo(){
    
    
        SqlSession sqlSession = null;
        try{
    
    
            sqlSession = MyBatisUtils.openSession();
            List<Map> list = sqlSession.selectList("selectBlogMap");
            for(Map map : list){
    
    
                System.out.println(map);
            }
        }catch (Exception e){
    
    
            throw e;
        }finally {
    
    
            MyBatisUtils.closeSession(sqlSession);
        }
    }

}

1. 以java.util.Map作为查询结果,返回的数据是以键值对的格式返回的,键名是表字段名,键值是表字段的值。并且java.util.Map接口默认实现类是HashMap,根据HashMap的底层是hash表,HashMap的Key是根据Key的hash值来进行排序,hash值是一个不稳定的数字,所以各字段排序的结果就会出现乱序。


2. 为保证返回结果的个字段的前后顺序一致,需要将resultType查询结果类型改为java.util.LinkedHashMap,LinkedHashMap底层是链表,在进行数据提取时,是按照我们往里插入数据时的先后顺序进行保存,因此不会像HashMap一样出现乱序现象。

<select id="selectBlogMap" resultType="java.util.LinkedHashMap">
    select b.* , u.nick_name from t_blog b , t_user u
    where b.user_id = u.user_id
</select>


总结:

  • 使用java.util.LinkedHashMap来接收数据,在我们的开发中是非常常见的。针对于多个表的关联查询,LinkedHashMap可以有效地帮助我们进行数据的扩展,使用起来非常灵活。

  • 关于javaType:

    • resultType的接收类型可以是实体类,实体类与表结构字段一致时可以自动封装数据到实体类中
    • 当resultType为Map时,查询出来的数据是无序的。
    • resultType的类型为Map / LinkedHashMap时多用于多表关联查询。

ResultMap结果集映射

1. ResultMap适用于java对象保存多表关联查询结果,可以将查询结果映射为复杂类型的java对象。

2. 我们在获取多表关联查询结果时,一般都会涉及到多个表的字段。这个时候,普通的实体类就无法满足我们的需求了(普通实体类对象的属性都是和对应表的字段一一对应的),当然我们也可以在实体类的基础上进行扩展。
例如:

public class Product {
    
    

    //商品id
    private Long productId;
    //商品名
    private String productName;
    //商品描述
    private String productDesc;
    //商品缩略图
    private String imgAddress;
    //原价
    private Double normalPrice;
    //折扣价
    private Double promotionPrice;
    //积分
    private Integer point;
    //权重
    private Integer priority;
    //状态 0:下架 1:在前端展示系统展示
    private Integer enableStatus;
    //创建时间
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date createTime;
    //修改时间
    /* 使用@JsonFormat注解格式化日期,才能按指定格式在前端页面,具体参考:https://www.jb51.net/article/144235.htm */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
    private Date lastEditTime;

/*---------下面是扩充的关联对象---------------------------------*/

    // 店铺实体类,标明商品属于哪个店铺
    private Shop shop;
    // 商品类别,一件商品仅属于一个商品类别
    private ProductCategory productCategory;

    // 图片详情图列表,跟商品是多对一的关系
    private List<ProductImg> productImgList;
    
}
<!--配置实体类属性与表字段的关系映射,结果集-->
<resultMap id="product" type="Product">
	<!--主键字段用id配置,非主键字段用result配置 【property:实体类属性名,column:表字段名】-->
    <id property="productId" column="product_id"/>
    <result property="productName" column="product_name"/>
    <result property="productDesc" column="product_desc"/>
    <result property="imgAddress" column="img_address"/>
    <result property="normalPrice" column="normal_price"/>
    <result property="promotionPrice" column="promotion_price"/>
    <result property="point" column="point"/>
    <result property="priority" column="priority"/>
    <result property="enableStatus" column="enable_status"/>
    <result property="createTime" column="create_time"/>
    <result property="lastEditTime" column="last_edit_time"/>
    <!--association: 多对一的关系-->
    <association property="productCategory" column="product_category_id" javaType="ProductCategory">
        <id property="productCategoryId" column="product_category_id"/>
        <result property="productCategoryName" column="product_category_name"/>
    </association>
    <!--association: 多对一的关系-->
    <association property="shop" column="shop_id" javaType="Shop">
        <id property="shopId" column="shop_id"/>
        <result property="shopName" column="shop_name"/>
        <result property="ownerId" column="owner_id"/>
    </association>
    <!--collection: 一对多的关系-->
    <collection property="productImgList" column="product_id" ofType="ProductImg">
        <id property="productImgId" column="product_img_id"/>
        <result property="productDetailImg" column="product_detail_img"/>
        <result property="productId" column="product_id"/>
    </collection>
</resultMap>


总结:

关于ResultMap:

  • resultMap主要用于保存多表关联查询结果,将查询结果映射为复杂类型的java对象(dto数据传输对象)。

  • resultMap使用<id>标签匹配主键字段;使用<result>标签匹配非主键字段。

  • <id> / <result>标签中的property属性对应实体类的属性;column属性对应数据库。表的字段

  • <association>标签用于多对一关联查询关系映射;<collection>标签用于一对多关联查询关系映射。

猜你喜欢

转载自blog.csdn.net/weixin_42950079/article/details/106182272