网站建设与管理学习收获,wordpress 锚文本插件,哈尔滨seo搜索优化公司排名,wordpress文章选择标签一直在使用Mybatis这个ORM框架#xff0c;都是使用mybatis里的一些常用功能。今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示#xff0c;如某张表的某些字段不让用户查询到。这种情况下#xff0c;就需要构建sql来动态传入表名、字段…一直在使用Mybatis这个ORM框架都是使用mybatis里的一些常用功能。今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示如某张表的某些字段不让用户查询到。这种情况下就需要构建sql来动态传入表名、字段名了。现在对解决方法进行下总结希望对遇到同样问题的伙伴有些帮助。
动态SQL是mybatis的强大特性之一mybatis在对sql语句进行预编译之前会对sql进行动态解析解析为一个BoundSql对象也是在此处对动态sql进行处理。下面让我们先来熟悉下mybatis里**#{}与${}**的用法
在动态sql解析过程#{}与${}的效果是不一样的
#{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符。
如以下sql语句
select * from user where name #{name};会被解析为
select * from user where name ?;可以看到#{}被解析为一个参数占位符。
${ } 仅仅为一个纯碎的 string 替换在动态 SQL 解析阶段将会进行变量替换
如以下sql语句
select * from user where name ${name};当我们传递参数“sprite”时sql会解析为
select * from user where name sprite;可以看到预编译之前的sql语句已经不包含变量name了。
综上所得
${ } 的变量的替换阶段是在动态 SQL 解析阶段而 #{ }的变量的替换是在 DBMS 中。
#{}与${}的区别可以简单总结如下
#{}将传入的参数当成一个字符串会给传入的参数加一个双引号
${}将传入的参数直接显示生成在sql中不会添加引号
#{}能够很大程度上防止sql注入${}无法防止sql注入
${}在预编译之前已经被变量替换了这会存在sql注入的风险。如下sql
select * from ${tableName} where name ${name}如果传入的参数tableName为user; delete user; --那么sql动态解析之后预编译之前的sql将变为
select * from user; delete user; --where name ?;–之后的语句将作为注释不起作用顿时我和我的小伙伴惊呆了看到没本来的查询语句竟然偷偷的包含了一个删除表数据的sql是删除删除删除重要的事情说三遍可想而知这个风险是有多大。
${}一般用于传输数据库的表名、字段名等
能用#{}的地方尽量别用${}
进入正题通过上面的分析相信大家可能已经对如何动态调用表名和字段名有些思路了。示例如下
select ${columns} from ${tableName}where COMPANY_REMARK ${company}要实现动态调用表名和字段名就不能使用预编译了需添加statementType“STATEMENT” 。
statementTypeSTATEMENT(非预编译)PREPARED(预编译)或CALLABLE中的任意一个这就告诉 MyBatis 分别使用StatementPreparedStatement或者CallableStatement。默认PREPARED。这里显然不能使用预编译要改成非预编译。
其次sql里的变量取值是${xxx},不是#{xxx}。
因为${}是将传入的参数直接显示生成sql如${xxx}传入的参数为字符串数据需在参数传入前加上引号如
String name “sprite”;
name “’” name “’”;
mybatis动态调用表名和字段名还可以应用于日志的收集上如数据库的日志表每隔一个月动态建一个日志表表名前缀相同(如log_201610,log_201611等)这样实现日志的分月分表存储方便日志的分析。