#与$的区别
我们在进行mybatis访问数据库的时候
经常会使用参数传递,这个时候就需要#或者$进行引用
那么这两个引用符号到底都是在什么时候使用呢?
我们先说相同点再说不同点
首先我们说区别,再实验
$符号:
使用这个sql主要是即时sql
即时SQL的访问程序主要是
语义分析 > SQL解析 > SQL优化 > SQL编译 > SQL执行
我们才能够肉眼看出来的就是其是直接替换占位符
假设使用string类型就会产生错误,因为是直接替换拼接,所以可能会导致sql注入的风险
使用string类型会导致失败是因为,直接替换而不是使用''包住,会导致BadSQL错误
比如
#符号:
这里主要是预编译SQL
相比即时SQL来说是有缓存的,相对来说性能更高
也会在替换占位符的时候携带类型插入等等
这里也可以防止SQL注入问题
我们使用#就可以完成任务
sql注入是什么?
sql注入就是当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。
假设我们指向查询id为1的数据
但是这时候我们被输入了 ' or 1 = '1
这时候使用$就会直接返回数据库里面的所有数据
类似于select * 的 操作
我们发现我们请求的内容和响应的内容并不相关
这可能导致黑客可以很轻易的查询出数据库中的内容
使用$的SQL注入解决方式
我们可以用无参接口代替代替传参(遍历所有需要的参数,将参数写死)
或者在查询之前加一层检验参数的合法性
但是$的使用也不是一无是处的,下面我们谈谈$的优点
假设这里我们需要进行一次查询并进行升序或者降序排列
这个时候使用$拼接就是符合要求的,这里的#就无法解决问题了
因为这里是不需要加上引号的,而使用#会默认进行加入引号的操作
但是为了防止SQL注入的问题
我们可以写一个升序和降序两个接口来代替传递参数的代码
模糊查询
MySQL中也存在like模糊查询
那么这里的模糊查询使用的是#还是$呢,我们用什么方式解决呢
话不多说,上测试
使用$轻松解决问题
使用#解决问题
为了防止sql注入,我们使用mysql内置的函数concat来解决问题
MySQL开发规范(常用)
对于表中的字段使用_连接
两个_之间不可以只有数字
_不可以作为开头
字段名一定要使用小写字母
表必备三个字段,即使表可能只有一列数据,也得加上id 创建时间 更新时间
动态SQL
对于不同的场景,我们对输入的参数也是有要求的
比如我们平常在淘宝进行筛选商品的时候
可以选择筛选条件,筛选条件可以有,也可以没有
上面我们写的这些SQL语句就是定死了的SQL
下面我们进行动态SQL的学习
以上是一个示例,下面我开始介绍平常的动态sql问题以及常见错误
首先我们说说navicat中如何修改表的约束
以上是当前表的约束选项
我们尝试实现
一个接口实现这里的前两条SQL
注意这里大部分的不设置的值都有默认值,不一定是null
这里引入xml中的if标签,本质上是字符串的拼接,根据java中有没有设置这个字段来确定是否拼接上去
我们来实现这个功能
if标签
此时我们已经初步实现了动态sql的编写
下面我们将所有参数都设置为可选填项
我们就会发现单单使用if语句会很难控制前面后面的逗号问题
比如insert into table1 values( ? ,?)
假设我们这里的第一个参数为空很容易就导致了badSQL问题
这里我们就可以引入第二个标签了
<trim>标签
学过java的都知道这个函数可以去除String的前后空格
但是这里,这个标签主要是处理前后缀的问题的
于是我们可以写出这样的代码
trim标签一共存在四个参数
prefix 表示前缀
prefixOverrides 表示整个语句块需要删除的前缀
suffix 表示后缀
suffixOverrides 表示整个语句块的后缀
这样就可以实现任意可选类型的参数是否输入的动态sql 了
下面我们来实现加入where筛选条件
我们也可以继续使用字符串的拼接来解决问题
where标签
但是我建议使用where标签来解决问题,更加省时省力
这里就筛选出来了name和password都为laoda的用户
set标签
下面再介绍一个set标签,在update语句中使用
此时我们发现已经修改成功了