Mybatis动态传入tableName--非预编译(STATEMENT)
在使用Mybatis过程中,你可以体会到它的强大与灵活之处,由衷的为Mybatis之父点上999个赞!在使用过程中经常会遇到这样一种情况,我查询数据的时候,表名称是动态的从程序中传入的,比如我们通过mybatis的xml文件写sql查询时都是下面的样子:
1、正常的查询
1
2
3
|
<select id="activityEnrollModelTableName" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT * FROM user WHERE userid = #
</select>
|
上面的查询语句用mybatis执行时,其实是自动的按照JDBC的预编译语句方式执行的,等同于下面一段JDBC代码的执行过程
1
2
3
4
5
6
7
8
9
|
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManage.getConnection("jdbc:mysql://localhost:3306/dbname","root","112233");
PreparedStatement preState = conn.prepareStatement("SELECT * FROM user WHERE userid = ?");
preState.setString(1,"96");
ResultSet result = preState.executeQuery();
while(result.next()){
result.getString(columnname);
..........
}
|
到这里我们不禁疑惑,难道mybatis默认都是按照预编译语句的方式执行sql的吗?其实就是这样。通过查看mybatis官网文档可以看到有这么一个参数,statementType=[STATEMENT | PREPARED | CALLABLE ];有三个可选值,mybatis默认值是PREPARED;
这个参数是什么作用呢:
- 设定mybatis执行sql的模式
- STATEMENT设定为非预编译语句模式
- PREPARED设定为预编译语句模式–mybatis默认
- CALLABLE设定为兼容模式,或者自适应模式,比如设置该值后,mybatis处理sql时会自动的处理根据#、$去判断处理,后面说一下#和$的区别。
综上所述,mybatis默认按照预编译语句方式执行sql语句
2、动态传入表名
其实也经常会遇到动态的传入tableName的情况,也就是说上面的sql语句中的”user”是动态传入的,动态传入表名是mybatis中的一种特殊情况,
1
2
3
|
<select id="activityEnrollModelTableName" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT * FROM # WHERE userid = # //错误的写法
</select>
|
针对上面的语句,如果让mybatis仍然按照预编译语句方式执行时,等同于如下面的JDBC代码:
1
2
3
4
5
6
7
8
9
10
|
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManage.getConnection("jdbc:mysql://localhost:3306/dbname","root","112233");
PreparedStatement preState = conn.prepareStatement("SELECT * FROM ? WHERE userid = ?");
preState.setString(1,"USER");
preState.setString(2,"96");
ResultSet result = preState.executeQuery();
while(result.next()){
result.getString(columnname);
..........
}
|
我们把该段JDBC代码通过java代码执行后,发现会报异常:
1
|
java.sql.SQLException: ORA-00903: 表名无效
|
所以可以说明预编译语句不能用于列名(查询的列名也不能用预编译语句)、表名;只能作用与where条件参数属性!既然JDBC就不能将预编译语句方式作用与表名上面,那么mybatis就同样也行不通(因为mybatis默认是预编译语句模式)。不过mybatis也早已考虑到了这种情况,所以为我们做了处理:
- select标签语句中添加statementType=”STATEMENT”的属性配置
- 标签内的sql语句中将所有的${}更换成为#{},即将$还成#;
123<select id="activityEnrollModelTableName" statementType="STATEMENT" parameterType="java.util.HashMap" resultType="java.util.HashMap">SELECT * FROM $ WHERE userid = $ //正确的写法</select>
上面的语句标签中通过添加statementType=”STATEMENT”配置后,mybatis就不再使用预编译语句方式执行sql语句了,也就是通过直接执行sql语句操作;那么既然添加了statementType=”STATEMENT”非预编译配置后,为什么还需要把#换成$呢?其实是这样:
- “#” 是预编译语句模式下面的默认匹配符,也就是说mybatis遇到#{}时,将#替换成占位符?;被解析为一个JDBC预编译语句,然后再将#本身的值set进来。
- “$” 是非预编译语句下面的匹配符,非预编译语句说白了就是你传入什么sql语句,就执行什么sql语句,mybatis不做任何处理操作,但是这里mybatis会将${}对应的值,当做一个字符串处理,也就是说你程序接口方法中传递过来参数值是什么,对应的sql填充就是什么!
Mybatis动态传入tableName--非预编译(STATEMENT)的更多相关文章
- mybatis中预编译sql与非预编译sql
预编译sql有缓存作用,非预编译没得 mybaits中带有#传参的有预编译左右,$没得 多用#传参 预编译语句的优势在于归纳为:一次编译.多次运行,省去了解析优化等过程:此外预编译语句能防止sql注入 ...
- [转]MyBatis动态传入表名、字段名参数的解决办法
一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能.今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字段不让用户查询到.这 ...
- MyBatis动态传入表名
mybatis里#{}与${}的用法: 在动态sql解析过程,#{}与${}的效果是不一样的: #{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符. 如以下 ...
- 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” (可省略) 同 ...
- oracle学习笔记(七) 预编译Statement介绍与使用
预编译Statement优点 执行效率高 由于预编译语句使用占位符 "?",在执行SQL之前语句会被先发送到Oracle服务器进行语法检查和编译等工作,并将SQL语句加入到Orac ...
- JDBC预编译statement(preparedstatement)和statement的比较、execute与executeUpdate的区别
和 Statement一样,PreparedStatement也是用来执行sql语句的与创建Statement不同的是,需要根据sql语句创建PreparedStatement除此之外,还能够通过设置 ...
- MyBatis,动态传入表名,字段名的解决办法
转载:http://luoyu-ds.iteye.com/blog/1517607 今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的, 本来这也不是 ...
随机推荐
- 模仿ToDoList
1.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- 11.2.0.4 ORA-15025 ORA-27041 IBM AIX RISC System/6000 Error: 13: Permission denied
ASM device error ORA-27041 ORA-15025 ORA-15081 (Doc ID 1487475.1) 描述总结:数据库的alert中发现大量ORA-27041 ORA-1 ...
- MySQL5.7主从复制-异步复制搭建
两台服务器,系统是Redhat6.5,MySQL版本是5.7.18.1.在主库上,创建复制使用的用户,并授予replication slave权限.这里创建用户repl,可以从IP为10.10.10 ...
- 一文读懂 Serverless,将配置化思想复用到平台系统中
作者 | 春哥大魔王 来源 | Serverless 公众号 写在前面 在 SaaS 领域 Salesforce 是佼佼者,其 CRM 的概念已经扩展到了 Marketing.Sales.Servic ...
- 从零入门 Serverless | 教你使用 IDE/Maven 快速部署 Serverless 应用
作者 | 许成铭(竞霄) 阿里云开发工程师 SAE 应用部署方式 1. SAE 概述 首先,简单介绍一下 SAE.SAE 是一款面向应用的 Serverless PaaS 平台,支持 Spring C ...
- RabbitMQ持久化机制、内存磁盘控制(四)
一.持久化 如果看到这一篇文章的朋友,都是有经验的开发人员,对持久化的概念就不用再做过多的解析了,经过前面的几篇文章,其实不难发现RabbitMQ 的持久化其实就只分交换器持久化.队列持久化和消息持久 ...
- 如何在前端通过JavaScript创建修改CAD图形
背景 在之前的博文CAD图DWG解析WebGIS可视化技术分析总结.CAD_DWG图Web可视化一站式解决方案-唯杰地图-vjmap中讲解了如何把CAD的DWG格式的图纸Web可视化的方案,那在Web ...
- shell关键字含义
linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...
- 【Java虚拟机1】Java字节码文件格式入门
第一次学习看字节码文件,这个对工作没什么用,但是会提升内功. 首先介绍两个IDEA插件以及使用: BinEd:以16进制格式查看class文件 使用方法:右键class文件,点击Open as bin ...
- 【UE4】虚幻引擎技术直播汇总(含中英文直播)
B站虚幻引擎官方账号 中文直播 [中文直播]第35期 | 使用GIS在UE中创造真实地球风貌 | Epic 周澄清 [中文直播]第34期 | 包教包会的Epic MegaGrants申请之道 | Ep ...