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

作者:猿人谷 时间:2022-03-18 16:54:14 

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

标签:mybatis,动态,表名,字段名
0
投稿

猜你喜欢

  • mybatis框架xml下trim中的prefix与suffix等标签的用法

    2023-09-20 18:55:24
  • Java这个名字的来历与优势

    2023-03-27 18:28:40
  • 史上最全图文讲解Java泛型

    2022-08-23 20:27:47
  • Spring实现处理跨域请求代码详解

    2023-11-25 12:28:34
  • Java OkHttp框架源码深入解析

    2023-11-29 03:22:50
  • C++实现图书管理系统

    2023-11-03 03:00:35
  • Java中Map集合的常用方法详解

    2021-12-31 16:05:54
  • SpringBoot实现Excel文件批量上传导入数据库

    2023-11-29 11:13:44
  • redis统计APP在线人数的实例

    2023-11-24 23:56:54
  • SpringBoot Nacos实现自动刷新

    2023-09-16 04:17:09
  • Mybatis分页插件使用方法详解

    2021-10-12 06:59:30
  • 详解ArrayList的扩容机制

    2022-06-18 05:56:32
  • 简单谈谈Java中的栈和堆

    2022-07-30 05:33:01
  • Java Annotation注解相关原理代码总结

    2023-11-18 02:13:57
  • Java实现图片验证码具体代码

    2021-06-30 13:16:35
  • java对象初始化代码详解

    2023-09-19 13:59:01
  • spring mvc中@PathVariable / 带斜杠方式获取

    2022-09-15 04:47:27
  • Java调用wsdl接口的两种方法(axis和wsimport)

    2023-06-23 14:41:22
  • 为什么Java开发需要配置环境变量

    2023-08-13 13:11:03
  • Java实现小型图书馆管理系统

    2021-06-14 04:27:35
  • asp之家 软件编程 m.aspxhome.com