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>标签用于一对多关联查询关系映射。