一、#{} ${} 的区别
-
{}是预编译处理,${}是字符串替换。
- mybatis在处理
#{}
时,会将sql中的#{}
替换为?号,调用PreparedStatement的set方法来赋值。
mybatis在处理${}
时,就是把${}
替换成变量的值。 - 使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。
- 预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
二、JdbcType
说明
数据库列字段都是有类型的,不同的数据库有不同的类型。为了表示这些数据类型,Java源码是采用枚举来定义的:
public enum JDBCType implements SQLType {
TINYINT(Types.TINYINT),
SMALLINT(Types.SMALLINT),
INTEGER(Types.INTEGER)
}
枚举变量也是有类型的,也是有值的,正如整数变量是整数类型,也有值大小一样,上述枚举变量值的定义是通过Types来描述刻画的。
public class Types {
public final static int TINYINT = -6;
public final static int SMALLINT = 5;
public final static int INTEGER = 4;
}
常用类型对照表
不同数据库的JdbcType稍微有些不同,不必刻意去记。
JDBC 类型 | Java Type |
---|---|
CHAR | String |
VARCHAR | String |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
BIGINT | long |
FLOAT | double |
DOUBLE | double |
REAL | float |
INTEGER | INTEGER |
SMALLINT | short |
TINYINT | byte |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
JdbcType类型的作用
在Mybatis明文建议在映射字段数据时需要将JdbcType属性加上,这样相对来说是比较安全的。
<insert id="test">
insert into role values (
#{roleId},
#{name},
#{remarks},
#{orderNo},
#{createBy,jdbcType=VARCHAR},
#{createDept,jdbcType=VARCHAR},
#{createTime,jdbcType=DATE},
#{updateBy,jdbcType=VARCHAR},
#{updateTime,jdbcType=DATE}
)
</insert>
保证了前四种是不能为空的前提下,而后面几项为空时也不至于程序报错。如果createBy为空,插入的时候mybatis不知道具体转换成什么jdbcType类型,通常会使用一个默认设置,虽然默认配置一般情况下不会出错,但是遇到个别情况还是会有问题的。Mybatis经常出现的:无效的列类型: 1111 错误,就是因为没有设置JdbcType造成的
网友评论