[转]MyBatis动态传入表名、字段名参数的解决办法
一直在使用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 id="getUser" resultType="java.util.Map" parameterType="java.lang.String" statementType="STATEMENT">
select
${columns}
from ${tableName}
where COMPANY_REMARK = ${company}
</select>
要实现动态调用表名和字段名,就不能使用预编译了,需添加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等),这样实现日志的分月分表存储,方便日志的分析。
参考文章:http://www.yuanrengu.com/index.php/mybatis1021.html
[转]MyBatis动态传入表名、字段名参数的解决办法的更多相关文章
- MyBatis动态传入表名,字段名参数的解决办法---statementType用法
statementType="STATEMENT" 要实现动态传入表名.列名,需要做如下修改 添加属性statementType="STATEMENT" 同时s ...
- MyBatis动态传入表名,字段名参数的解决办法
原文:http://blog.csdn.net/xichenguan/article/details/50393748 要实现动态传入表名.列名,需要做如下修改 添加属性statementType=& ...
- mybatis动态传入表名、列名
原文:http://luoyu-ds.iteye.com/blog/1517607 要实现动态传入表名.列名,需要做如下修改 添加属性statementType=”STATEMENT” (可省略) 同 ...
- MyBatis动态传入表名
mybatis里#{}与${}的用法: 在动态sql解析过程,#{}与${}的效果是不一样的: #{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符. 如以下 ...
- MyBatis,动态传入表名,字段名的解决办法
转载:http://luoyu-ds.iteye.com/blog/1517607 今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的, 本来这也不是 ...
- mybatis动态调用表名和字段名
以后慢慢启用个人博客:http://www.yuanrengu.com/index.php/mybatis1021.html 一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用 ...
- 【死磕jeesite源码】mybatis动态调用表名和字段名
本文转载自夏雪冬日 一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能.今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字 ...
- KO ------- 表中字段名和实体类属性名不一致
-----------------------siwuxie095 KO ------- 表中字段名和实体类属性名不一致 如果数据库表中的字段名和实体类的属性名不一致,那么在查询时, 相应字段的结果就 ...
- MyBatis学习总结4--解决字段名与实体类属性名不相同的冲突
在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定是完全相同的,如果直接在xml映射文件中使用sql进行映射,会造成返回值为空的情况,下面阐述解决方案: 测试所用表和数据 create t ...
随机推荐
- 二: drf视图
Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 一:请求与响应 1:request Request 1 REST f ...
- 微信端修改title
function setTitle(t) { document.title = t; var i = document.createElement('iframe'); i.src = "i ...
- C# 文件/文件夹压缩解压缩
项目上用到的,随手做个记录,哈哈. 直接上代码: using System; using System.Data; using System.Configuration; using System.C ...
- [Hibernate] One-To-Many 配置文件和注解的方式以及HQL语句
一对多需要在一的类配置多的类的set泛型集合. 多的一端需要添加一的类作为属性,其和数据库对应的是对应表的主键. 一个购物车有多个商品,购物车有个cart_id作为主键,商品除了自己的items_id ...
- vue 日历组件只显示本月和下个月 -- 多选日期
效果就是上图 代码贴出 1.在components > calander > index.vue <template> <div class="page&quo ...
- Descriptors;Hello1 project中的Web.xml
Deployment Descriptors(描述符)是一个xml文件,用来描述如何部署一个模块或者应用(根据描述符中定义的配置和容器选项).举例来说,一个EJB的部署描述符会向EJB容器传递如何管理 ...
- ELK安装使用教程
一.说明 ELK是当下流行的日志监控系统.ELK是Elasticsearch.Logstash.Kibana三个软件的统称. 在ELK日志监控系统中,Logstash负责读取和结构化各类日志+发送给E ...
- mac上配置java开发环境
项目在mac上跑起来的步骤: 1. 访问,https://brew.sh/ 装上这个然后 brew install git brew install maven, settings.xml需要放 ...
- 微信小程序中对于变量的定义
在页面对应的js文件中: page顶部使用let定义变量,这是定义的全局变量,在当前脚本页面,任何函数中都可以直接使用变量名调用.如果做修改,就直接使用变量等于要更改的值. 使用const定义变量,就 ...
- Spring Boot + Spring Cloud 实现权限管理系统 (Spring Security 版本 )
技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro 也足够好用并且简单,但对于 Spring 官方主推的安全框架 Spring Security,用户群也是甚大的,所以我们这 ...