Mybatis#与$的区别与认知

本文介绍了一种使用MyBatis处理特殊字符的方法,解决在查询含有特殊字符的商品属性时出现的问题。通过对比#与$符号在MyBatis中的区别,最终采用$符号解决了SQL查询失败的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近适用mybatis有个查询需求,就是将商品属性与数据库中的商品属性字符串进行比对,从而通过用户筛选的属性获取对应的商品。 从前台获取json封装都1属性值对后,在后台进行解析,然后对多个属性存储在List集合中。然后将该集合传参给Mapper接口进行查询。
其中List集合中的值长这样
List<String> attr = new ArrayList<String>();
attr.add("'%\"品牌\":[%\"花花公子\"%]%'");
attr.add("'%\"尺码\":[%\"M\"%]%'");

mapper接口是这样子搭:
//通过类目id与商品属性获取该类目
 List<Good> selectByAttributes(@Param("id")Integer id, @Param("attr")List<String> attr); 

然后xml文件查询语句是这样的:
  <!--通过类目id与商品属性获取该类目  -->
  <select id="selectByAttributes" resultMap="BaseResultMap">
     SELECT sg.id,sg.goodName,sg.status,sg.updateTime,sg.enteringTime,sg.updatePersonId,sg.enteringPersonId,sg.romotion,sg.totalSales ,sg.originalPrice
     from shop_good sg
     LEFT JOIN shop_base_attri_good sbag on sbag.goodId = sg.id
     where categoryId = #{id,jdbcType=INTEGER} and
     <foreach item="attribute" collection="attr" index="index" separator=" and ">
          attributes like #{attribute}
     </foreach>
  </select>


以上,一切看起来自我感觉良好,测试运行以下,获取的结果是List<Good>的大小为0
一脸懵逼的查看运行日志:
[2018-04-18 15:09:35,700] [DEBUG] [org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:87)] [JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b718392] will not be managed by Spring]
[2018-04-18 15:09:35,712] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [==>  Preparing: SELECT sg.id,sg.goodName,sg.status,sg.updateTime,sg.enteringTime,sg.updatePersonId,sg.enteringPersonId,sg.romotion,sg.totalSales ,sg.originalPrice from shop_good sg LEFT JOIN shop_base_attri_good sbag on sbag.goodId = sg.id where categoryId = ? and attributes like ? and attributes like ? ]
[2018-04-18 15:09:35,796] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [==> Parameters: 64(Integer), '%"品牌":[%"花花公子"%]%'(String), '%"尺码":[%"M"%]%'(String)]
[2018-04-18 15:09:35,854] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [<==      Total: 0]
[2018-04-18 15:09:35,857] [DEBUG] [org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:191)] [Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d816dde]]
[2018-04-18 15:09:35,857] [DEBUG] [org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:329)] [Returning JDBC Connection to DataSource]
0

从上面看到查询语句没出错,传参也没错,于是不服的拿到navicat进行查询,结果如下:

于是很纳闷,问题出现在哪里,通过查阅mybatis相关数据,得知特殊字串的替换与处理问题,
mybatis中#与$的区别:#{} 在动态解析的时候, 会解析成一个参数标记符。${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中
  • #方式能够很大程度防止sql注入。
  • $方式无法防止Sql注入。
  • $方式一般用于传入数据库对象,例如传入表名.
本次查询条件中包含特殊字符,我一开始使用的是#,所以会导致查询失败,改为$后查询就成功了。
[2018-04-18 15:21:11,633] [DEBUG] [org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:87)] [JDBC Connection [com.mysql.jdbc.JDBC4Connection@7ee55e70] will not be managed by Spring]
[2018-04-18 15:21:11,651] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [==>  Preparing: SELECT sg.id,sg.goodName,sg.status,sg.updateTime,sg.enteringTime,sg.updatePersonId,sg.enteringPersonId,sg.romotion,sg.totalSales ,sg.originalPrice from shop_good sg LEFT JOIN shop_base_attri_good sbag on sbag.goodId = sg.id where categoryId = ? and attributes like '%"品牌":[%"花花公子"%]%' and attributes like '%"尺码":[%"M"%]%' ]
[2018-04-18 15:21:11,697] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [==> Parameters: 64(Integer)]
[2018-04-18 15:21:11,848] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] [<==      Total: 7]
[2018-04-18 15:21:11,850] [DEBUG] [org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:191)] [Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d816dde]]
[2018-04-18 15:21:11,850] [DEBUG] [org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:329)] [Returning JDBC Connection to DataSource]
7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值