Mybatis的映射器配置和动态SQL语句


1.背景介绍

       映射器是mybatis最复杂且最重要的组件。它由一个接口加上xml文件(或注解)组成。在映射器中可以配置参数、各类SQL语句、存储过程、缓存、级联等复杂的内容,并且通过简易的映射规则映射到指定的POJO或者其他对象上,映射器能够有效消除JDBC底层的代码。注解方式在实际开发中很少应用,因为其可读性比较差,不能很好的表达对应关系。

2.映射器配置元素

元素 说明
1.select 查询语句,可以自定义参数、返回结果
2.insert 插入语句,返回入条数
3.update 更新语句,返回影响行数
4.delete 删除语句,返回删除的行数
5.sql 定义部分固定的sql,方便其他地方使用
6.resultMap 声明结果集映射规则
7.cache 缓存配置

3.select元素-查询语句

   在映射器中select元素代表SQL的select语句,用于查询。使开发过程中用的最多的语句,多则意味着强大和复杂,select的配置元素一共有14种,这里我们介绍几种常用的元素。

元素 说明 备注
id           他和Mapper的命名空间组合起来是唯一的,供mybatis调用

如果命名空间和id结合起来不

唯一,mybatis将抛出异常

resultType                                       

定义类的全路径,在允许自动匹配的情况下,结果集将通过javaBean的规范映射;或定义为int、double、float、map等参数;

也可以使用别名,但要符合别名规范,切不能和resultMap同时使用            

常用参数,比如统计总条数,设为int,注意全路径引用
resultMap t它是映射集的引用,将执行强大的映射功能。resultMap能提供自定义映射规则的机会 mybatis最复杂的元素,可以配置映射规则、级联和typeHandler
parameterType 将会传入这条语句的参数类的完全限定名或别名。  
flushCache 无论语句什么时候被调用,都会导致缓存被清空。 Boolean类型默认值:false。
useCache 启动二级缓存开关,是否要求mybatis将此次结果缓存 Boolean类型默认值:true。
timeout 这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)  
fetchSize 这是暗示驱动程序每次批量返回的结果行数。默认不设置(驱动自行处理)  
statementType STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis使用选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。  


为了解决数据库表格字段和POJO类的属性名称不一致(mysql:create_time;student:createTime),可以在mybatis的配置文件的settings选项的mapUnderscoreToCamelCase,是控制驼峰映射的开关。

驼峰映射

 <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

驼峰映射对于命名规则有着严格的要求,有时不能满足项目中灵活应用,通常采用resultMap建立映射

<resultMap id="StudentDO" type="com.ptteng.classwork.pojo.StudentDO">
        <id column="add_id" property="addId"/>
        <result column="name" property="name"/>
        <result column="qq" property="qq"/>
        <result column="type" property="type"/>
        <result column="entor_time" property="entorTime"/>
        <result column="graduate_school" property="graduateSchool"/>
        <result column="net_id" property="netId"/>
        <result column="daily_link" property="dailyLink"/>
        <result column="wish" property="wish"/>
        <result column="senior" property="senior"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>

id colum对应数据库表格中的主键

别名设置:

为了简化resultType和parameterType的全路径引入,在

typeAliases
配置别名
  <typeAliases>
        <typeAlias type="java.lang.Integer" alias="int"/>
        <typeAlias type="java.util.List" alias="list"/>
        <!--对pojo对象较多的情况下,扫描包文件,自动默认小写命名,形成映射-->
        <package name="com.ptteng.classwork.pojo"/>
    </typeAliases>

@param注解传递参数,注意由于注解的指定,在mapper文件中不用再设置parameterType

   boolean updateType(@Param("type")String name,
                       @Param("updateTime")Long updateTime,
                       @Param("addId")int addId );
   <update id="updateType">
        UPDATE student_registrantion SET type=type=#{type},update_time=#{updateTime} WHERE add_id=#{addId}
    </update>

采用注解方式传递参数,代码简洁,可阅读性强,在参数少于5个情况下,优先选择。参数过多则采用bean类传递参数。

4.insert元素-插入语句

主键回填,元素属性

元素 描述 备注
useGeneratedKeys                                         是否启用JDBC的getGeneratedKeys方法来取出有数据库内部生成的主键。(数据库表格中的自增主键)                                                                                                                默认为false
keyPropery                w唯一标记一个属性,Mybatis会通过gettGeneratedKeys的返回值,或则insert语句的selectKey子元素设置它的键值 默认值unset,不能和keyColum连用
keyColumn t通过生成键值设置表格中的列名,这个设置仅在数据中是必须的,当主键列不是表格中的第一列时需要设置



从数据库中获取主键

  <insert id="saveStudent" parameterType="studentDO"
    useGeneratedKeys="true" keyProperty="addId">
        INSERT INTO student_registrantion (name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
        VALUES(#{name},#{qq},#{type},#{entorTime},#{graduateSchool},#{netId},#{dailyLink},#{wish},#{senior},#{createTime},#{updateTime})
    </insert>

自定义主键

     有的时候主键可能依赖于某些规则,比如取消表格中add_id的自增规则,而是将其规则修改为:

  • 当记录为空时,add_id=1
  • 当记录不为空时,add_id为当前id加3

当然也可以设定规则为最后一个插入的数据的值,来获取自增主键

<insert id="saveStudent" parameterType="studentDO">
        <selectKey keyProperty="addId" order="AFTER" resultType="int">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
        VALUES(#{addId},#{name},#{qq},#{type},#{entorTime},#{graduateSchool},#{netId},#{dailyLink},#{wish},#{senior},#{createTime},#{updateTime})
    </insert> 

4.动态SQL

MyBatis的动态SQL语句是基于OGNL表达式的。可以方便的在SQL语句中实现某些逻辑,总体说来MyBatis动态SQL语句主要有以下几类:
1、if语句(简单的条件判断)。
2、choose(when,otherwize),相当于Java语言中的switch,与JSTL中的choose很类似。 3、trim(对包含的内容加上prefix,或者suffix等,前缀,后缀)。
4、where(主要是用来简化SQL语句中where条件判断的,能智能的处理and or,不必担心多余导致语法错误)。
5、set(主要用于更新时)。
6、foreach(对集合的处理,在实现Mysql in语句查询时特别有用)

动态sql语句在场景中的应用

模糊查询

<select id="selectLikeNameNetId" parameterType="studentDO"
            resultType="studentDO">
        SELECT * FROM student_registrantion WHERE 1=1
        <choose>
            <when test="name !=null and name !=''" >
                and name like CONCAT(CONCAT('%',#{name},'%'))
            </when>
            <when test="netId !=null and netId !='' ">
                <bind name="pattern1" value="'%'+_parameter.netId+'%'"></bind>
                AND net_id LIKE #{pattern1}
            </when>
        </choose>
    </select>

choose when标签,相当于java中的switch case,匹配条件执行,条件符合则跳出判断

    <select id="selectLikeNameNetId" parameterType="studentDO"
            resultType="studentDO">
        SELECT * FROM student_registrantion
        <where>
            <if test="name !=null and name !=''" >
                NAME like CONCAT(CONCAT('%',#{name},'%'))
            </if>
            <if test="netId !=null and netId !='' ">
                <bind name="pattern1" value="'%'+_parameter.netId+'%'"></bind>
                AND net_id LIKE #{pattern1}
            </if>
        </where>
    </select>

where 标签默认匹配上下文的and or,两个属性共同参与判断,实现模糊查询

   <insert id="studentBatchInsert" parameterType="List" useGeneratedKeys="true" keyProperty="addId">
        INSERT INTO  student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
        VALUES
        <foreach collection= "list" item= "studentDO"  separator = ",">
            (#{studentDO.addId},#{studentDO.name},#{studentDO.qq},#{studentDO.type},#{studentDO.entorTime},#{studentDO.graduateSchool},
            #{studentDO.netId},#{studentDO.dailyLink},#{studentDO.wish},#{studentDO.senior},#{studentDO.createTime},#{studentDO.updateTime})
        </foreach>
    </insert>

全字段更新插入,判断属性为空则不更新,简化DAO

<!--根据主键全字段更新,if字段为空/为0,字段不更新-->
    <update id="updateStudent" parameterType="studentDO">
        UPDATE student_registrantion
     <!--trim标签替代关键字set-->
        <trim prefix="set" suffixOverrides=",">
            <if test="name !=null and name != ''">
                name=#{name},
            </if>
            <if test="qq !=null and qq != ''">
                qq=#{qq},
            </if>
            <if test="type !=null and type != ''">
                type=#{type},
            </if>
            <if test="entorTime !=null and entorTime != ''">
                entor_time=#{entorTime},
            </if>
            <if test="graduateSchool !=null and graduateSchool != ''">
                graduate_school=#{graduateSchool},
            </if>
            <if test="netId !=null and netId != ''">
                net_id=#{netId},
            </if>
            <if test="dailyLink !=null and dailyLink != ''">
                daily_link=#{dailyLink},
            </if>
            <if test="wish !=null and wish != ''">
                wish=#{wish},
            </if>
            <if test="senior !=null and senior != ''">
                senior=#{senior},
            </if>
            <if test="updateTime !=null and updateTime != ''">
                update_time=#{updateTime},
            </if>
        </trim>
         WHERE add_id=#{addId}
    </update>

批量插入

   <insert id="studentBatchInsert" parameterType="List" useGeneratedKeys="true" keyProperty="addId">
        INSERT INTO  student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
        VALUES
        <foreach collection= "list" item= "studentDO"  separator = ",">
            (#{studentDO.addId},#{studentDO.name},#{studentDO.qq},#{studentDO.type},#{studentDO.entorTime},#{studentDO.graduateSchool},
            #{studentDO.netId},#{studentDO.dailyLink},#{studentDO.wish},#{studentDO.senior},#{studentDO.createTime},#{studentDO.updateTime})
        </foreach>
    </insert>

foreach标签遍历集合,批量插入

猜你喜欢

转载自blog.csdn.net/qiaobao2018/article/details/80261908
今日推荐