SQL或HQL预编译语句,能够防止SQL注入,但是不能处理%和_特殊字符

最近项目在做整改,将所有DAO层的直接拼接SQL字符串的代码,转换成使用预编译语句的方式。个人通过写dao层的单元测试,有以下几点收获。

dao层代码如下

//使用了预编译sql
public List<IndvConfigModel> selectConfigBySuffix(String suffix)
{
        String hql = "from IndvConfigModel where configKey like '%'||?||'%'";

        return this.selectConfigByHQL(hql, new Object[]{suffix});
}

单元测试代码和执行结果如下:

@Test
public void testLike()
{
    List<IndvConfigModel> list = dao.selectConfigBySuffix("picQual");
    Assert.assertEquals(list.size(), 2);// 1.true

    list = dao.selectConfigBySuffix("picQua%");
    Assert.assertEquals(list.size(), 2);// 2.true

    list = dao.selectConfigBySuffix("pic'Qual");
    Assert.assertEquals(list.size(), 0);//3. true

}

1、第一个断言是true,说明上面的做法,的确能够起到模糊查询的效果

2、第二个断言是true,说明%被认为是模糊匹配,并没有被oracle看成普通的字符。这说明预编译语句,是不能处理参数值中的特殊字符的。遇到%和_这种数据库模糊查询的特殊字符,需要使用者自己转义.

3、第三个断言没有报异常。说明:预编译语句已经对oracle的特殊字符单引号,进行了转义。即将单引号视为查询内容,而不是字符串的分界符。

由于SQL注入其实就是借助于特殊字符单引号,生成or 1= 1这种格式的sql。预编译已经对单引号进行了处理,所以可以防止SQL注入

时间: 2024-10-11 03:42:29

SQL或HQL预编译语句,能够防止SQL注入,但是不能处理%和_特殊字符的相关文章

PDO预编译语句执行查询与DML操作

代码示例: MyPDO.class.php的代码如下: /** * 使用PDO预编译语句执行DML操作并返回受影响的行数 * @param $sql 需要执行的SQL语句(预编译语句写法) * @param array $arr 预编译语句需要添加的数据值,数组结构 * @return int 返回DML执行后受影响的行数 */public function intByPdoPrepare($sql, array $arr=array()){ $ps =$this->pdo->prepare(

关于mysql使用prepare关键字预编译语句后是否使用deallocate的区别

下图是mysql数据库中某一数据库,里面有一张user表. 1.新建查询之后,下图展示的使用prepare预编译查询结果(注意:使用了DEALLOCATE关键字删除预编译语句) 2.再次运行刚才的预编译语句aa, 结果出现错误.原因是:之前使用deallocate已经删除了预编译语句. 3.这一次不使用deallocate关键字删除预编译语句. 再一次调用已经预编译过的aa语句. 这一次仍然可以使用该语句. 4.使用deallocate删除该语句. 再次运行已删除语句. 结果再次报错.说明dea

mybatis以及预编译如何防止SQL注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者).[摘自] SQL injection - Wikipedia SQL注入,大家都不陌生,是一种常见的攻击方式.攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=’1’”这样的语句),有可能入侵参数检验不足的应用程序.所以,在我们的应用中需要做一些工作,来防备这样的攻击方式.在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句

JDBC预编译语句表名占位异常

有时候,我们有这样的需求,需要清空多个表的内容,这样我们有两种做法,可用delete from table 或 truncate table table,两种方法视情况而定,前者只是一条条的删除表数据,主键自增的序列还能保存,后者类似是重新建表保留表结构,主键信息,也被清空. OK,下面我们用JDBC开始删除,因为是多个表,所以要循环删除,根据以往的经验,使用预编译的sql语句,可能执行效率会更高,短短几行代码,搞定: public void clearTables()throws Except

JDBC 预编译语句对象

Statement的安全问题:Statement的执行其实是直接拼接SQL语句,看成一个整体,然后再一起执行的. String sql = "xxx"; // ? 预先对SQL语句进行语法的校验 PreparedStatement ps = conn.prepareStatement(sql); // ? 对应的索引从1开始 ps.setString(1, username); ps.setString(2, password); rs = ps.executeQuery(); 还可以

面试题--如何防止sql注入,使用PreparedStatement的预编译,传入的内容就不会和原来的语句发生任何匹配的关系,达到防止注入的方法

PreparedStatement的用法 jdbc(java database connectivity,java数据库连接)的api中的主要的四个类之一的java.sql.statement要求开发者付出大量的时间和精力.在使用statement获取jdbc访问时所具有的一个共通的问题是输入适当格式的日期和时间戳:2002-02-05 20:56 或者 02/05/02 8:56 pm. 通过使用java.sql.preparedstatement,这个问题可以自动解决.一个prepareds

测试mysql的sql语句预编译效果

玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升.现在在转Mysql之后特别是innodb很多东西都还能和Oracle对得上号的,就像innodb_buffer_pool_size类似于Oracle的database buffer cache,innodb_log_buffer_size类似于redo log buffer,但是innodb_additional_mem_pool_size仅仅类似于s

atitit.查看预编译sql问号 本质and原理and查看原生sql语句

atitit.查看预编译sql问号 本质and原理and查看原生sql语句 1. 预编译原理. 1 2. preparedStatement 有三大优点: 1 3. How to look  gene  sql 2 1. Hb cfg all debug ,cant see... 2 2. WSExplorer按照进程抓取pack可以看见.. 2 3. Mysql 5.6 开放日志可以看见 2 4. Mysql and msssql的不同实现 2 4. MYSql的实现是jdbc连接完全的sql

JDBC 删除数据两种方式,PreparedStatement表示预编译的 SQL 语句的对象,防止sql注入

1.statement使用的不方便 2.sql注入的问题 *  在SQL语句中使用了系统自带的关键字 or and ,让where条件判断失效 *   prepareStatement: *  1.sql语句不用在拼字符串 *  2.防止sql注入问题 1 public class CURDTest { 2 public static void main(String[] args) throws Exception { 3 //insertTest(); 4 //deleteTest(); 5