mybatis学习之路----模糊查询实现

点滴记载,点滴进步,愿自己更上一层楼。


废话不多说,进入主题。

项目还是在上篇  mybatis学习之路----非代理方式的增删改查用法 基础之上进行开发


一个简单的模糊查询sql。

SELECT * FROM t_user WHERE username LIKE '%黄%'
根据以上sql,查询结果。


像这样的用到模糊查询的地方很多。下面来介绍mybatis的三种方式。


1 使用${}代替#{}接收参数。此种方式有sql注入风险。关于sql注入在下面会有实例演示。

2 使用mysql的concat语法给传入参数拼%号。即concat('%',param,'%').

3 直接接收带%号的参数进行查询  此种方式存在硬编码,不推荐。


在user.xml中添加如下信息。也就是上面三种方法的实现

    <!--模糊查询 demo1 直接用${} 接收参数 此种方式有sql注入的危险
    注意:如果parameterType为简单类型,最好写成${value}  写成别的很容易报错
              There is no getter for property named 'username' in 'class java.lang.String',
          如果parameterType为包装类型,和model中的属性对应即可-->
    <select id="findUserByName1" parameterType="String" resultMap="userMap">
        select * from t_user where username like '%${value}%'
    </select>

    <!--模糊查询 demo2 直接用concat拼字符串 此种可以有效防止sql注入 -->
    <select id="findUserByName2" parameterType="String" resultMap="userMap">
        select * from t_user where username like concat('%', #{username} ,'%')
    </select>

    <!--模糊查询 demo3 直接接收 拼好的参数  几接收参数就是 %参数% 形式,这种存在硬编码,不推荐 -->
    <select id="findUserByName3" parameterType="String" resultMap="userMap">
        select * from t_user where username like #{username}
    </select>

UserDao.java中添加对应的接口

    /**
     * 模糊查询第一种方式
     * @param username 参数
     * @return
     */
    List<User> findUserByName01(String username);

    /**
     * 模糊查询第二种方式  使用concat拼接查询命令
     * @param username 参数
     * @return
     */
    List<User> findUserByName02(String username);

    /**
     * 模糊查询第三种方式  直接接收拼好的字符串
     * @param username 参数
     * @return
     */
    List<User> findUserByName03(String username);

对应的实现    UserDaoImpl.java

    
    /**
     * 模糊查询第一种方式
     * @param username 参数
     * @return
     */
    public List<User> findUserByName01(String username) {
        String statementId = "test.findUserByName1";
        return findUserList(statementId,username);
    }

    /**
     * 模糊查询第二种方式  使用concat拼接查询命令
     * @param username 参数
     * @return
     */
    public List<User> findUserByName02(String username) {
        String statementId = "test.findUserByName2";
        return findUserList(statementId,username);
    }

    /**
     * 模糊查询第三种方式  直接接收拼好的字符串
     * @param username 参数
     * @return
     */
    public List<User> findUserByName03(String username) {
        String statementId = "test.findUserByName3";
        return findUserList(statementId,username);
    }

    /**
     * 由于都需要三种方式查询除了两个地方不一样其他的处理都相同,此处抽取相同部分
     * @param statementId
     * @param param
     * @return
     */
    private List<User> findUserList(String statementId, Object param){
        SqlSession sqlSession = null;
        try {
            sqlSession = SqlsessionUtil.getSqlSession();
            return sqlSession.selectList(statementId,param);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            SqlsessionUtil.closeSession(sqlSession);
        }
        return new ArrayList<User>();
    }

基本实现已经完成,下面进行测试。

UserDaoTest.java  中添加对应的测试代码。

    @Test
    public void findUserByName01() throws Exception {
        List<User> users = dao.findUserByName01("黄");
        for(User user:users){
            System.out.println("findUserByName01:" + user);
        }
    }

    @Test
    public void findUserByName02() throws Exception {
        List<User> users = dao.findUserByName02("黄");
        for(User user:users){
            System.out.println("findUserByName02:" + user);
        }
    }

    @Test
    public void findUserByName03() throws Exception {
        // 此种方式存在硬编码,不推荐
        List<User> users = dao.findUserByName03("%黄%");
        for(User user:users){
            System.out.println("findUserByName03:" + user);
        }
    }
三种方法测试结果。





到此,三种实现模糊查询方式示例完毕。


上面写到使用${}来接收参数的时候,说有sql注入的风险。那么什么是sql注入呢?

sql注入传送门

其实简单来说,传入的参数中有一段有风险的并且可执行sql代码。如果没有规避掉,可能是系统直接瘫痪。下面进行演示。


测试代码findUserByName01使用的是${}来接收参数,即

    @Test
    public void findUserByName01() throws Exception {
        List<User> users = dao.findUserByName01("黄");
        for(User user:users){
            System.out.println("findUserByName01:" + user);
        }
    }
这段代码怎么sql注入呢?

如果将参数修改成带有可执行sql的参数即("4' or username in (select username from t_user) or username like '3")
其中有了  or username in (select username from t_user)   这个条件,sql执行结果就是全表数据显示。

修改后带有sql注入的java代码。

    @Test
    public void findUserByName01() throws Exception {
        List<User> users = dao.findUserByName01("黄' or username in (select username from t_user) or username like '3");
        for(User user:users){
            System.out.println("findUserByName01:" + user);
        }
    }
执行结果。

可以看到全表的数据都显示出来了。

想想如果注入的sql是删除语句的话。。。。。。

但是同样的带有sql注入代码的参数,放到findUserByName02中,结果大不相同。

    @Test
    public void findUserByName02() throws Exception {
        List<User> users = dao.findUserByName02("黄' or username in (select username from t_user) or username like '3");
        for(User user:users){
            System.out.println("findUserByName02:" + user);
        }
    }

结果:


这就是说为什么,不提倡${}的方式来写模糊查询,而推荐使用concat拼接方式来进行模糊查询了。



  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中,可以使用%符号实现模糊查询。然而,直接使用%可能会引发SQL注入的问题。为了同时解决模糊查询和SQL注入的问题,可以借助MySQL的函数和MyBatis的bind标签来实现。 首先,可以使用MySQL的CONCAT()函数将多个字符串连接成一个字符串。在MyBatis的映射文件中,可以使用该函数来实现模糊查询。例如,可以使用以下语句实现模糊查询: SELECT * FROM t_role WHERE role_name LIKE CONCAT('%',#{keyword},'%') OR id LIKE CONCAT('%',#{keyword},'%') OR role_type LIKE CONCAT('%',#{keyword},'%') 另外,还可以使用MyBatis的bind标签来定义一个变量,并将模糊查询的字符串赋值给该变量。然后,在查询语句中使用该变量来实现模糊查询。例如,可以使用以下语句实现模糊查询: <bind name="pattern" value="'%' + keyword + '%'" /> SELECT * FROM t_role WHERE role_name LIKE #{pattern} OR id LIKE #{pattern} OR role_type LIKE #{pattern} 需要注意的是,在使用bind标签时,要使用${...}来引用变量,而不是使用#{...}。这是因为#{...}会将传入的参数作为字符串参数处理,而${...}会将传入的参数直接替换到SQL语句中。 综上所述,可以通过使用MySQL的函数和MyBatis的bind标签来实现MyBatis的入参模糊查询。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SSM框架的学习与应用-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发](https://download.csdn.net/download/m0_53659738/88258800)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MyBatis模糊查询的4种实现方式](https://blog.csdn.net/shadow_zed/article/details/107929621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [MyBatis模糊查询多种写法](https://blog.csdn.net/qq_45802158/article/details/127183382)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值