Mybatis的#{}与${}与和statementType的结合

#{}:以预编译的形式进行查询,所有要传的参数均用?代替,

${}:以传输值的方式查询,有SQL注入的危险。

当指定statementType属性时:

1.#{}与PREPARED

  //#{}与PREPARED
  /*
<select  statementType="PREPARED" id="selectUserById" resultType="org.example.pojo.User">
    select * from t_user WHERE id = #{id}
</select>
*/
    @Test
    public void testSelectUserById() throws Exception{

        SqlSession session = getSqlSession();//自定义方法,返回一个SqlSession对象
        try {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectUserById(9);
            System.out.println(user);
        }finally {
            session.close();
        }
    }

结果:正常

 2.#{}与STATEMENT

//#{}与STATEMENT
/*<select  statementType="STATEMENT" id="selectUserById" resultType="org.example.pojo.User">
    select * from t_user WHERE id = #{id}
</select>
*/
    @Test
    public void testSelectUserById() throws Exception{

        SqlSession session = getSqlSessionFactory();
        try {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectUserById(9);
            System.out.println(user);
        }finally {
            session.close();
        }
    }

结果:提示SQL语法错误,检查第一行的?号。

Error querying database.  Cause: java.sql.SQLSyntaxErrorException: 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
### The error may exist in t_user.xml
### The error may involve org.example.dao.UserMapper.selectUserById
### The error occurred while executing a query
### SQL: select * from t_user WHERE id = ?
### Cause: java.sql.SQLSyntaxErrorException: 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

3.${}与PREPARED

//${}与PREPARED
/*<select  statementType="PREPARED" id="selectUserById" resultType="org.example.pojo.User">
    select * from t_user WHERE id = ${id}
</select>
*/
    @Test
    public void testSelectUserById() throws Exception{

        SqlSession session = getSqlSessionFactory();
        try {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectUserById(9);
            System.out.println(user);
        }finally {
            session.close();
        }
    }

结果:正常

 4.${}与STATEMENT

  //${}与STATEMENT
/*<select  statementType="STATEMENT" id="selectUserById" resultType="org.example.pojo.User">
    select * from t_user WHERE id = ${id}
</select>
*/
    @Test
    public void testSelectUserById() throws Exception{

        SqlSession session = getSqlSessionFactory();
        try {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectUserById(9);
            System.out.println(user);
        }finally {
            session.close();
        }
    }

结果:正常

 从3的结果我们得知,当用${}的方法传参并且指定statementType为PREPARED时,程序成功运行了。那么能不能用这种方式来解决${}的sql注入问题呢?

验证:

1.在UserMapper接口中准备根据姓名查询用户方法

List<User> selectUserByName(String username);

2.在对应的xml文件中准备该方法的select标签。(注意statementType的类型为PREPARED,sql参数为${})

<select id="selectUserByName" statementType="PREPARED" resultType="org.example.pojo.User">
        SELECT * FROM t_user WHERE username = ${parm1}
    </select>

3.准备

@Test
    public void testSelectUserByname() throws Exception{
        SqlSession session = getSqlSessionFactory();
        try {
            UserMapper mapper = session.getMapper(UserMapper.class);
            List<User> users = mapper.selectUserByName("'admin' " + "OR 1=1");
            for(User user:users){
                System.out.println(user);
            }
        }finally {
            session.close();
        }

    }

结果:编译通过

 得出结论:当使用${}并且指定statementType为PREPARED时,并不能解决sql注入问题。mybatis仍是直接将传递的参数拼接进sql中而不是用占位符代替。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值