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>

三、resultTyperesultMap

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实现一对一,一对多关联的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis学习04mapper代理方法开发dao

IDEA创建Mapper.xml文件识别不成功的问题

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

找不到映射文件mapper.xml解决方法

mapper.xml怎么写当前时间

mapper.xml的使用