设为首页 收藏本站
查看: 1018|回复: 0

[经验分享] MyBatis动态SQL之where语句

[复制链接]

尚未签到

发表于 2017-7-14 15:20:38 | 显示全部楼层 |阅读模式
针对模糊查询的三种方式
  业务层传递数据,在映射文件取值时where语句理论上应写为where user_name like #{user_name}%,但实际上控制台会报错。



### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
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 '%' at line 1
  提示的是数据库Sql语句的错误,如果使用了log4j日志,控制台显示:



DEBUG [main] - ==> Preparing: select * from web_user where user_name like ?%
DEBUG [main] - ==> Parameters: 悟(String)
  后面会解释为什么会出错。所以直接取值是不行的,可以使用下面的几种方式。
  一  在业务层进行处理
  在业务层接收到数据时,首先对数据进行一次简单的处理操作。



//接口中的方法为List<User> where01(String user_name);
//MyBatisUtil类详见前面的MyBatis工具类整合
try {
    sqlSession = MyBatisUtil.getSqlSession();
    String user_name = "悟";
    List<User> list = sqlSession.getMapper(UserDao.class).where01(user_name + "%");
    logger.debug(list);
  } finally {
    MyBatisUtil.closeSqlSession(sqlSession);
  }
  映射文件中的sql语句为:



<select id="where01" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like #{user_name}
</select>
  此时日志在控制台输出



DEBUG [main] - ==>  Preparing: select * from web_user where user_name like ?
DEBUG [main] - ==> Parameters: 悟%(String)
  二  在映射文件取值时进行处理
  在业务层不进行数据处理,在映射文件中不用#{}取值,改为${}方式取值。



<select id="where01" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like '${_parameter}%'
</select>
  控制台的信息:



DEBUG [main] - ==>  Preparing: select * from web_user where user_name like '悟%'
DEBUG [main] - ==> Parameters:
  由此可以看出#和$的区别
  #会将字符串进行预处理,用一对引号加在字符串外边,再替代?如#{user_name}% -->'悟'%,所以直接用#{}接值控制台报错的原因就在于此。
  $将取到的数据直接替换掉,并不会进行预处理。如'${_parameter}%' -->'悟%'
  三  在映射文件用方法进行拼接
  在业务层不进行数据处理,在映射文件调用MySql的concat(param1,param2,...)进行拼接



<select id="where03" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like concat(#{user_name},"%")
</select>
  日志:



DEBUG [main] - ==>  Preparing: select * from web_user where user_name like concat(?,"%")
DEBUG [main] - ==> Parameters: 悟(String)
针对多条件的where语句
  当有多个查询条件时,用if标签进行条件筛选



//接口中的方法为List<User> wheremore(@Param("userName") String user_name, @Param("account") String account);
try {
sqlSession = MyBatisUtil.getSqlSession();
String user_name = "悟";
String account = "wukong";
List<User> list = sqlSession.getMapper(UserDao.class).wheremore(user_name, account);
logger.debug(list);
  } finally {
    MyBatisUtil.closeSqlSession(sqlSession);
  }
  映射文件中的内容为:



<select id="wheremore" resultType="self.exercise.bean.User">
select * from web_user where 1=1
<if test="userName != null and userName != ''.trim()">
and user_name like concat(#{userName},"%")
</if>
<if test="account != null and account != ''.trim()">
and account = #{account}
</if>
</select>
  其中,test中的变量对应的为map中的key值、类中的属性名或者接口中param方法映射出的属性名
  但是之前提到过,XML中有些运算符不能被识别,所以test中进行测试时一些运算符需要进行用转义运算符替换,XML中有五个转义字符:



      运算符   转义字符
逻辑与    &    &amp;
大于号    >    &gt;
小于号    <    &lt;
双引号    "    &quot;
单引号    '    &apos;
  在读取的时候,解析器会自动将其转换回"&","<",">"等特殊字符,正常来说,只有"<" 字符和"&"字符对于XML来说是严格禁止使用的
  需要注意的是:
a. 转义序列各字符间不能有空格;
b. 转义序列必须以";"结束;
c. 单独的&不被认为是转义开始;
d. 区分大小写。

  判断一个字符串不为空串的几种方式:



<if test="user_name != ''.trim()"></if>
<if test="user_name.lengh() != 0"></if>
  以上的多条件查询方法,where后面跟着 1=1,每次执行sql语句都会进行一次判断(即使条件全部为空),当数据量很大时效率低下,可以where标签进行改进。



<select id="wheremore02" resultType="self.exercise.bean.User">
  select * from web_user
  <where>
    <if test="userName != null and userName != ''.trim()">
      and user_name like concat(#{userName},"%")
    </if>
    <if test="account != null &amp;&amp; account.length() != 0">
      and account = #{account}
  </if>
  </where>
</select>
  where标签会检索语句,将where中的第一个and 或者or 去掉,这里的and 和or 都是sql中的关键字(注意关键字后的空格也会被去掉),如果名为and_user_name的属性在最前面,则不会被检索出来。
  choose标签,相当于Java中的switch分支语句,跟if标签类似。
  但是这种方式不能使用,当最前边的条件判断正确后,会直接break;后面的条件不再判断。



<select id="wheremore03" resultType="self.exercise.bean.User">            
select * from web_user                                                
<where>                                                               
<choose>                                                         
<when test="userName != null and userName != ''.trim()">      
and user_name like concat(#{userName},"%")               
</when>                                                      
<when test="account != null &amp;&amp; account.length() != 0">
and account = #{account}                                 
</when>                                                      
</choose>                                                         
</where>                                                              
</select>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393825-1-1.html 上篇帖子: 一些内存使用错误理解 下篇帖子: Windows 8及以上系统安装好SQL Server 2008之后找不到SQL Server配置管理器的问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表