Mybatis动态调用表名和字段名的解决方法

 更新时间:2016年10月12日 16:09:26   作者:猿人谷  
今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,这种情况下,就需要构建sql来动态传入表名、字段名了,下面给大家介绍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动态调用表名和字段名的解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

本文转自:http://www.yuanrengu.com/index.php/mybatis1021.html

相关文章

  • 浅谈java中HashMap键的比较方式

    浅谈java中HashMap键的比较方式

    今天带大家了解一下java中HashMap键的比较方式,文中有非常详细的解释说明及代码示例,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • Spring @Transactional注解失效解决方案

    Spring @Transactional注解失效解决方案

    这篇文章主要介绍了Spring @Transactional注解失效解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • springboot实现文件上传步骤解析

    springboot实现文件上传步骤解析

    这篇文章主要介绍了springboot实现文件上传步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Spring Cloud Alibaba Nacos 入门详解

    Spring Cloud Alibaba Nacos 入门详解

    这篇文章主要介绍了Spring Cloud Alibaba Nacos入门详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • 解决spring懒加载以及@PostConstruct结合的坑

    解决spring懒加载以及@PostConstruct结合的坑

    这篇文章主要介绍了解决spring懒加载以及@PostConstruct结合的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringMVC自定义拦截器实现过程详解

    SpringMVC自定义拦截器实现过程详解

    这篇文章主要介绍了SpringMVC自定义拦截器实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java中由substring方法引发的内存泄漏详解

    Java中由substring方法引发的内存泄漏详解

    这篇文章主要介绍了Java中由substring方法引发的内存泄漏详解,涉及substring方法引发的内存泄漏简介,substring的作用和实现原理等相关内容,具有一定借鉴价值,需要的朋友可以参考下
    2017-12-12
  • SpringCloud之Admin服务监控实现流程示例详解

    SpringCloud之Admin服务监控实现流程示例详解

    这篇文章主要为大家介绍了SpringCloud之Admin服务监控流程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • java基于正则提取字符串中的数字功能【如提取短信中的验证码】

    java基于正则提取字符串中的数字功能【如提取短信中的验证码】

    这篇文章主要介绍了java基于正则提取字符串中的数字功能,可用于提取短信中的验证码,涉及java基于正则的字符串匹配相关操作技巧,需要的朋友可以参考下
    2017-01-01
  • springboot连接不同数据库的写法详解

    springboot连接不同数据库的写法详解

    这篇文章主要介绍了springboot连接不同数据库的写法 ,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04

最新评论