一直在使用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”" 。

statementType:STATEMENT(非预编译),PREPARED(预编译)或CALLABLE中的任意一个,这就告诉 MyBatis 分别使用Statement,PreparedStatement或者CallableStatement。默认:PREPARED。这里显然不能使用预编译,要改成非预编译。

其次,sql里的变量取值是${xxx},不是#{xxx}。

因为${}是将传入的参数直接显示生成sql,如${xxx}传入的参数为字符串数据,需在参数传入前加上引号,如:

String name = “sprite”;

name= “’” + name + “’”;

mybatis动态调用表名和字段名,还可以应用于日志的收集上,如数据库的日志表,每隔一个月动态建一个日志表,表名前缀相同(如log_201610,log_201611等),这样实现日志的分月分表存储,方便日志的分析。

mybatis获取表名——mybatis动态调用表名和字段名#{},${}相关推荐

  1. mybatis获取表名_mybatis动态调用表名和字段名

    一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能.今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字段不让用户查询到.这 ...

  2. mybatis动态调用表名和字段名

    一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能.今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字段不让用户查询到.这 ...

  3. mysql 动态 建表,mysql数据库动态创建表的实例分享

    摘要 腾兴网为您分享:mysql数据库动态创建表的实例分享,易视云3,完美root,刷机大师,手游宝等软件知识,以及清仓兔,找明星,爱普生1500w,txt完结小说全本软件,windows自带画图软件 ...

  4. mysql 存储过程 动态建表_MySQL存储过程动态创建表,数据分表

    BEGIN DECLARE `@i` int(11); DECLARE `@siteCount` int(11); DECLARE `@sqlstr` VARCHAR(2560); DECLARE ` ...

  5. php如何拼接变量名,php动态拼接变量名,可变变量,动态变量,使用花括号,使用两个$符...

    php动态拼接变量名,可变变量,动态变量,使用花括号,使用两个$符 方式一:使用花括号,前缀部分不需要用单引号 $nums10 = 100; $xxx*${bcount.$nums10}['m54'] ...

  6. Mybatis使用statementType=STATEMENT实现动态传入表名或字段名

    mybatis中使用statementType="STATEMENT"实现动态传入字段名时一直报语句错误,但实际上语句并没有毛病,爬了一天坑才找到问题,记录一下.  整条语句中里所 ...

  7. java方法调用之动态调用多态(重写override)的实现原理——方法表

    转自:http://blog.csdn.net/fan2012huan/article/details/51007517 上两篇篇博文讨论了java的重载(overload)与重写(override) ...

  8. DBA必知的170张Oracle常用动态性能表介绍

     DBA必知的170张Oracle常用动态性能表介绍 常用动态性能表.pdf 附录C 动态性能(V$)视图 本附录介绍动态性能视图.这些视图一般作为V$视图引用.本附录包括下列内容: ???? 动态性 ...

  9. 一个简单的动态内表alv案例

    动态内表的问题一直没搞明白,每次都要复制粘贴. 动态内表的创建和使用主要有以下几点: 1.动态内表的创建,首先要定义动态结构,然后再根据定义的动态结构利用系统一个标准的method:"cl_ ...

最新文章

  1. python 判断子序列_LeetCode 392. 判断子序列 | Python
  2. [51nod1847][算法马拉松23(飞越愚人节)F]奇怪的数学题
  3. 正泰eplan_【万泉河】给EPLAN初学者的建议:不用宏
  4. 多行文本溢出显示省略号
  5. fft qt 代码_最简洁的FFT代码(C++实现)
  6. JavaScript之Ajax-1 Ajax(Ajax原理、Ajax对象属性和方法)
  7. screenfetch 和 linux_logo安装使用
  8. 随手记android面试题,synchorinzed的一个面试题
  9. Java爬虫高级教程-动力节点
  10. 概率论与数理统计(陈希孺)笔记2.2
  11. 一种 Python 获取时间序列数据集的方式
  12. 干货 | 在搜索引擎广告关键词生成上,算法可以做什么?
  13. opencore 引导 近完美 黑苹果EFI(技嘉H310/I5-9400F/RX560D)
  14. apollo学习之---(19)commen-filter学习
  15. [转载]Malcolm的新书:Outliers
  16. 微信小程序中页面跳转时要始终返回首页的问题
  17. java List去除重复数据的五种方式
  18. JavaScript - 解析JSON
  19. NGFF、M.2、NVME、SATA、PCIE、USB的层次和区别:协议?接口?
  20. fl2440串口编程

热门文章

  1. c ++查找字符串_C ++朋友功能| 查找输出程序| 套装1
  2. 求阶乘的第一个非零数字_查找数字阶乘中的尾随零
  3. 网际控制报文协议icmp_网络中的ICMP(Internet控制消息协议)
  4. 十六进制转八进制c++代码_如何将十六进制代码上传到微控制器?
  5. python随机抽签列表中的同学值日_神奇的大抽签--Python中的列表_章节测验,期末考试,慕课答案查询公众号...
  6. 测试私有方法 重构_一个全栈工程师重构之路:中小公司 DevOps 落地实践
  7. 计算机组成原理输入实验报告,计算机组成原理实验报告
  8. Python获取电脑硬件配置的封装类,可以获取CPU序列号、主板序列号、BIOS序列号、硬盘序列号和网卡MAC地址
  9. CentOS7搭建部署Ambari 2.6.2.0最新版(HDP-UTILS、HDP-GPL)大数据平台
  10. 如何利用shell脚本和client-go实现自己的k8s调度器