Java--Mybatis,mapper.xml文件使用association;collection实现一对一,一对多关联
Posted MinggeQingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java--Mybatis,mapper.xml文件使用association;collection实现一对一,一对多关联相关的知识,希望对你有一定的参考价值。
我们用JDBC访问数据库,除了需要自己写SQL之外,还必须操作Connection, Statement, ResultSet 这些其实只是辅助类。 不仅如此,访问不同的表,还会写很多雷同的代码,显得繁琐和枯燥。
使用了Mybatis之后,只需要自己提供SQL语句,其他的工作,诸如建立连接,Statement, JDBC相关异常处理等等都交给Mybatis去做了,那些重复性的工作Mybatis也给做掉了,我们只需要关注在增删改查等操作层面上,而把技术细节都封装在了我们看不见的地方。
今天主要说的是表关联查询,Mybatis中使用association和collection标签实现关联查询
Mybatis 一对一,使用 association 标签
Mybatis 一对多,使用 collection 标签
我们以User,Role表为例
<mapper namespace="XX.SysUserMapper">
<!--user用户表映射-->
<resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id" />
<result property="deptId" column="dept_id" />
<result property="userName" column="user_name" />
<result property="roleId" column="role_id" />
<result property="status" column="status" />
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap>
<!--dept部门表映射-->
<resultMap id="deptResult" type="SysDept">
<id property="deptId" column="dept_id" />
<result property="parentId" column="parent_id" />
<result property="deptName" column="dept_name" />
<result property="status" column="dept_status" />
</resultMap>
<!--role权限表映射-->
<resultMap id="RoleResult" type="SysRole">
<id property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="status" column="role_status" />
</resultMap>
<sql id="selectUserVo">
select u.user_id, u.dept_id, u.user_name, u.nick_name,
d.dept_id, d.parent_id, d.dept_name, d.status as dept_status,
r.role_id, r.role_name, r.status as role_status
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_role r on r.role_id = u.role_id
</sql>
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
<if test="userName != null and userName != ''">
AND u.user_name like concat(concat('%',#{userName}),'%')
</if>
<if test="status != null and status != ''">
AND u.status = #{status}
</if>
<if test="deptId != null and deptId != 0">
AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE FIND_IN_SET(#{deptId}, ancestors) <![CDATA[ <> ]]> 0 ))
</if>
</select>
</mapper>
在这里先说明一下
一、resultMap,id,type标签
type:对应的是我们的实体类,全路径名
id:可以理解为别名
id:唯一标识(一般为映射主键),此id值用于select元素属性的引用
column:对应我们数据库表中的字段名称
property:对应我们的实体类的属性,比如:User中的属性userName,要和数据库表user中的name对应。
result:标识一些简单属性,其中column属性代表数据库的字段名,property代表查询出来的字段名映射到实体类的某个属性
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
<if test="userName != null and userName != ''">
AND u.user_name like concat(concat('%',#{userName}),'%')
</if>
</select>
二、parameterType:MyBatis的传入参数
1、两种
(1)基本数据类型:int,string,long,Date
(2)复杂数据类型:类和Map
2、获取参数中的值
(1)基本数据类型:#{参数} 获取参数中的值
(2)复杂数据类型:#{属性名} ,map中则是#{key}
3、实例
3.1 基本数据类型案例
<sql id="Base_Column_List" >
id, car_dept_name, car_maker_name, icon,car_maker_py,hot_type
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from common_car_make
where id = #{id,jdbcType=BIGINT}
</select>
3.2 复杂类型--map类型
<select id="queryCarMakerList" resultMap="BaseResultMap" parameterType="java.util.Map">
select
<include refid="Base_Column_List" />
from common_car_make cm
where 1=1
<if test="id != null">
and cm.id = #{id,jdbcType=DECIMAL}
</if>
<if test="carDeptName != null">
and cm.car_dept_name = #{carDeptName,jdbcType=VARCHAR}
</if>
<if test="carMakerName != null">
and cm.car_maker_name = #{carMakerName,jdbcType=VARCHAR}
</if>
<if test="hotType != null" >
and cm.hot_type = #{hotType,jdbcType=BIGINT}
</if>
ORDER BY cm.id
</select>
3.3 复杂类型--类类型
<update id="updateByPrimaryKeySelective" parameterType="com.epeit.api.model.CommonCarMake" >
update common_car_make
<set >
<if test="carDeptName != null" >
car_dept_name = #{carDeptName,jdbcType=VARCHAR},
</if>
<if test="carMakerName != null" >
car_maker_name = #{carMakerName,jdbcType=VARCHAR},
</if>
<if test="icon != null" >
icon = #{icon,jdbcType=VARCHAR},
</if>
<if test="carMakerPy != null" >
car_maker_py = #{carMakerPy,jdbcType=VARCHAR},
</if>
<if test="hotType != null" >
hot_type = #{hotType,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
3.4 复杂类型--map中包含数组的情况
<select id="selectProOrderByOrderId" resultType="com.epeit.api.model.ProOrder" parameterType="java.util.HashMap" >
select sum(pro_order_num) proOrderNum,product_id productId,promotion_id promotionId
from pro_order
where 1=1
<if test="orderIds != null">
and
<foreach collection="orderIds" item="item" open="order_id IN(" separator="," close=")">
#{item,jdbcType=BIGINT}
</foreach>
</if>
GROUP BY product_id,promotion_id
</select>
三、resultType和resultMap
resultType:直接表示返回类型, 包括基本数据类型和复杂数据类型。
resultMap:外部定义的引用,通过对应的外部的id,表示结果映射到哪个上,一般用于字段名和属性名不一致的情况,或者需要做复杂的联合查询以便自由控制映射结果
四、association
映射到JavaBean的某个复杂的”数据类型”属性,仅处理一对一的关联关系。
<!--user用户表映射-->
<resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id" />
<result property="deptId" column="dept_id" />
<result property="userName" column="user_name" />
<result property="roleId" column="role_id" />
<result property="status" column="status" />
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap>
association的属性节点:
property:映射数据库列的实体对象属性名
javaType:完整的java类名和限定名;propert所映射的属性的类型
子元素
id:一般为映射主键,可以提高性能。
result:
column:映射的数据库的字段名。
property:映射的数据列对应的实体对象属性。
五、collection
映射到JavaBean的某个复杂的”数据类型”属性,这个属性是一个集合列表,处理一对多的关联关系。
其余和association基本一致。
association和collection都具备延迟加载功能。
延迟加载:先从单表查询,需要时再查关联表,大大的提高了数据库性能,因为相对来说单表查询比多表查询要快
以上是关于Java--Mybatis,mapper.xml文件使用association;collection实现一对一,一对多关联的主要内容,如果未能解决你的问题,请参考以下文章
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)