zoukankan      html  css  js  c++  java
  • 【死磕jeesite源码】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 = ?;

      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等),这样实现日志的分月分表存储,方便日志的分析。

      希望对大家有帮助!如有疑问可以在底下留言。

  • 相关阅读:
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码分析(八)-----Reduce Shuffle过程分析
    YARN源码分析(八)-----Reduce Shuffle过程分析
    【每天一道算法题】整数循环节之和——数字黑洞6174
    getline函数
    设计模式之建造者模式Builder(创建型)
    字符串算法总结
    C++设计模式之单例模式
    Linux下C的线程同步机制
  • 原文地址:https://www.cnblogs.com/abc8023/p/9089999.html
Copyright © 2011-2022 走看看