最近在使用Mybatis的过程中遇到了一些问题,感觉有必要总结一下。前面一段时间简单的看了一点Mybatis的源码,对Mybatis在项目启动过程中以及启动后执行查询的工作流程有了一个大概的了解。这周开始我又到另一个项目,这是一个微服务项目,不过我只参与了一个服务的开发,项目使用的是Mybatis,但是并不是使用xml的方式,而是注解的方式,这也是我第一次在项目中使用注解的方式开发,中间也遇到了一些问题,这里做一个总结。
其实在前面Mybatis源码分析(一)的过程中有提到过Mybatis的注解,但是我一直习惯使用xml方式,所以并没有专门去了解注解的方式。这次总结主要还是专注于使用中遇到的问题。
一、一对多查询问题。
开发这么久也是我第一次需要使用一对多查询,为了方便我自己写了一点简单的代码,来模拟这样一个问题。首先我有2个model,分别是order和product,从业务上来讲我一个订单可能有多个product,所以model的定义如下:
@Data
public class Order {
private String userid;
private String province;
private String city;
private String street;
private String orderid;
}
@Data
public class Product {
private String orderid;
private String productname;
private Integer count;
private String price;
private String skucode;
}
@Data
public class CustomOrder {
private String userid;
private String province;
private String city;
private String street;
private String orderid;
private List<String> productList;
}
CustomOrder中有一个productList的属性,存储的是某订单所有Product的skucode属性。当然productList也可以是所有商品的全部属性。
1、使用Mapper.xml文件
1.1 多表查询
其实首先容易想到的就是关联表查询,sql如下:
select o.*,p.skucode from t_order o left join t_product p on o.orderid = p.orderid where o.userid = ?;
查询的结果如下:
图-1.png
其实这个结果并不是我想要的,我希望最后一列的skucode多行数据转一行数据,即根据userid等列分组,也就是这种结果:
图-2.png
这个方式可以直接通过sql的方式实现,我们如果使用Mybatis的xml方式又该如何实现呢?其实查询的sql并不需要改变,只需要在进行结果映射的时候将查询的skucode放入到映射的model的productList属性即可,即映射到CustomOrder的productList属性中,xml如下:
<mapper namespace="com.ypc.mybatis.mapper.OrderMapper">
<resultMap id="BaseResultMap" type="com.ypc.mybatis.model.CustomOrder">
<result column="userid" jdbcType="VARCHAR" property="userid" />
<result column="province" jdbcType="VARCHAR" property="province" />
<result column="city" jdbcType="VARCHAR" property="city" />
<result column="street" jdbcType="VARCHAR" property="street" />
<result column="orderid" jdbcType="VARCHAR" property="orderid" />
<collection property="productList" ofType="string" javaType="list">
<result column="skucode"/>
</collection>
</resultMap>
<sql id="Base_Column_List">
userid, province, city, street, orderid
</sql>
<select id="selectByUserId" resultMap="BaseResultMap">
select o.*,p.skucode
from t_order o left join t_product p on o.orderid = p.orderid where o.userid = #{userId}
</select>
</mapper>
上面的xml中最主要的就是"<collection>"标签,"property"表示的是映射的model的属性,即CustomOrder的属性名称,ofType表示的是映射的集合中类型的名称,javaType表示的是集合类型,里面的还有多个标签