Mybatis中一对多(collection)和一对一(association)的组合查询使用
作者:huangyaa729
这篇文章主要介绍了Mybatis中一对多(collection)和一对一(association)的组合查询使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Collection
collection
: 一个复杂的类型关联,许多结果将映射为这种类型property
: 这是关联的 JavaBean 中的属性名, 在 RoleModel 中对应 private List<MenuModel> menus;javaType
: property 属性对应的集合类型ofType
: property 集合中的泛型,即定义时泛型所表示的具体类型column
: RoleModel 的 id ,作为参数传入被调用的 Select 语句
用法,嵌套在其他的查询说sql中,写法 主要以下3种:
第一种:select 语句在其他dao.java对应的 mapper.xml中
<collection property="tProductVideos" ofType="com.pasture.mpi.provider.biz.model.auto.TProductVideo" column="product_id" select="com.mpi.biz.dao.cust.ProductDao.getProductList"> </collection>
第二种:select语句在同一个mapper.xml中
(与第一种的区别在于select属性的值不一样)
..... <collection property="tProductVideos" ofType="com.pasture.mpi.provider.biz.model.auto.TProductVideo" column="product_id" select="getProductList"> </collection> ...... <resultMap id="BaseProduct" type="com.mpi.biz.model.auto.TProduct"> <id column="id" property="id" jdbcType="INTEGER" /> <result column="product_id" property="productId" jdbcType="INTEGER" /> <result column="image_url" property="imageUrl" jdbcType="VARCHAR" /> <result column="type" property="type" jdbcType="CHAR" /> </resultMap> <select id="getProductImageList" resultMap="BaseProduct" parameterType="java.lang.Integer"> SELECT i.id, i.product_id, i.image_url,i.type FROM t_product_image i WHERE i.product_id = #{productId} </select>
第三种,如果再一个查询中可以直接查询到所需要的数据
但是需要映射到该对象的属性上,则可以使用该方式(建议使用上两种,看起来更清晰):
<resultMap id="BaseRoleResultMap" type="cn.com.hellowood.springsecurity.model.RoleModel"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="is_active" property="isActive" jdbcType="BOOLEAN"/> <result column="description" property="description" jdbcType="VARCHAR"/> <result column="last_update_time" property="lastUpdateTime" jdbcType="TIMESTAMP"/> <collection property="menus" ofType="com.pasture.mpi.provider.biz.model.auto.TProductVideo" javaType="java.util.ArrayList"> <id column="id" property="id" jdbcType="INTEGER" /> <result column="product_id" property="productId" jdbcType="INTEGER" /> <result column="image_url" property="imageUrl" jdbcType="VARCHAR" /> <result column="type" property="type" jdbcType="CHAR" /> </collection> </resultMap> <select id="getRoles" parameterType="java.lang.Integer" resultMap="BaseRoleResultMap"> SELECT r.id, r.name, r.description, r.is_active, r.last_update_time, m.id, m.value, m.display_value, m.url, m.category, m.description, m.is_active, m.last_update_time FROM table1 r LEFT JOIN t_product p ON r.id = p.r_id WHERE r.id = #{roleId,jdbcType=INTEGER} </select>
association总结
主要用到的属性:
property
:映射数据库列的字段或属性。column
:数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。javaType
:完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。resultMap
:一个可以映射联合嵌套结果集到一个适合的对象视图上的ResultMap。这是一个替代的方式去调用另一个select语句。
association查询与主查询一般写在一个文件中,如下:
第一种:不另外写查询语句
(1)把返回的属性提取出来
<association property="product" resultMap="ResultMapWithBLOBs"/>
(2)糅合在一起
<association property="category" javaType="com.provider.biz.model.auto.TCategory"> <id column="category_id" property="categoryId" jdbcType="INTEGER"/> <result column="c_name" property="name" jdbcType="VARCHAR"/> <result column="image_url" property="imageUrl" jdbcType="VARCHAR"/> <result column="c_status" property="status" jdbcType="CHAR"/> </association>
第二种:另外写查询语句
<resultMap id="testMap" type="xxx" > <id property="id" column="id" jdbcType="DECIMAL" /> <result property="startDateStr" column="startDateStr" jdbcType="VARCHAR" /> <result property="endDateStr" column="endDateStr" jdbcType="VARCHAR" /> <association property="tableEntity" column="table_a_id" select="selectById"></association> </resultMap> <select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select * from Table_XXX where a_id=#{aId} (注:这里的aId即为上述传的参数值table_a_id,只传一个参数时名称可以不一样) </select>
第三种:与collection一样
提到外面其他的dao接口中,此处省略…
补充:
association的使用要特别注意下,数据映射时会出现异常,再一次的项目中就出现过实际有5条数据,但返回到service层时只有1条数据,这一条数据各个部分的信息还不对应,通过打印mysql执行语句和逐条排查,发现是association标签的问题;
切记,association使用时<resultMap id="testMap" type="xxx" >中一定要有 <id>标签,否则会出现返回的数据与实际查询结果不一致的问题
多参数传递
当需要传递多个值时,写法如下:
column= “{prop1=col1,prop2=col2}
接收的类型为 parameterType=“java.util.Map”,这里的参数使用时名称要保持一致;
例:
<resultMap id="testMap" type="xxx" > <id property="id" column="id" jdbcType="DECIMAL" /> <result property="startDateStr" column="startDateStr" jdbcType="VARCHAR" /> <result property="endDateStr" column="endDateStr" jdbcType="VARCHAR" /> <association property="tableEntity" column="{reqId=id,endDate=endDateStr,startDate=startDateStr}" select="selectById"> </association> </resultMap> <select id="selectById" parameterType="java.util.Map" resultMap="BaseResultMap">
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。