Mybatis-4-映射文件详解2

简介: 今天继续记录下Mybatis细化的一些特性。

上篇看了简单的增删改查标签的使用及官网的介绍,第一次见那么全面的官网,点赞!

今天继续记录下细化的一些特性。

一、参数

       在xml中,参数是很常用的,每一个语句都用到参数,大多数的情况下,我们你只须简单指定属性名,顶多要为可能为空的列指定 jdbcType,其他的事情交给 MyBatis 自己去推断就行了吗,比如下面:

<updateid="updateByPrimaryKey"parameterType="com.xing.generator.model.User">updateusersetuserName=#{username,jdbcType=VARCHAR},
passWord=#{password,jdbcType=VARCHAR},
realName=#{realname,jdbcType=VARCHAR}
whereid=#{id,jdbcType=INTEGER}
</update>

我们就指定了一个jdbcType=VARCHAR,其他的都交给Mybatis框架自己默认就好。不过也可以了解下在复杂的场景下可以使用哪些属性。

<selectid="selectUsers"resultType="User">selectid, username, passwordfromuserswhereid=#{id}
</select>

上面的这个示例说明了一个非常简单的命名参数映射。鉴于参数类型(parameterType)会被自动设置为 int,这个参数可以随意命名。原始类型或简单数据类型(比如 Integer 和 String)因为没有其它属性,会用它们的值来作为参数。

然而,如果传入一个复杂的对象,行为就会有点不一样了。比如:

<insertid="insertUser"parameterType="User">insertintousers (id, username, password)
values (#{id}, #{username}, #{password})
</insert>

如果 User 类型的参数对象传递到了语句中,会查找 id、username 和 password 属性,然后将它们的值传入预处理语句的参数中,当然也可以自己指定javaType=int:

#{property,javaType=int,jdbcType=NUMERIC}

不指定的话,Mybatis可以根据参数对象的类型确定 javaType。这里特殊情况是该对象是一个 HashMap。这个时候,你需要显式指定 javaType 来确保正确的类型处理器(TypeHandler)被使用。

#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

对于数值类型,还可以设置 numericScale 指定小数点后保留的位数。

#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

下面这几句我就没玩过了:

【mode 属性允许你指定 IN,OUT 或 INOUT 参数。如果参数的 mode 为 OUT 或 INOUT,将会修改参数对象的属性值,以便作为输出参数返回。如果 mode 为 OUT(或 INOUT),而且 jdbcType 为 CURSOR(也就是 Oracle 的 REFCURSOR),你必须指定一个 resultMap 引用来将结果集 ResultMap 映射到参数的类型上。要注意这里的 javaType 属性是可选的,如果留空并且 jdbcType 是 CURSOR,它会被自动地被设为 ResultMap。

#{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}

MyBatis 也支持很多高级的数据类型,比如结构体(structs),但是当使用 out 参数时,你必须显式设置类型的名称。比如(再次提示,在实际中要像这样不能换行):

#{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentResultMap}

二、字符串替换

       这里其实就是说的 #{} 和${}了,面试的时候可能会提问这两的区别。

默认情况下,使用 #{} 参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样),如果只传入一个参数的话名字可以随意取。

       #{value}会被传入的内容替换,替换的时候将传入的内容当成字符串,加上引号:

# 例如传入的内容为123,sql语句会变为

selectcount(*) fromuserwhereage='23'

这样做更安全,更迅速,通常也是首选做法.

不过有时你就是想直接在 SQL 语句中直接插入一个不转义的字符串。

# 比如 ORDER BY 子句,这时候你可以:

ORDERBY${columnName}

# 再比如 替换表名的情况 同样适合用

selectcount(*) from${tableName} whereage='100'

结论就是:${value} 会被直接替换,而 #{value} 会使用 ? 预处理。

$会导致潜在的 SQL 注入攻击。因此,要么不允许用户输入这些字段,要么自行转义并检验这些参数,动态参数还是要用#。



总结:

       参数一般情况下不需要刻意指定,Mybatis根据参数类型会自动映射对应的类型,也可以指定一个jdbcType,其他的交给Mybatis搞就可以。

       $ 和 # 的区别,# 相当于是使用了预处理,调用preparedStatement的setString方法传入参数可以防止sql注入,安全性更高。$会将传入的内容替换,注意此处是直接替换,不会加上引号,如果是如表名、字段名等写死的字段不让用户输入,那可以用$,不然会有sql注入的安全风险。


END











目录
相关文章
|
8月前
|
SQL Java 数据库连接
|
20天前
|
Java 数据库连接 数据库
mybatis的@MappedTypes
mybatis的@MappedTypes
39 1
|
8月前
|
SQL Java 数据库连接
|
9月前
|
SQL Java 数据库连接
Mybatis Plus
Mybatis Plus
|
9月前
|
SQL XML 存储
MyBatis(上)
MyBatis(上)
|
9月前
|
SQL Java 数据库连接
MyBatis(下)
MyBatis(下)
|
10月前
|
SQL XML Java
什么是 Mybatis?
什么是 Mybatis?
52 0
|
10月前
|
SQL XML 算法
MyBatis-Plus
简称MP,是在Mybatis的基础上进行增强,用户简化开发,提高效率。只做增强不做改变 支持主键自动生成、内置代码生成器、内置分页插件
73 0
|
11月前
|
SQL XML 存储
Mybatis总结
Mybatis总结
88 0
|
11月前
|
SQL 缓存 IDE