课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > mybatis动态调用表名和字段名
  • mybatis动态调用表名和字段名

    发布:昆明Java培训      来源:达内新闻      时间:2016-10-21

  • 昆明Java培训机构的老师一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能。今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字段不让用户查询到。这 情况下,就需要构建sql来动态传入表名、字段名了。

    动态SQL是mybatis的强大特性之一,mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态sql进行处理。下面让昆明Java培训机构的老师带大家先来熟悉下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等),这样实现日志的分月分表存储,方便日志的分析。

    昆明Java培训机构的老师下一期还有新的知识点给大家分享,大家不要错过啰。

    推荐文章

上一篇:【昆明Java培训机构】简述抽象和封装

下一篇:Java:简单的通过XML的AOP配置

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56