zoukankan      html  css  js  c++  java
  • MyBatis 模糊查询的 4 种实现方式

    引言

    MyBatis 有 4 种方式可以实现模糊查询。

    员工信息表 ( tb_employee ) 如下:

    id name sex email birthday address
    001 张一凡 zyf@qq.com 1989-10-11 成都市一环路海南之家188号
    002 张军 zj@qq.com 1990-02-10 成都市二环路神仙树街200号
    003 李国华 lgh@qq.com 1980-02-10 成都市三环路迎宾路58号
    根据姓名模糊查询员工信息

    方式一

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like #{name}
    </select>
    

    此种方式需要调用接口方法传参时,手动的去添加 “%” 通配符,即

    SqlSession sqlSession = MyBatisUtil.getSession();
    IEmpolyeeDao empolyeeDao = sqlSession.getMapper(IEmpolyeeDao.class);
    EmployeeEntity = IEmpolyeeDao.selectByName("%"+"张"+"%");
    MyBatisUtil.closeSesion(sqlSession);
    

    这种方式可以实现模糊查询,但是有一点不方便的地方就是在调用接口 selectByName() 方法传参时需要手动的添加 "%" 号通配符,有些麻烦。

    方式二

    你可能会想到,能否在映射配置文件中直接将”%“号通配符写好呢?如下:

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like %#{name}%
    </select>
    

    但是,测试后你会发现,程序会报错,错误原因是:缺少单引号。

    这时你可能会这样想了,那干脆加一个“单引号”不就得了,如下:

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like '%#{name}%'
    </select>
    

    测试后发现,程序依然会报错,原因是:如果加上单引号,那么就当成是一个字符串,而 #{ } 写在字符串中不能识别,正确的做法是将#{ }改写成 ${ } 这种形式,如下:

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like '%${name}%'
    </select>
    

    测试后发现,程序终于没报错了。

    但是这种方式有一个美中不足的地方,就是它是以拼接字符串的方式生成 sql,这样做会引发 sql 注入的问题。

    SQL 注入是黑客常用的一种攻击技术,想知道详情请搜索看我的另一篇专门介绍 SQL 注入问题以及防御办法的文章

    方式三

    前两种方式,虽然可以解决模糊查询的问题,但是都不怎么好,要么手动添加太麻烦,要么有 SQL 注入的安全问题。有没有什么办法,能够两全其美呢?有的,我们可以借助 mysql 的字符串拼接 concat 函数,如下:

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like concat( '%' , #{name}, '%')
    </select>
    

    这是 concat( '%' , #{name}, '%') 的作用就将三个字符串拼接起来。

    方式四

    当然对于方式三,也可以使用 ${} 的方式,不过需要特别留意单引号的问题。

    <select id="selectByName" resultType="EmployeeEntity">
         select * from tb_employee where name like concat( '%' , ‘${name}', '%')
    </select>
    

    总结

    • '#{}'是预编译处理,MyBatis 在处理 #{ }时,它会将sql中的#{ }替换为 ?号,然后调用JDBC 中 PreparedStatement 的 set 方法来赋值,传入字符串后会自动在值两边加上单引号,使用占位符的方式提高效率,可以防止 sql 注入问题(主要使用方式)

    • '${ }' 表示拼接 sql 串,将接收到参数的内容不加任何修饰拼接在 sql 中,可能引发 sql 注入问题(一般很少使用)

    作者:Binge
    本文版权归作者和博客园共有,转载必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    quotaon
    quotacheck
    quota
    query_module
    数据库连接驱动
    PHP 开发 APP 接口 学习笔记与总结
    Java实现 LeetCode 76 最小覆盖子串
    Java实现 LeetCode 74 搜索二维矩阵
    Java实现 LeetCode 74 搜索二维矩阵
    Java实现 LeetCode 74 搜索二维矩阵
  • 原文地址:https://www.cnblogs.com/binbingg/p/13797208.html
Copyright © 2011-2022 走看看