MBS4: Map接口传参、模糊查询以及#{}与${}的SQL注入问题

4.1 Map接口

简介: 当我们在MyBatis中,使用对象进行传参时(例如MBS3中的User),如果实体类的属性十分庞大,而自己需要传递的参数只有几个,这时候使用对象传参是十分不换算的。例如,我们需要更改一个用户的姓名,但是User实体类中的属性有20几个,我们使用构造器时,是需要将20属性全部赋值的。因此,我们可以使用Map接口来节约资源,并简化操作。

数据库:

idnamegender
1张大姐2
2李大哥1
3王五婶2

4.2 代码实现

UserMapper接口:

package com.yun.dao;

import com.yun.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {    
    //Map接口的使用
    List<User> getUserList2(Map<String,Object> map);		//可以指定String,Object,也可以不用
}

UserMapper.xml:

<?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.yun.dao.UserMapper" >

        <select id="getUserList2" parameterType="Map" resultType="com.yun.pojo.User">
            select * from user where id =#{userId}			<!--括号里的值,是键-->
        </select>
    </mapper>

测试Map使用接口:

package com.yun.dao;

import com.yun.pojo.User;
import com.yun.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {
    @Test
    public void getUserList2Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String,Object> map = new HashMap();
        map.put("userId",2);

        List<User> users = mapper.getUserList2(map);
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

4.3 模糊查询的两种方式

4.3.1 java传递通配符

UserMapper接口:

package com.yun.dao;

import com.yun.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
    //模糊查询
    List<User> getUserLike(String values);
}

UserMapper.xml:

<?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.yun.dao.UserMapper" >
        <select id="getUserListLike" parameterType="String" resultType="com.yun.pojo.User">
            select * from user where name like #{values}
        </select>
    </mapper>

测试模糊接口:

package com.yun.dao;

import com.yun.pojo.User;
import com.yun.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {
    @Test
    public void getUserListLikeTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.getUserListLike("%大%");

        for (User user : users) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}

4.3.2 MyBatis通配符

UserMapper接口:

package com.yun.dao;

import com.yun.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
    //模糊查询
    List<User> getUserListLike(String values);
}

UserMapper.xml:

<?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.yun.dao.UserMapper" >
        <select id="getUserListLike" parameterType="String" resultType="com.yun.pojo.User">
            select * from user where name like concat('%',#{values},'%')
        </select>
    </mapper>

测试模糊接口:

package com.yun.dao;

import com.yun.pojo.User;
import com.yun.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {
    @Test
    public void getUserListLikeTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.getUserListLike("大");

        for (User user : users) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}

4.3 关于#{}与${}的SQL注入问题

4.3.1 简介:

#{}${} 是MyBatis提供的两种对参数取值的方式。二者都可取出参数但是,二者功能有所不同。

4.3.2 #{}原理

简介: #{} 并不只是简单地取参数值,而是会创建PreparedStatement对象,并通过预编译的方式,对SQL语句进行传值。

例子:

<select id="getUserListLike" parameterType="String" resultType="com.yun.pojo.User">
    select * from user where name like #{values}
</select>

等同于以下语句:

String sql = "select * from user where name like ?";
PreparedStatement pre = con.prepareStatement(sql);

pre.set(1,values);

提示: java的PreparedStatement对象,就是为了防止SQL注入而存在的,并且#{}传递的值永远都是字符串存在的,因此#{}根本不会存在SQL注入的问题。

4.3.3 ${}的使用

简介: ${} 传递的是未经修改的字符,并不会存在创建PreparedStatement对象,而是直接传值,所以会存在SQL注入问题。

使用: 当我们需要传递一些Mysql里的关键字时,我们则需要使用 ${}

<select id="getUserListLike" parameterType="String" resultType="com.yun.pojo.User">
    select * from user order by id ${values}
</select>

如果上述语句中,values的候选值为 ”DESC“,”ASC“ ,如果我们使用的是 #{} ,那么于MySql而言,则是以下语句:

select * from user order by id DESC					<!--#{}使用结果-->

select * from user order by id 'DESC'				<!--${}使用结果-->

提示: 显然, #{} 使用结果语句在MYSQL中,是 非法 的。

SQL注入解决方案: 有大佬给出了解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值