首页 > 其他分享 >MyBatis动态表名和字段,减轻很大工作

MyBatis动态表名和字段,减轻很大工作

时间:2023-07-12 23:33:38浏览次数:50  
标签:name sql 减轻 user 表名 MyBatis 参数 where select

在动态sql解析过程,#{}与${}有本质差别
1. #{} 是基于JDBC的preparedStaement ,${} 是基于JDBC的Statement
2. #{} 表示的是预编译的参数,就是 替代在SQL语句中的占位符‘?’,并会将参数作为字符串处理;如果要动态传入 表名或者字段名,不能使用#{}
3. #{} 是使用预编译 传参,可以预防SQL注入,${} 是直接将值输出,是不安全的
4. ${}只能获得参数池的值, 而#{}可以获得接口方法参数列表的值,也可以获取参数池的值,如果使用${}获取参数类别中的值,这个参数必须使用 @Param 强制绑定

可以看到#{}被解析为一个参数占位符?
select * from user where name = #{name};
会被解析为:
select * from user where name = ?;

${} 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换
select * from user where name = ${name};
当我们传递参数“sprite”时,sql会解析为:
select * from user where name = sprite; 注意要传值,需要加引号'sprite',不然报错,而传表名字段名则不需要

SQL注入风险

${}在预编译之前已经被变量替换了
select * from ${tableName} where name = ${name}

如果传入的参数tableName为user; delete user; --,那么sql动态解析之后,预编译之前的sql将变为:

select * from user; delete user; -- where name = ?;

查询语句变为删除数据,所以尽量选择使用#{}更为安全些。

实例

public List<Map<String, Object>> getDatasByMap(Map<String> map);

 <select id="getDatasByMap" resultType="java.util.Map" parameterType="java.util.HashMap"  statementType="STATEMENT" >
    select 
        ${columns}
    from ${tableName}
        group by ${columns}
  </select>


   @Test
    public List<Map<String, Object>> testByMap(Map<String> map){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        HashMap<String, Object> map = new HashMap();
        map.put("columns", "name,age,id");
        map.put("tableName", "users");
        User user = mapper.getDatasByMap(map);
        System.out.println(user);

    }


要实现动态调用表名和字段名,就不能使用预编译了,需添加statementType="STATEMENT"" 。
statementType:STATEMENT(非预编译),PREPARED(预编译)或CALLABLE中的任意一个,这就告诉 MyBatis 分别使用Statement,PreparedStatement或者CallableStatement。默认:PREPARED。这里显然不能使用预编译,要改成非预编译。

其次,sql里的变量取值是${xxx},不是#{xxx}。
因为${}是将传入的参数直接显示生成sql,如${xxx}传入的参数为字符串数据,需在参数传入前加上引号,如:
String name = "sprite";
name = "'" + name + "'";
这样,sql就变成:
select * from user where name = 'sprite';

Mybatis学习教程链接

标签:name,sql,减轻,user,表名,MyBatis,参数,where,select
From: https://www.cnblogs.com/hbym/p/17549170.html

相关文章

  • MyBatis,mapper找不到方法
       项目目录如下,可以看到是接口映射xml文件的mybatis此时运行项目会出现找不到save方法 解决方法:确保接口与xml文件路径一致在xml文件上再建一级mapper,并将其移入其中可  ......
  • SSM - Mybatis - Example - SQL
     Teacher/Student表CREATETABLE`teacher`(`id`INTNOTNULL,`name`VARCHAR(30)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=UTF8MB4;INSERTINTOteacher(`id`,`name`)VALUES(1,'秦老师');CREATETABLE`student`(......
  • mybatis快速入门
    MyBatis快速入门1.创建User表,添加数据2.创建模块,导入坐标pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"......
  • mybatis-plus Error attempting to get column 'xxx' from result set.
     报错信息:mybatis-plusErrorattemptingtogetcolumn'xxx'fromresultset. 解决:1、获取数据的实体类中新建了一个有参的构造方法,却没有无参构造方法,使用MyBatis-Plus内置方法进行查询时会报错。解决办法:新建一个无参构造方法。......
  • MyBatis实现动态SQL更新
    博主记得在一个周五快下班的下午,产品找到我(为什么总感觉周五快下班就来活......
  • IDEA的Mybatis 开发追踪跳转插件
    MybatisX是一款基于IDEA的快速开发插件,为效率而生。安装方法:打开IDEA,进入File->Settings->Plugins->BrowseRepositories,输入 mybatisx 搜索并安装。 转自:https://baomidou.com/pages/ba5b24/#%E5%8A%9F%E8%83%BD ......
  • SSM - Mybatis - Lombok - 配置
    Lombok配置Lombok安装方式有三部,IDEA安装,POM引用,接口使用。详见@ (15条消息)idea中怎么使用lombok依赖_idea依赖树只有lombok_南商的博客-CSDN博客 <!--https://mvnrepository.com/artifact/org.projectlombok/lombok--><dependency><groupId>org.projectlombok</g......
  • Spring整合MyBatis
     主要是把xml中的mysql数据源、mysql映射还有SqlSessionFactoryBean工厂给放到bean类中    还有把Dao使用@Autowired注解注入到Service中 包 下面是全部的代码(从上到下)这是sql数据源配置 这里面是工厂和映射 这是核心配置 Dao Service业务逻辑层......
  • mybatis的延时加载
    https://www.bilibili.com/video/BV1V24y1V7aJ/?spm_id_from=333.337.search-card.all.click&vd_source=46d50b5d646b50dcb2a208d3946b1598https://www.bilibili.com/video/BV1Tb4y1p7rh/?spm_id_from=333.337.search-card.all.click&vd_source=46d50b5d646b50dcb2a2......
  • Mybatis里面的缓存机制
    1.mybatis的SqlSession是什么MyBatis的SqlSession是MyBatis框架提供的一个关键接口,它代表了和数据库的一次会话。SqlSession提供了执行SQL语句、管理事务以及获取映射器(Mapper)等操作。在一般情况下,每次查询都会创建一个新的SqlSession实例。这是因为SqlSession代表......