mybatis字符#与字符$的区别

  问题:使用in查询查询出一批数据,in查询的参数是字符串拼接的。调试过程中,把mybatis输出的sql复制到navicat中,在控制台将sql的参数也复制出来,替换到sql的字符 '?' 的位置,执行sql,能查询到数据,但是java程序无法查询到数据。

  原因:因为mybatis的参数占位符以#字符开头的参数,在处理过程中会自动给参数加引号,及一些字符过滤处理(例如防止sql注入等等)

  解决方式:  in查询的参数占位符换成字符$开头,因为mybatis在处理 $ 开头的参数占位符时候不会给参数加引号及其他额外处理(例如sql注入字符过滤),使用的是参数原值。

mybatis 参数查询修改前片段
AND a.source in (#{source})mybatis 参数查询修改后片段
AND a.source in (${source})

其他: 因为mybatis的参数占位符以#字符开头的参数,在处理过程中会自动给参数加引号,那么是加单引号还是双引号呢?

    实际上mybatis对这个#开头的参数参数进行了参数化处理,防止注入。

     如果参数拼接 top_news','net_music','knowledge_sns','wb ,如果#开头参数处理是单纯加单引号,那么sql条件语句如果变成如下这样,是可以查询到数据的,但是结果是没有查询到数据,说明,时间拼接的数据不是如下的结果,结果是#开头的参数不是单纯的加单引号处理

AND a.source in ('top_news','net_music','knowledge_sns','wb')   

如果参数拼接使用双引号拼接如下 top_news","net_music","knowledge_sns","wb ,如果#开头参数处理是单纯加双引号,那么sql条件语句如果变成如下这样,是可以查询到数据的,但是结果是没有查询到数据,说明,实际拼接的数据不是如下的结果,结果是#开头的参数不是单纯的加双引号处理

AND a.source in ("top_news","net_music","knowledge_sns","wb") 

至于#开头的参数到底怎么处理的,既不是单纯加单引号也不是单纯加双引号,具体做了哪些处理,请阅读源码。反正mybatis进行in查询时,参数是拼接好的字符串的时候,参数占位符使用$,而不使用#,在使用$做参数占位符时候,给参数赋值前确保代码里做了防注入处理或者已知的代码是安全的不存在sql注入的,可以直接使用$作为参数占位符。

  mybatis xml 文件(修改前),in查询参数使用占位符使用字符#

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkgem.jeesite.modules.backend.dao.ChannelDao">
<sql id="channelColumns">a.id AS "id",a.name AS "name",a.source AS "source",a.url AS "url",a.create_by AS "createBy.id",a.update_by AS "updateBy.id",a.update_date AS "updateDate",a.create_date AS "createDate",a.remarks AS "remarks",a.del_flag AS "delFlag"
</sql><sql id="channelJoins">
</sql><select id="findList" resultType="Channel">SELECT <include refid="channelColumns"/>FROM mkt_channel a<include refid="channelJoins"/><where>a.del_flag = #{DEL_FLAG_NORMAL}<if test="source != null and source!=''">AND a.source in (#{source})</if><if test="createBy != null">AND  a.create_by = #{createBy.id}</if></where><choose><when test="page !=null and page.orderBy != null and page.orderBy != ''">ORDER BY ${page.orderBy}</when><otherwise>ORDER BY a.update_date DESC</otherwise></choose>
</select>
</mapper>

ChannelController.java

@Controller
@RequestMapping(value = "${a}/backend/channel")
public class ChannelController extends BaseController {@Autowiredprivate ChannelService channelService;@Autowiredprivate SystemService systemService;@RequiresPermissions("backend:channel:view")@RequestMapping(value = {"list", ""})public String list(Channel channel, HttpServletRequest request, HttpServletResponse response, Model model) {String sourceName= request.getParameter("sourceName");String srcStr = null;boolean srcFindDo = false;if(StringUtils.isNotEmpty(sourceName)) {Map<String, Object> findedChannelMap = SourceUtils.getInstance().searchSourceList(sourceName);srcStr = (String) findedChannelMap.get("srcStr");srcFindDo = true;}String createBy = request.getParameter("createBy");channel.setCreateBy(null);createBy = XssFilter.getInstance().cleanXssChars(createBy);if(StringUtils.isNotEmpty(createBy)) {User user = systemService.getUserById(createBy);if(null != user) {channel.setCreateBy(user);}}Page<Channel> page = new Page<>();if(srcFindDo && StringUtils.isEmpty(srcStr)){page.setList(new ArrayList<>());page.setPageNo(0);page.setPageSize(0);page.setCount(0);page.setMessage("没有找到数据");}else {channel.setUtmSource(labelStr);page = channelService.findPage(new Page<Channel>(request, response), channel);}model.addAttribute("page", page);return "modules/backend/channelList";}
}

SourceUtils.java

package com.thinkgem.jeesite.common.utils;import com.thinkgem.jeesite.modules.backend.entity.ChannelSource;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.*;public class SourceUtils {private Logger logger = LogManager.getLogger(SourceUtils.class);private ChannelSourceFacade channelSourceFacade;private static SourceUtils instance;private SourceUtils() {channelSourceFacade = SpringContextHolder.getBean(ChannelSourceFacade.class);}public static SourceUtils getInstance() {if (null == instance) {instance = new SourceUtils();}return instance;}/*** 获取所有的来源列表* @return*/public List<ChannelSource> getAllSource() {List<ChannelSource> dataList = new ArrayList<>();Response<List<ChannelSource>> response = channelSourceFacade.getChannelSourceList();dataList = response.getData(); return dataList;}/*** 根据来源名称模糊查找渠道* @return*/public Map<String,Object> searchChannelList(String label,String desc,String code) {Map<String,Object> dictMap = new HashMap<>();String labelStr = "";List<ChannelSource> findedList = new ArrayList<>();List<ChannelSource> srcList = getAllChannelDict();if(null != srcList && srcList.size() > 0) {for (ChannelSource item : srcList) {if (dictMap.containsKey(item.getLabel())) {continue;}if(channelMatch(name,item)) {findedList.add(item);srcStr = String.format("%s'%s',",srcStr,item.getLabel());}}}if(srcStr.length() > 1) {//移除最后一个逗号和2个引号srcStr = srcStr.substring(0, srcStr.length() - 1);}dictMap.put("srcStr",srcStr);dictMap.put("findedList",findedList);return dictMap;}private boolean channelMatch(String sourceName,Dict item) {boolean result = true;name = null == name ? "" : name;if (StringUtils.isNotEmpty(name)) {if (dict.getDescription().indexOf(desc) == -1) {result = false;return result;}}return result;}}

转载于:https://www.cnblogs.com/huangzhihua/p/7761136.html

java in查询无法查询到数据(mybatis字符#与字符$的区别)相关推荐

  1. 【Java从0到架构师】MyBatis - 查询

    MyBatis - 查询 数据库事务 (Database Transaction) MyBatis 使用准备 依赖 配置文件 创建 Session MyBatis 查询 实体映射 字段映射 - res ...

  2. java 实现违章_基于JAVA的车辆违章查询数据调用代码实例

    基于JAVA的车辆违章查询数据调用代码实例 代码描述:基于JA V A的车辆违章查询数据调用代码实例 相关平台:聚合数据 import java.io.BufferedReader; import j ...

  3. MySQL_(Java)分页查询MySQL中的数据

    MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL_(Java)使用preparestatement ...

  4. java scan hbase_hbase+java实例,Scan查询所有、get根据rowkey查询一行或一列数据

    hbase+java实例,Scan查询所有.get根据rowkey查询一行或一列数据 import java.io.IOException; import java.text.SimpleDateFo ...

  5. java显示数据库_java查询数据库中的数据并显示

    java查询数据库中的数据并显示 关注:93  答案:2  mip版 解决时间 2021-01-17 16:29 提问者笑低了眉眼 2021-01-17 04:11 button.addSelecti ...

  6. java将后台数据库查询到的数据导出word文档当中

    java将后台数据库查询到的数据导出word文档当中 之前项目需求使用Java导出word文档,一直没有进行整理,今天把它进行整理出来,以便以后使用到:下面是导出的word文档. // 前端报告表格 ...

  7. java 实现查询近七天数据功能

    java 实现查询近七天数据功能 接上一篇 如何使用echarts表图地址 实现了页面的表图 那么如何对接数据 如何使用 耐心看完!!! 这次就以右下角这一个表图做示范 这个表图的下面是按时间排序的 ...

  8. java查询elasticsearch_elasticsearch查询所有数据restful api以及java代码实现

    elasticsearch查询所有数据restful api以及java代码实现 restful api实现如下: 返回所有数据: Java代码实现:/** * 查询所有 * @throws Exce ...

  9. java查询几万条数据_java一次性查询几十万,几百万数据解决办法(转载)

    0hB)H"aK ZJ%K Z0java查询一次性查询几十万,几百万数据解决办法51Testing软件测试网0L?pAzOk51Testing软件测试网2@ai.g\1p 很早的时候写工具用 ...

最新文章

  1. xss植入_xss的高级利用
  2. bat脚本 git pull_bat文件方式对git进行操作
  3. linux上安装hackrf_在Linux上安装Kubectl
  4. 获取sqlserver数据库中所有库、表、字段名的方法
  5. sql注入pythonpoco_.NET EF(Entity Framework)详解
  6. 从Spring Boot信息泄露到AWS控制台劫持(攻破aws亚马逊服务器)
  7. poj 1459 Power Network 多源多汇网络流
  8. 用html制作圆的周长,几何画板制作圆周长展开动画
  9. python实现元胞自动机
  10. JavaScript 基础概念
  11. 哈佛幸福课中提到的书_借助虚拟现实,在哈佛最大的班级中排在前列
  12. java程序设计概念对象先行_《Java程序设计概念:对象先行》【摘要 书评 在线阅读】-苏宁易购图书...
  13. android编译生成apk文件怎么打开,android studio生成apk在哪?
  14. unity 5.x android发布注意事项
  15. c# mysql 批量导入_C#:MySql批量数量导入
  16. poj 1608 dp(Banal Ticket)
  17. 大话设计模型 Task02:策略、装饰、代理
  18. n个点求 能构成多少个三角形
  19. 猝灭剂BHQ-1 amine/1308657-79-5/BHQ-2 氨基/1241962-11-7者相关的物理性质还是有一定的区别,整理以下相关的数据进行对比。
  20. 高等数学(Calculus II)

热门文章

  1. AutoCAD2010云盘分享链接
  2. android 巧用动画使您app风骚起来
  3. jsf标签,jsp标签与jstl标签
  4. sql返回刚添加的数据的自增id
  5. Python源代码文件的文本编码
  6. 使用tcgetattr函数与tcsetattr函数控制终端-转
  7. Linux调试工具strace和gdb常用命令小结-转
  8. 蓝桥杯 ADV-222 算法提高 7-2求arccos值
  9. zabbix分布式监控环境搭建
  10. PowerDesigner概念模型与物理模型相互转换及导出数据字典