Mybatis中使用#{}可以防止sql注入

#{}: 表示一个占位符号,实现向PreparedStatement占位符中设置值(#{}表示一个占位符?),自动进行Java类型到JDBC类型的转换(因此#{}可以有效防止SQL注入).#{}可以接收简单类型或PO属性值,如果parameterType传输的是单个简单类型值,#{}花括号中可以是value或其它名称.

: 表 示 拼 接 S Q L 串 , 通 过 {}: 表示拼接SQL串,通过:表示拼接SQL串,通过{}可将parameterType内容拼接在SQL中而不进行JDBC类型转换,可 以 接 收 简 单 类 型 或 P O 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 的 是 单 个 简 单 类 型 值 , {}可以接收简单类型或PO属性值,如果parameterType传输的是单个简单类型值,可以接收简单类型或PO属性值,如果parameterType传输的是单个简单类型值,{}花括号中只能是value.

虽然不 能 防 止 S Q L 注 入 , 但 有 时 {}不能防止SQL注入,但有时不能防止SQL注入,但有时{}会非常方便(如order by排序,需要将列名通过参数传入SQL,则用ORDER BY ${column},使用#{}则无法实现此功能.

防止sql注入的原理:

先看下面用占位符来查询的一句话

String sql = “select * from administrator where adminname=?”;

psm = con.prepareStatement(sql);

String s_name =“zhangsan’ or ‘1’='1”;

psm.setString(1, s_name);

假设数据库表中并没有zhangsan这个用户名,

用plsql运行sql语句,可以查出来所有的用户名,但是在Java中并没有查出任何数据,这是为什么呢?

首先,setString()的源码中只有方法名字,并没有任何过程性处理,

那么答案肯定出现在Java到数据库这个过程中,也就是mysql和oracle驱动包中,在mysql驱动包中,PreparedStatement继承并实现了jdk中的setString方法,

也就是原因在于数据库厂商帮你解决了这个问题,下面就看看这个方法的具体实现:

可以看出数据驱动代码中对传入的参数首尾加了引号,并且对参数中的引号进行了转义,所以在数据库中真正执行的是把参数作为一个字符串格式来处理,如果是整数类型字段会自动cast类型。

spring #{} 可以使用SpEL表达式,${}可以获取应用配置文件中的配置值

1 @Value("#{}") SpEL表达式

@Value("#{}") 表示SpEl表达式通常用来获取bean的属性,或者调用bean的某个方法。当然还有可以表示常量

@RestController

@RequestMapping("/login")

@Component

public class LoginController {

@Value("#{1}")

private int number; //获取数字 1

@Value("#{'Spring Expression Language'}") //获取字符串常量

private String str;

@Value("#{dataSource.url}") //获取bean的属性

private String jdbcUrl;

@Autowired

private DataSourceTransactionManager transactionManager;

@RequestMapping("login")

public String login(String name,String password) throws FileNotFoundException{

System.out.println(number);

System.out.println(str);

System.out.println(jdbcUrl);

return "login";

}

}

[email protected](#{""}) 获取其他bean的属性,或者调用其他bean的方法时,只要该bean (Beab_A)能够访问到被调用的bean(Beab_B),即要么Beab_A 和Beab_B在同一个容器中,或者Beab_B所在容器是Beab_A所在容器的父容器。(拿我上面贴出来的代码为例在springMvc项目中,dataSource这个bean一般是在springContext.xml文件中申明的,而loginController这个bean一般是在springMvc.xml文件中申明的,虽然这两个bean loginController和dataSource不在一个容器,但是loginController所在容器继承了dataSource所在的容器,[email protected]("#{dataSource.url}")能够获取到dataSource的url属性)。

2 @Value("${}")

[email protected]("${}") 可以获取对应属性文件中定义的属性值。假如我有一个sys.properties文件 里面规定了一组值: web.view.prefix =/WEB-INF/views/

在springMvc.xml文件中引入下面的代码既即以在 [email protected]("w e b . v i e w . p r e f i x " ) 获 取 这 个 字 符 串 。 需 要 指 出 的 是 , 如 果 只 在 s p r i n g M v c . x m l 引 入 下 面 代 码 , 只 能 在 s p r i n g M v c . x m l 文 件 中 扫 描 或 者 注 册 的 b e a n 中 才 能 通 过 @ V a l u e ( " {web.view.prefix}")获取这个字符串。需要指出的是,如果只在springMvc.xml引入下面代码,只能在springMvc.xml文件中扫描或者注册的bean中才能[email protected]("web.view.prefix")获取这个字符串。需要指出的是,如果只在springMvc.xml引入下面代码,只能在springMvc.xml文件中扫描或者注册的bean中才能通过@Value("{web.view.prefix}")获取这个字符串,其他未在springMvc.xml扫描和定义的bean必须在相应的[email protected]("${}”)表达式

然后再controller文件中通过下面代码即可获取“”/WEB-INF/views/“”这个字符串

@Value("${web.view.prefix}")

private String prefix;

最新文章

  1. cgi web 调用多次启动_CGI、FastCGI和PHPFPM有什么关系呢?
  2. python读取txt文件代码-python批量处理txt文件的实例代码
  3. Exception in thread “main“ org.apache.ibatis.exceptions.PersistenceException奇葩解决方案
  4. centos minimal 安装无法自定义分区
  5. 【手把手教你树莓派3 (二)】 启动wifi模块
  6. 央视曝光!朋友圈八大骗局正在瞄准你的个人信息 看看你中招没?
  7. 什么是软件测试中的黑天鹅
  8. LeetCode刷题(18)
  9. python items() 函数的使用(一分钟读懂)
  10. iosTableView 局部全部刷新以及删除编辑操作
  11. Java概 述(新手专区)
  12. python 序列去重并保持原始顺序
  13. 基于Vue的移动端图片裁剪组件 vue-clip(完美兼容ios与安卓)
  14. debian 安装teamviewer
  15. 数据学习(十)-假设检验
  16. 磊科路由器信号按键_磊科怎么隐藏wifi信号 磊科路由器如何隐藏wifi信号?-192路由网...
  17. xp系统 自动锁定计算机,xp如何设置锁屏时间
  18. 修改电脑qq的聊天背景
  19. 介绍一款LaTeX编辑器——LyX
  20. (Modern Family S01E01) Part 11 PhilClair Luke和Phil打篮球 总

热门文章

  1. 【OS学习笔记】五 VirtualBox的下载、安装和配置
  2. maven 解决冲突
  3. Linux系统添加永久静态路由的方法
  4. Linux服务部署之NTP时间服务器
  5. 原生js简单实现双向数据绑定原理
  6. 《C++ Primer Plus(第六版)》(25)(第十三章 类继承 笔记)
  7. 140. Word Break II
  8. [Leetcode][第78题][JAVA][子集][位运算][回溯]
  9. 站怎么点都是一样_老鼠被卡在轮胎里,像是被点了穴道一样:这可怎么办才好?...
  10. java菜单面板设置完能关闭_用Java创建一个屏幕外框架(或者:当所有应用程序窗口关闭时,如何避免Mac上的空白菜单)?...