四MyBatis获取参数值的两种方式
Posted 钟楼小奶糕6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四MyBatis获取参数值的两种方式相关的知识,希望对你有一定的参考价值。
MyBatis配置相关模板
1.核心配置文件的模板
2.映射文件模板
3.封装SqlSessionUtils工具类
package com.atguigu.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionUtils
public static SqlSession getSqlSession()
SqlSession sqlSession = null;
try
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
catch (IOException e)
e.printStackTrace();
return sqlSession;
MyBatis获取参数值的两种方式
- MyBatis获取参数值的两种方式:$和#
- $本质是字符串拼接,#的本质是占位符赋值
- $使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号。
- #使用占位符赋值的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要自动加单引号。
1.单个字面量类型的参数
- 若mapper接口的方法参数为单个的字面量类型,此时可以使用$和#以任意的名称获取参数值。$需要手动加引号
①在ParameterMapper接口上
②在ParameterMapper.xml上
- 用#username- username可任意替换
2.用’$username’ - username可任意替换
③测试
2.多个字面量类型的参数
- 若mapper接口的方法参数是多个时,此时MyBatis会自动的将这些参数放在一个map集合中以arg0,arg1…为键,以参数为值或者以param1,param2为键,以参数为值
- 此时通过$和#访问map集合的键会获取对应的值
①在ParameterMapper接口中
②在 ParameterMapper.xml配置类
③测试
3.map集合类型的参数
- 若map接口的方法参数为多个,可以手动创建map集合,通过#和$访问map集合的键获取对应的值
①在ParameterMapper接口中
②在 ParameterMapper.xml配置类
③测试
4.实体类类型的参数
- 若mapper接口的方法参数是实体类对象,可以使用$或#通过对象的属性名获取属性值。
①在ParameterMapper接口中
②在 ParameterMapper.xml配置类
③测试
5.使用@Param标识参数
- 可以通过@Param注解标识mapper接口的方法参数,此时参数会放在map集合中
①以@Param注解的value属性值为键,参数值为值
②以param1,param2为键。以参数为值
2.通过#或$访问map集合的键可以获取对应的值
①在ParameterMapper接口中
②在 ParameterMapper.xml配置类
③测试
MyBatis动态传递参数的两种方式#{}和${}
最近做的Java规范更新涉及到MyBatis映射配置文件中动态传递参数的两种方式#{}和${},两者的区别,
(1) #{}为参数占位符?,即SQL预编译。${}为字符串替换,即SQL拼接,可以理解为仅仅是个纯碎的string替换,在动态SQL解析阶段将会进行变量替换。
(2) #{}是“动态解析->预编译->执行”的过程。${}是“动态解析->编译->执行”的过程。
(3) #{}的变量替换是在DBMS中。${}的变量替换是在DBMS外。
(4) 变量替换后,#{}对应的变量自动加上引号。变量替换后,${}对应的变量不会加上引号。
例如给参数name传递一个值test,如果是#{name},则值为'test',
select id,name,age from student where name=#{name}
如果是${name},则值为test,
select id,name,age from student where name=${name}
(5) #{}能防止SQL注入。${}不能防止SQL注入。
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以他为背景设置安全的值(例如?)。这样做很安全,很迅速,是首选做法,有时只是想直接在SQL语句中插入一个不改变的字符串。例如ORDER BY,可以这样来使用ORDER BY ${columnName},这里MyBatis不会修改或转义字符串。
但是要知道,接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此不应该允许用户输入这些字段,或者通常自行转义并检查。
ORDER BY通常比较特殊,例如根据前端传过来的字段排序,用了如下格式,
select XXXX from table order by #{column} #{desc}
但是排序没生效,查看日志,发现实际执行的SQL如下所示,排序未生效,
select XXXXX from table order by "column" "desc"
主要还是对MyBatis传参形式不了解,官方介绍,
P.S. https://mybatis.org/mybatis-3/sqlmap-xml.html#Parameters
原文如下,
By default, using the #{} syntax will cause MyBatis to generate PreparedStatement properties and set the values safely against the PreparedStatement parameters (e.g. ?). While this is safer, faster and almost always preferred, sometimes you just want to directly inject an unmodified string into the SQL Statement. For example, for ORDER BY, you might use something like this:
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);
#{}相当于jdbc中的preparedstatement,进行了预编译,而${}直接是字符串本身,是有意设计成这样,方便拼接成动态SQL,但可能存在注入的问题。
另外一个场景,就是隐式转换,SQL Server碰到过传入的是varchar,字段类型是varchar,但是通过#{},传入的就成了nvarchar,例如,
select * from test where id = #{id};
导致隐式转换,此时有两种解决,
(1) 需要在jdbc的url配置中添加sendStringParameterAsUnicode=false;关闭unicode字符串的转换,
jdbc:sqlserver://x.x.x.x:1433;DatabaseName=test;sendStringParametersAsUnicode=false;
(2) #{}改为${},避免类型转换,
select * from test where id = '${id}';
因此,
(1) 能用#{}的地方就用#{},不用或少用${}。
(2) 表名作参数时,必须用${},例如select * from ${tableName}。
(3) ORDER BY时,必须用${},例如,
select * from t_user order by ${columnName}
(4) 使用${}时,要注意何时加或不加单引号,即${}和'${}'。
(5) 存在隐式转换时,注意${}和#{}。
参考资料,
https://mybatis.org/mybatis-3/sqlmap-xml.html#Parameters
https://www.cnblogs.com/yang82/p/7813549.html
https://blog.csdn.net/siwuxie095/article/details/79190856
https://blog.csdn.net/angyuhh07719/article/details/102429418
近期更新的文章:
《知乎的彩蛋》
文章分类和索引:
以上是关于四MyBatis获取参数值的两种方式的主要内容,如果未能解决你的问题,请参考以下文章