Mybatis框架学习之使用篇二:标签语法
常用标签的使用姿势小结及参数绑定的三种方式
- select
- update
- delete
- insert
- choose, when, otherwise
- if
- bind
- foreach
- trim
- set
- where
I. 结构标签
xml中,一般常见的写法如下
1 | <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" > |
1. 结构说明
分析上面的demo,三个参数比较重要
- id:与dao层接口中定义的方法对应,不允许出现相同id的case
- resultMap: 出参
- resultType: 出参类型
- parameterType:传参类型
2. sql片段定义
一般我们查询时,大多不建议直接使用 select *
的方式,而是具体的写上查询的列,然后一个问题就来了,每个查询都得写上一遍,不仅麻烦,对于后续表结构标定时,需要改的地方要多,所以就有了sql片段定义
:通过该标签可定义能复用的sql语句片段,在执行sql语句标签中直接引用即可。这样既可以提高编码效率,还能有效简化代码,提高可读性
实际case
1 | <sql id="poetryEntity"> |
3. 常见标签
1 | - <select> 表示这是一个查询sql |
II. 内部标签
1. where
通常sql中,所有的where都可以被<where>
替换,而这个标签的主要作用是为了防止sql可能出现的异常状况,如以下几种case
a. case1 无查询条件
1 | select * from table where |
当id不存在时,导致上面的sql被解析为 select * from table where
, 显然这是一个非法sql
b. case2 最前or最后的连接条件
1 | select * from table where |
当id不存在,uname存在时,上面的sql被解析为 select * from table where and uname=#{uname
, 显然也是非法sql
所以,这种场景下,用<where>
标签优势就很明显了,在解析时,会根据实际的sql,来决定是否有where,是否去掉前面和后面非法的and/or
c. trim标签
除了直接使用where标签之外,更常见的一个就是
- prefix:前缀
- suffix:后缀
- prefixOverrides:忽略第一个指定分隔符
- suffixOverrides:会略最后一个分隔符
1 | <select id="user" parameterType="user" resultType="User"> |
2. foreach
用于循环的场景,如常见的 xxx in (xxx, xxx)
,通常就是foreach来使用
- collection:迭代的参数,一般是个列表or数组,值一般直接为参数名
- index: 迭代过程中,元素的别称
- open: 开始符号 如(
- close: 结束符号,如)
- separator:分割符号
一个实际case如下
接口为:
1 | List<PoetryEntity> queryPoetryByIds(@Param("ids") List<Long> ids); |
对应的sql为
1 | <select id="queryPoetryByIds" resultType="com.git.hui.demo.mybatis.entity.PoetryEntity"> |
3. Choose
选择标签,类似java中的switch,一旦其中一个条件匹配,整个choose块结束
一个xml如下
1 | <select id="getUserList_choose" resultMap="resultMap_user" parameterType="com.yiibai.pojo.User"> |
mybatis的这个选择,基本上和我们的switch语句一样, 对应关系如下
1 | <choose> ---- switch |
4. if
条件判断,在拼装sql时,最常见的就是为了防止传入null的参数,导致拼出一个业务逻辑有问题的sql,用if标签就很有用了
使用姿势也比较简单了,主要是内部的test条件判断
1 | <if test="sex != null and sex != ''"> |
5. set标签
更新的时候使用,同样是为了解决拼装成的sql中,最前面or最后面的英文逗号
1 | <update id="userUpdate" parameterType="user"> |
6. bind
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文
比如对于like查询,需要在参数的前面or后面加上 %
, 就可以这么玩:
1 | <select id="queryPoetryByContent" resultType="com.git.hui.demo.mybatis.entity.PoetryEntity"> |
上面的也可以使用concat来做,如下
1 | <select id="queryPoetryByContent" resultType="com.git.hui.demo.mybatis.entity.PoetryEntity"> |
III. 参数替换
dao层的参数,是如何传入到xml中的sql语句的呢?
1. map传递
dao层接口参数为map,xml中可以直接通过map中的key,来绑定参数
1 | public User selectUser(Map paramMap); |
假设传入的参数为两个,uname, password
对应的xml为
1 | <select id=" selectUser" resultMap="BaseResultMap"> |
2. 参数位置替换
这种是直接根据参数的索引位置来绑定, {0} 表示第一个参数, {1} 表示第二个参数
1 | public User selectUser(String uname, String password); |
对应的xml
1 | <select id=" selectUser" resultMap="BaseResultMap"> |
3. 注解指定方式
通过 @Param注解,直接指定name,在sql中即可通过name方式引用
1 | public User selectUser(@Param("uname") String uname, @Param("password") String password); |
对应的sql为
1 | <select id=" selectUser" resultMap="BaseResultMap"> |
4. $#区别
使用#传入参数是,sql语句解析是会加上””,
比如 select * from table where name = #{name}
,传入的name为小李,那么最后打印出来的就是
select * from table where name = "小李"
,就是会当成字符串来解析
因此在动态排序时,比如 order by column
,这个时候务必要用${},因为如果你使用了#{}
区别
#
将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号$
将传入的数据直接显示生成在sql中#
方式能够很大程度防止sql注入$
方式无法防止Sql注入$
方式一般用于传入数据库对象,例如传入表名,列名
简单来说,两者区别: $ 是sql替换,直接拼成一条可执行sql; # 是参数替换
IV. 其他
项目工程
个人博客: 一灰灰Blog
基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
声明
尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840