mybatis中用like的时候,变量是动态的,但是总是多了一个单引号,好奇怪。

public List getmajorscores(String course,String term){//这是调用方法
List list = sMapper.getmajorscores("17会计","2");
return list;
}
在score.java中:
List getmajorscores( String course, String term);
在score.xml中:
select * from scores where s_term = #{1} and s_class like CONCAT('%',#{0},'%') and s_course in(SELECT DISTINCT s_course from scores where s_class like CONCAT('%',#{0},'%') )

9个回答

sql本身如楼上所说,and s_class like CONCAT('%',#{0},'%')这句话不用要,因为你虚表本身就有,说实话,就sql本身而言,楼主将sql写复杂了,
我们分析一下,SELECT DISTINCT s_course from scores where s_class like CONCAT('%',#{0},'%')这句话就是查询课程根据班级,而你
所以整个sql可以翻译为查询信息根据 s_term 并且 根据 班级s_class like CONCAT('%',#{0},'%')(这句)并且根据课程,而课程是怎么查出来的?根据班级SELECT DISTINCT s_course from scores where s_class like CONCAT('%',#{0},'%'),楼主可以试一下,根本没必要要最后一个and之后的语句,查询出的信息觉对完全一样,也就是2句话说的是一个意思,如果是因为s_cores可能为null导致的可以加一句and s_course is not null,至于为什么觉得让楼主去掉最后一个and之后的,是因为in的效率极其低下我们一般sql能不用in就不用in的,in是全表检循环检索,也就是说,你有1000条数据,in有10个条件,呢么就要检索1000*10次,什么概念?你有百万条数据呢?另外看你贴的错误其是因为17会计真正传过去的时候是'17会计',其暂时我还没看出来,方便的话,将整个xml关于这段贴出来,包含select标签

zhangpan_soft
zhangpan_soft 回复weixin_40119478: 我知道你没有加,我说的假如,假如我是一个攻击者,我就非常轻松的进入你系统了
接近 2 年之前 回复
weixin_40119478
代码没写完 回复sky__fall: 没有啊,就直接传变量过去的,我没有单独加一个单引号
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft 回复weixin_40119478: $会产生sql注入漏洞,真正解决办法已贴出,你可以看下,$的含义在评论某条帖子时已说明,我给你举一个例子,就比如你的sql,假如我这样传入参数,我的参数是' OR 1=1,会产生什么?,sql变为 where s_term = ... and s_class like '' or 1=1这时候直接把你所有数据拿到了,假如再狠一点我用1来试你有多少列,然后关联用户表,试出密码,如下:我传入' UNIQUE SELECT 1如果不是一列报错再传入' UNIQUE SLEECT 1,1,不是2列继续递推,当推出你有多少列的时候我开始传入' UNIQUE SELECT ... FROM 表名,试出用户表,说严重点,我甚至可以根据sql漏洞,拿到数据库权限,拿到数据库权限,然后将其升级为root用户,拿到整个操作系统权限,你就gg了
接近 2 年之前 回复
sky__fall
Dream_fall 回复weixin_40119478: 尽量不要用美元符号哦,有sql注入漏洞的风险。你是否确定course参数中没有单引号?
接近 2 年之前 回复
weixin_40119478
代码没写完 感谢您的指导,我后面再优化一下语句,不用in了,整句是这样的: <select id="getmajorscores" resultMap="BaseResultMap" > select * from scores where s_term = #{term} and s_class like CONCAT('%',${course},'%') and s_course in(SELECT DISTINCT s_course from scores where s_class like CONCAT('%',${course},'%') ) </select>
接近 2 年之前 回复

没有语法错误,但是你得sql语句写重复了 不需要下面这句: and s_course in(SELECT DISTINCT s_course from scores where s_class like CONCAT('%',#{0},'%') )

weixin_40119478
代码没写完 后面那句是有用的,所以不能删呢。
接近 2 年之前 回复
weixin_40119478
代码没写完 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'17会计'%' at line 1 忘记放上去错误了,在变量那里&多了一个‘
接近 2 年之前 回复

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'17会计'%' at line 1
忘记放上去错误了,在变量那里&多了一个‘

建议试一下:
List getmajorscores( String course, String term); 这句改成List getmajorscores( @Param("course")String course, @Param("term")String term);

#{1} 改成 #{term} #{0} 改成 #{course}

另外 in 后半句确实没用,子查询和外面的查询都是从一张表查?那还搞个子查询干嘛

 select * from scores where s_term = #{1} and 
<bind name="pattern" value="'%"+#{0} +" %'" />
s_class like #{pattern}
and s_course in(SELECT DISTINCT s_course from scores where s_class like  #{pattern})

图片说明

补充一点,我们在用模糊的时候,很少如楼主呢让用,我们一般是在业务层拼接好传过去的,也就是在service中已经拼接成%17会计%,然后将这个传入sql,在sql中就变为了like #{...},

zhangpan_soft
zhangpan_soft 回复zhangpan_soft: 方便的话加我qq283483610,我给你远程下,个人感觉是一个小点被忽略了,
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft 回复weixin_40119478: like不会自己加的,我一直这么写的,没出过问题
接近 2 年之前 回复
weixin_40119478
代码没写完 回复zhangpan_soft: 确定了传的时候17会计没有’引号,语句用的like #{0},感觉'%'是这个like自己加进去的
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft 回复weixin_40119478: 你先试试,我先吃饭去了
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft 回复weixin_40119478: 如果还是报这个错那绝对是因为你的参数本身就带了',你可以改为List<Scores> list = sMapper.getmajorscores("%"+course.replaceAll("\'","")+"%","%"+term+"%");就没问题了
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft 回复weixin_40119478: select * from scores where s_term = #{1} and s_class like #{0} 将这句话替换你原来sql试下
接近 2 年之前 回复
sky__fall
Dream_fall 回复weixin_40119478: 1、%外还是要加单引号的;2、这个说明,course里本来就有单引号,你可以把course打印出来试试。
接近 2 年之前 回复
weixin_40119478
代码没写完 List<Scores> list = sMapper.getmajorscores("%"+course+"%","%"+term+"%");我这样子拼接了一下,还是这样ight syntax to use near '%'17会计'%' at line 1
接近 2 年之前 回复
weixin_40119478
代码没写完 我试试
接近 2 年之前 回复

把#{0}换成${0}试试应该可以

图片说明
#{}是带引号的吧,拼接会报错,?就没错。

zhangpan_soft
zhangpan_soft 回复u014794644: 一样的,你只不过用的是注解方式,mybatis注解是不支持$的,仅仅这个区别
接近 2 年之前 回复
u014794644
瓦史托德 回复zhangpan_soft: xml和java不一样的,我java的使用$就报错
接近 2 年之前 回复
zhangpan_soft
zhangpan_soft #在mybatis中等同于jdbc的?,?的含义是PreparedStatement,好好研究下什么是PreparedStatement,什么是Statement,在MyBatis中#代表PreparedStatement,$代表Statement,Statement会产生sql注入漏洞,我是怀疑楼主加了DATA头,所以出问题了
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐