Mybatis标签总结

一、标签内容

功能

标签名称

定义sql

select

insert

delete

update

动态sql

if

连用标签

choose

when

otherwise

trim

where

set

foreach

定义常量

sql

表信息定义

resultMap 

Mybatis中mapper.xml

注意事项:sql结尾不用加;号

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wounler.dao.UserInfoMapper">
    <!-- 表定义信息 -->
    <resultMap id="BaseResultMap" type="com.wounler.pojo.UserInfo">
        <id column="user_id" jdbcType="VARCHAR" property="userId"/>
        <result column="user_name" jdbcType="VARCHAR" property="userName"/>
        <result column="sex" jdbcType="VARCHAR" property="sex"/>
        <result column="age" jdbcType="NUMERIC" property="age"/>
        <result column="create_date" jdbcType="DATE" property="createDate"/>
    </resultMap>
    <!-- 定义常量 -->
    <sql id="Base_Column_List">
        USER_ID,USER_NAME,SEX,AGE,CREATE_DATE
    </sql>
    <sql id="userInfoMap">
        <where>
            <if test="userId != null and userId != ''">
                user_id = #{userId}
            </if>
            <if test="userId != null and userId != ''">
                and user_name = #{userName}
            </if>
        </where>
    </sql>
    <!--select标签查看所有数据-->
    <select id="getUserList" resultMap="BaseResultMap">
        select * from user_info
    </select>
    <!--select标签查看指定条件的数据-->
    <select id="userList" parameterType="com.wounler.pojo.UserInfo" resultMap="BaseResultMap">
        select
            <include refid="Base_Column_List"/>
        from user_info where user_name = #{userName}
    </select>
    <!--update标签更新指定条件的数据-->
    <update id="updateUserInfo" parameterType="java.util.Map">
        update user_info set user_name = #{userName},age = #{age} where user_id=#{userId}
    </update>
    <!--update标签和set标签where标签的连用-->
    <!--where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
    但是第一个判断我们明知道时第一个数据,前面就不用加“AND” 或 “OR”-->
    <!--set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
    但是最后一个判断我们明知道时最后一个数据,后面就不用加逗号了-->
    <update id="updateUserInfoByTag" parameterType="java.util.Map">
        update user_info
        <set>
            <if test="sex != null and sex != ''">
                user_name = #{sex,jdbcType=VARCHAR},
            </if>
            <if test="age!= null and age!= ''">
                age = #{age,jdbcType=NUMERIC}
            </if>
        </set>
        <where>
            <if test="userId!= null and userId!= ''">
                user_id <![CDATA[<>]]> #{userId,jdbcType=VARCHAR}
            </if>
            <if test="userName != null and userName != ''">
                and user_name = #{userName,jdbcType=VARCHAR}
            </if>

        </where>
        <!--此处where也可以用 <include refid="userInfoMap"/> -->
    </update>

</mapper>

二、标签解读        

select 标签的使用

属性

描述

id

在空间命名中唯一的标识符,可以被用来引用这条语句。如:id=”key”

parameterType

将要传入这条语句的参数类的完全限定名或别名 例:com.test.poso.User或user。这个属性是可选的,因为mybatis可以通过TypeHandler推断出具体传入语句的参数,默认值是unset(“未设置”或者解释成“依赖驱动”)。如:parameterType=”java.lang.String”

resultType

语句返回值类型或别名。注意,如果是集合,那么这里填写的是集合的泛型,而不是集合本身(resultType 与resultMap 不能并用)。如resultType=”java.lang.String”

resultMap

外部resultMap的命名引用。如:resultMap=”BaseResultMap”

Insert、update、delete 标签的使用

属性

描述

id

在空间命名中唯一的标识符,可以被用来引用这条语句。如:id=”key”

parameterType

将要传入这条语句的参数类的完全限定名或别名 例:com.test.poso.User或user。这个属性是可选的,因为mybatis可以通过TypeHandler推断出具体传入语句的参数,默认值是unset(“未设置”或者解释成“依赖驱动”)。如:parameterType=”java.lang.String”

keyProperty

仅对insert和update有用,唯一标记一个属性,mybatis会通过getGeneratedKeys的返回值或者通过insert语句的select Key子元素设置它的键值,默认为unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表

foreach 标签的使用

属性

描述

item表示本次迭代获取的元素,若collection为List、Set或者数组,则表示其中的元素;若collection为map,则代表key-value的value,该参数为必选。item 的值是本次迭代获取到的元素,需要与#{}中的字符保持一致
open表示该语句以什么开始,最常用的是左括弧’(’,注意:mybatis会将该字符拼接到整体的sql语句之前,并且只拼接一次,该参数为可选项
close表示该语句以什么结束,最常用的是右括弧’)’,注意:mybatis会将该字符拼接到整体的sql语句之后,该参数为可选项
separatormybatis会在每次迭代后给sql语句append上separator属性指定的字符,该参数为可选项。设置foreach生成的多条记录之间的分割符,可以根据自己的需要设置,比如“,”,"and"之类的
index在list、Set和数组中,index表示当前迭代的位置,在map中,index代指是元素的key,该参数是可选项。索引(index)代表变量,index 是当前迭代的序号
collection请看下面有关collection的描述

三、实例讲解

1、#{}和${}区别

        1)、#和$两者含义不同
#{} 占位符、${} 拼接符
#会把传入的数据都当成一个字符串来处理,会在传入的数据上面加上双引号,变量替换后,#{} 对应的变量自动加上单引号#{} 能防止sql 注入
而$则是把传入的数据直接显示在sql语句中,不会添加双引号。变量替换后,${} 对应的变量不会加上单引号${} 不能防止sql 注入
        2)、举例说明
其中如果传入的username类型为字符型,比如输入zhangsan,那么username=#{username}#表示的就是username=”zhangsan”,如果传入的username类型为数值类型,比如输入11,那么username=#{username}#表示的就是username=”11”。
其中如果传入的username类型为整型类型,那么在执行sql语句时就不会出错,但是如果传入的username类型为字符串型,比如输入zhangsan,那么username=${username}就会变成username=zhangsan,执行会报错,所以sql语句必须写成下面这样。

#{} 和 ${} 的实例:假设传入参数为 1
(1)开始
1)#{}:select * from t_user where uid=#{uid}
2)${}:select * from t_user where uid= '${uid}'
(2)然后
1)#{}:select * from t_user where uid= ?
2)${}:select * from t_user where uid= '1'
(3)最后
1)#{}:select * from t_user where uid= '1'
2)${}:select * from t_user where uid= '1'

        3)、#{} 和 ${} 在使用中的技巧和建议
(1)不论是单个参数,还是多个参数,一律都建议使用注解@Param("")
(2)能用 #{} 的地方就用 #{},不用或少用 ${}
(3)表名作参数时,必须用 ${}。如:select * from ${tableName}
(4)order by 时,必须用 ${}。如:select * from t_user order by ${columnName}
(5)使用 ${} 时,要注意何时加或不加单引号,即 ${} 和 '${}'


2、foreach 也就是遍历迭代,在SQL中通常用在 in 这个关键词的后面

foreach元素的属性主要有 item,index,collection,open,separator,close。
分别代表:
item表示集合中每一个元素进行迭代时的别名,要和#{}中的名字保持一致
index用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符,
close表示以什么结束

关于collection属性
首先需要知道mybatis怎么处理参数的,传递给XXXMapper接口方法的所有参数会被放到一个map中(后面叫这个map为M),假设存在参数properties:

  1. 传递List类型的参数,则会在M里有一条 {"list" : properties },所以此时collection设置为“list”就等于拿出M中key="list"的value,然后遍历它。
  2. 传递数组类型参数, 则会在M里有一条{"array", properties},所以此时需要设置collection="array".
  3. 传递Map类型的参数, 不会做任何转换,假设你的Map类型的参数中包含的是{"china" :"beijing", "usa":"w.d.c"}, 那么M中就有两条映射:{"china" :"beijing", "usa":"w.d.c"} 。
  4. 如果传入的是一个bean,那么的bean中的属性作为key,属性值作为value放到M中。
  5. 如果传入的是一个基本类型变量,那么M中就会存在一条key是变量名,value是变量值(由于jdk7之前反射无法拿到参数名,可以使用下面介绍的注解)。

综上,collection能够指定的值就是M中最终存在的key,<foreach>标签从M中拿到key的value,然后遍历value,所以这个value必须是能够被遍历的对象。

以上都是假设你没有在Mapper的接口方法上使用mybatis提供的注解org.apache.ibatis.annotations.Param注解参数名时collection的默认值,如果你在参数上使用了这个注解,那么最终M中的key是注解名,value是参数值,如下:

public interface PersonMapper {
  void insertPerson1(@Param("map") Map<String, Person> persons);
}

使用注解时M中就存在一条"map" -> persons的映射,而不是上面介绍的把persons的key,value直接方到M中

那么可以在PersonMapper.xml中:
<insert id="insertPerson1">
        INSERT INTO mybatis.person VALUES
        <foreach collection="map" index="key" item="person" separator=",">
            (#{person.name}, #{person.age})
        </foreach>
</insert>

这里collection="map", 相当于拿到M.get("map")的值,也就是persons, 
然后遍历persons, 遍历的结果是index是persons的key, item是对应的value

而最为重要的就是collection属性了,既然是迭代就表示传入的参数是多个,这时候传入的参数就有以下几种可能:

1. 传入的参数为list(set的话,替换掉list就行了)的时候

<!-- 对应的Dao中的Mapper文件是: -->
public List<User> selectByIds(List<Integer> ids);

<!-- 如果Mapper文件参数中增加@Param(vale="ages") ,则下面需要这样写collection="ages"-->
<!-- xml文件代码片段: -->
<select id="selectByIds" resultType="com.wounler.pojo.User">
    select * from user where id in
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
         #{item}
    </foreach>
</select>

假设接口中传递的list如下所示:

List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");

可以看到的是foreach标签指定了逗号作为分隔符,那么mybatis将会解析出foreach标签里面的内容作为一个整体然后再其后面拼接上逗号分隔符,拼接后的过程如下所示:

(                                               //第一步,拼接open指定的开始字符
('zhangsan'                             //第二步,迭代集合,拼接对应的item
('zhangsan',                            //第三步,拼接separator指定的分隔符
('zhangsan','lisi'                      //第四步,迭代集合,拼接对应的item
('zhangsan','lisi',                     //第五步,拼接separator指定的分隔符
('zhangsan','lisi','wangwu'     //第六步,迭代集合,拼接对应的item
('zhangsan','lisi','wangwu')    //第七步,拼接close指定的闭合字符

最终结果是:

('zhangsan','lisi','wangwu')

如果在foreach标签前面加上select … from table where … in ,将会变形成

SELECT * FROM user WHERE user_name in ('zhangsan','lisi','wangwu')

2. 传入的参数为Array的时候

<!-- 对应的Dao中的Mapper文件是: -->
public List<User> selectByIds(int[] ids);

<!-- 如果Mapper文件参数中增加@Param(vale="ages") ,则下面需要这样写collection="ages"-->
<!-- xml文件代码片段: -->
<select id="selectByIds" resultType="com.wounler.pojo.User">
    select * from user where id in
    <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

3. 传入的参数为Map的时候
        map的时候需要注意的是:collection的值“ids”是存储在map中的key(比如:map.put("ids",ids));尤其需要注意;

<!-- 对应的Dao中的Mapper文件是: -->
<!-- params.add("ids",list) -->
public List<User> selectByIds(Map<String, Object> params);

<!-- xml文件代码片段: -->
<select id="selectByIds" resultType="com.wounler.pojo.User">
select * from user where  id in
    <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

四、注意事项

1、split方法:colleation=”prodNum.split(‘,’)”

2、<sql id=”Base_Column_LIst”></sql>    <include refid=”Base_Column_LIst”/>需要结合使用

3、以下标签需要结合使用<choose><when></when><otherwise></otherwise></choose>

4、对象.属性的形式:If(test=”person.name != null and person.name != ‘’”)

5、size方法:list.size > 0

6、toString方法,判断条件为等于的时候,常量需要加 .toString() 来转换,这种方法是稳定的,推荐使用:age ==  '0'.toString()

7、不等于号:!=、<![CDATA[<>]]> 
术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。
在 XML 元素中,"<" 、">" 和 "&" 是非法的。
"<" 会产生错误,因为解析器会把该字符解释为新元素的开始。">",解析器会把该字符解释为新元素的结束
"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
<![CDATA[   ]]> 是什么,这是XML语法。在CDATA内部的所有内容都会被解析器忽略。
因此"<"、“>”、“<>”,需要用<![CDATA[<]]>、<![CDATA[>]]>、<![CDATA[<=]]>、<![CDATA[>=]]>、<![CDATA[<>]]>

8、括号的运用:test="(grtrList != null and grtrList.size > 0) or (grteList != null and grteList.size > 0)"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值