Mybatis学习总结第三课----使用XML配置SQL映射器详解

     关系型数据库和SQL是经受时间考验和验证的数据存储机制。和其他的ORM框架如Hibernate不同,MyBatis鼓励开发者可以直接使用数据库,而不是将其对开发者隐藏,因为这样可以充分发挥数据库服务器所提供的SQL语句的巨大威力。与此同时,MyBaits消除了书写大量冗余代码的痛苦,它让使用SQL更容易。在代码里直接嵌套SQL语句是很差的编码实践,并且维护起来困难。MyBaits使用了映射文件或注解来配置SQL语句。
    

           

一、 select 查询元素

  select 主要要来做查询使用

<sql id="Base_Column_List">
		id, user_name, real_name, sex, mobile, email, note,position_id
	</sql>

	<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
		select
		<include refid="Base_Column_List" />
		from t_user
		where id = #{id,jdbcType=INTEGER}
	</select>

自动映射
      前提:SQL列名和JavaBean的属性是一致的;
      自动映射等级autoMappingBehavior设置为PARTIAL,需要谨慎使用FULL;
 使用resultType;
         如果列名和JavaBean不一致,但列名符合单词下划线分割,Java是驼峰命名法,
         则mapUnderscoreToCamelCase可设置为true;
传递多个查询入参
 使用map传递参数;可读性差,导致可维护性和可扩展性差,杜绝使用;
  使用注解传递参数;直观明了,当参数较少一般小于5个的时候,建议使用;
 使用Java Bean的方式传递参数;当参数大于5个的时候,建议使用;

如:

/**
     * 是map作为入参
     * 使用map传递参数;可读性差,导致可维护性和可扩展性差,不建议这样使用
     * @param param
     * @return
     */
    List<TUser> selectByEmailAndSex1(Map<String, Object> param);

    /**
     *使用注解传递参数;直观明了,当参数较少一般小于5个的时候,建议使用
     * @param email
     * @param sex
     * @return
     */
    List<TUser>  selectByEmailAndSex2(@Param("email") String email, @Param("sex") Byte sex);

    /**
     * 使用Java Bean的方式传递参数;当参数大于5个的时候,建议使用
     * @param esb
     * @return
     */
    List<TUser> selectByEmailAndSex3(EmailSexBean esb);

mapper 中对应:

	<select id="selectByEmailAndSex1" resultMap="BaseResultMap" parameterType="map">
		select
		id, user_name, real_name, sex, mobile, email, note,position_id
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>

	<select id="selectByEmailAndSex2" resultMap="BaseResultMap">
		select
		id, user_name, real_name, sex, mobile, email, note,position_id
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>


	<select id="selectByEmailAndSex3" resultMap="BaseResultMap" 
			parameterType="com.study.mybatis.entity.EmailSexBean">
		select
		id, user_name, real_name, sex, mobile, email, note,position_id
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>

二 resultMap元素 属性

       resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出
来,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。
      ResultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。

<resultMap id="BaseResultMap" type="com.study.mybatis.entity.TUser">
		<!-- <constructor>
			<idArg column="id" javaType="int"/>
			<arg column="user_name" javaType="String"/>
		</constructor>  -->
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="user_name" property="userName" jdbcType="VARCHAR" />
		<result column="real_name" property="realName" jdbcType="VARCHAR" />
		<result column="sex" property="sex" jdbcType="TINYINT" />
		<result column="mobile" property="mobile" jdbcType="VARCHAR" />
		<result column="email" property="email" jdbcType="VARCHAR" />
		<result column="note" property="note" jdbcType="VARCHAR" />
		<result column="position_id" property="positionId" jdbcType="INTEGER" />
	</resultMap>
    <!--可以继承-->
	<resultMap id="userAndJobs2" extends="BaseResultMap" type="TUser">
		<collection property="jobs" fetchType="lazy" column="id"
			select="com.enjoylearning.mybatis.mapper.TJobHistoryMapper.selectByUserId" />
	</resultMap>

2.1 resultMap子属性

   

2.2 id & result 

     id 和 result 都将一个列的值映射到一个简单数据类型(字符串,整型,双精度浮点数,日期等)的属性或字段。
     两者之间的唯一不同是, id 表示的结果将是对象的标识属性,这会在比较对象实例时用到。 这样可以
提高整体的性能,尤其是缓存和嵌套结果映射(也就是联合映射)的时候。

2.3 constructor

      一个pojo不存在没有参数的构造方法,就需要使用constructor;
      为了通过名称来引用构造方法参数,你可以添加 @Param 注解,指定参数名称的前提下,以任意顺序编写
arg 元素

          

 

三 insert, update 和 delete

     主要做数据增删改使用

       

3.1 selectKey元素

3.2 sql元素和参数

四、注解方式配置

    

 @Results(id="jobInfo",value={
    		@Result(property="id",column="id",id = true),
    		@Result(property="userId",column="user_id"),
    		@Result(property="compName",column="comp_name"),
    		@Result(property="years",column="years"),
    		@Result(property="title",column="title")
    })
    @Select("select id, user_id, comp_name, years, title from t_job_history"
    		+ "	where user_id = #{userId}")
    List<TJobHistory> selectByUserId(int userId);
    
    @ResultMap("jobInfo")
    @Select("select id, user_id, comp_name, years, title from t_job_history")
    List<TJobHistory> selectAll();
    
    @Insert("insert into t_job_history (id, user_id, comp_name,	years, title)"
    		+ "	values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER},"
    		+ "#{compName,jdbcType=VARCHAR},"
    		+ "#{years,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR})")
    @Options(useGeneratedKeys=true,keyProperty="id")
    int insert(TJobHistory record);

五 动态sql元素

     

    

5.1 if 标签


     if 标签通常用于 WHERE 语句、UPDATE 语句、INSERT 语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。

<select id="selectIfandWhereOper" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		<where>
			<if test="email != null and email != ''">
				and a.email like CONCAT('%', #{email}, '%')
			</if>
			<if test="sex != null ">
				and a.sex = #{sex}
			</if>
		</where>
	</select>

5.2 where 标签

当 if 标签较多时,这样的组合可能会导致错误。 如下:

<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">
    SELECT * from STUDENT WHERE
    <if test="name!=null and name!='' ">
        NAME LIKE CONCAT(CONCAT('%', #{name}),'%')
    </if>
    <if test="hobby!= null and hobby!= '' ">
        AND hobby = #{hobby}
    </if>
</select>


    当 name 值为 null 时,查询语句会出现 “WHERE AND” 的情况,解决该情况除了将"WHERE"改为“WHERE 1=1”之外,还可以利用 where
标签。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以 AND 或 OR 开头的,则它会剔除掉。

<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">
    SELECT * from STUDENT
    <where>
        <if test="name!=null and name!='' ">
            NAME LIKE CONCAT(CONCAT('%', #{name}),'%')
        </if>
        <if test="hobby!= null and hobby!= '' ">
            AND hobby = #{hobby}
        </if>
    </where>
</select>

5.3 set 标签


       没有使用 if 标签时,如果有一个参数为 null,都会导致错误。当在 update 语句中使用 if 标签时,如果最后的 if 没有执行,则或导致逗号多余错误。使用 set 标签可以将动态的配置 set
关键字,和剔除追加到条件末尾的任何不相关的逗号。

<update id="updateStudent" parameterType="Object">
    UPDATE STUDENT SET
    <if test="name!=null and name!='' ">
        NAME = #{name},
    </if>
    <if test="hobby!=null and hobby!='' ">
        MAJOR = #{major},
    </if>
    <if test="hobby!=null and hobby!='' ">
        HOBBY = #{hobby}
    </if>
    WHERE ID = #{id};
</update>


使用 set+if 标签修改后,如果某项为 null 则不进行更新,而是保持数据库原值。

<update id="updateStudent" parameterType="Object">
    UPDATE STUDENT
    <set>
        <if test="name!=null and name!='' ">
            NAME = #{name},
        </if>
        <if test="hobby!=null and hobby!='' ">
            MAJOR = #{major},
        </if>
        <if test="hobby!=null and hobby!='' ">
            HOBBY = #{hobby}
        </if>
    </set>
    WHERE ID = #{id};
</update>

5.4 foreach 标签

foreach 标签主要用于构建 in 条件,可在 sql 中对集合进行迭代。也常用到批量删除、添加等操作中。

<!-- in查询所有,不分页 -->
<select id="selectIn" resultMap="BaseResultMap">
    select name,hobby from student where id in
    <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>


属性介绍:

collection:collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合。
item :表示在迭代过程中每一个元素的别名
index :表示在迭代过程中每次迭代到的位置(下标)
open :前缀
close :后缀
separator :分隔符,表示迭代时每个元素之间以什么分隔

 

5.5 choose 标签

   有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis 提供了 choose 元素,按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when
的条件都不满则时,则执行 otherwise 中的 sql。类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

   if 是与(and)的关系,而 choose 是或(or)的关系。

<select id="getStudentListChoose" parameterType="Student" resultMap="BaseResultMap">
    SELECT * from STUDENT WHERE 1=1
    <where>
        <choose>
            <when test="Name!=null and student!='' ">
                AND name LIKE CONCAT(CONCAT('%', #{student}),'%')
            </when>
            <when test="hobby!= null and hobby!= '' ">
                AND hobby = #{hobby}
            </when>
            <otherwise>
                AND AGE = 15
            </otherwise>
        </choose>
    </where>
</select>

5.6trim标签

trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefixsuffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverridessuffixOverrides。正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where/set标签的功能,示例代码如下:

trim代替where标签:

<!-- 5.1 if/trim代替where(判断参数) - 将实体类不为空的属性作为where条件 -->  
<select id="getStudentList_if_trim" resultMap="resultMap_studentEntity">  
    SELECT ST.STUDENT_ID,  
           ST.STUDENT_NAME,  
           ST.STUDENT_SEX,  
           ST.STUDENT_BIRTHDAY,  
           ST.STUDENT_PHOTO,  
           ST.CLASS_ID,  
           ST.PLACE_ID  
      FROM STUDENT_TBL ST   
    <trim prefix="WHERE" prefixOverrides="AND|OR">  
        <if test="studentName !=null ">  
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')  
        </if>  
        <if test="studentSex != null and studentSex != '' ">  
            AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}  
        </if>  
        <if test="studentBirthday != null ">  
            AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}  
        </if>  
        <if test="classId != null and classId!= '' ">  
            AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}  
        </if>  
        <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">  
            AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}  
        </if>  
        <if test="placeId != null and placeId != '' ">  
            AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}  
        </if>  
        <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">  
            AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}  
        </if>  
        <if test="studentId != null and studentId != '' ">  
            AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}  
        </if>  
    </trim>     
</select> 

trim代替set标签

<!-- 5.2 if/trim代替set(判断参数) - 将实体类不为空的属性更新 -->  
<update id="updateStudent_if_trim" parameterType="liming.student.manager.data.model.StudentEntity">  
    UPDATE STUDENT_TBL  
    <trim prefix="SET" suffixOverrides=",">  
        <if test="studentName != null and studentName != '' ">  
            STUDENT_TBL.STUDENT_NAME = #{studentName},  
        </if>  
        <if test="studentSex != null and studentSex != '' ">  
            STUDENT_TBL.STUDENT_SEX = #{studentSex},  
        </if>  
        <if test="studentBirthday != null ">  
            STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},  
        </if>  
        <if test="studentPhoto != null ">  
            STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},  
        </if>  
        <if test="classId != '' ">  
            STUDENT_TBL.CLASS_ID = #{classId},  
        </if>  
        <if test="placeId != '' ">  
            STUDENT_TBL.PLACE_ID = #{placeId}  
        </if>  
    </trim>  
    WHERE STUDENT_TBL.STUDENT_ID = #{studentId}  
</update> 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值