Java 如何在sql查询中传递参数而不使其在查询本身中显式?

Java 如何在sql查询中传递参数而不使其在查询本身中显式?,java,sql,ignite,Java,Sql,Ignite,我正在测试我的ignite缓存,在缓存中插入一个简单的用户,然后通过一个查询,我得到了之前输入的用户,返回了我在编写查询时遇到的问题。我注意到这样写: @Test @EnableStreamCacheTestUtil(caches = {@Cache(name = "User", queryEntity = {@QueryEntity(tableName = "USER", keyClass = String.class, valueClass =

我正在测试我的ignite缓存,在缓存中插入一个简单的用户,然后通过一个查询,我得到了之前输入的用户,返回了我在编写查询时遇到的问题。我注意到这样写:

@Test
    @EnableStreamCacheTestUtil(caches = {@Cache(name = "User", queryEntity = {@QueryEntity(tableName = "USER", keyClass = String.class, valueClass = User.class)})})
    public void Test_expected_Ok() throws Exception {
        Ignite ignite = Ignition.ignite();


        UsersRequest usersRequest = new UsersRequest();
        usersRequest.setName(TestCostants.NAME);
   

        IgniteCache<String, User> igniteCache = ignite.cache("User");
        User user = new User("Ennio","Ragno",90")
        igniteCache.put("1", user);
    

        SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
                " FROM USER WHERE NAME ='ENNIO'");

        int counter = 0;
        List<List<?>> cursor = igniteCache.query(sql).getAll();
        // try(QueryCursor<List<?>> cursor = igniteCache.query(sql)) {
        for (List<?> row : cursor) {
            log.info("SQLQUeryresult:{}", row);
            counter++;
        }
        Assertions.assertEquals(1,counter);
      }

    
    }

现在它不再工作了。这是我第一次尝试使用查询和缓存,但从技术上讲,这不应该是相同的吗?在传递这样的参数时,是否有不同的方法来编写查询?

正确的方法是使用参数替换,避免SQL注入和其他问题:

    //Clearly in the constant that there is the value "ENNIO"
    UsersRequest usersRequest = new UsersRequest();
    usersRequest.setName(TestCostants.NAME);

    //some code

   
    SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
            " FROM USER WHERE NAME = ?").setArgs(usersRequest.getName());

正确的方法是使用参数替换,避免SQL注入等问题:

    //Clearly in the constant that there is the value "ENNIO"
    UsersRequest usersRequest = new UsersRequest();
    usersRequest.setName(TestCostants.NAME);

    //some code

   
    SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
            " FROM USER WHERE NAME = ?").setArgs(usersRequest.getName());

在中间代码中,在缓存中设置一个值,稍后使用
.getName()

当您调用
usersRequest.getName()

那么

 SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
                " FROM USER WHERE NAME ='ENNIO'");
哪一个是成功的,第二个是成功的

SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
                " FROM USER WHERE NAME = "+usersRequest.getName());

失败的是,第二个调用是使用
Ennio
而不是
Ennio
在中间代码中,在缓存中设置一个值,稍后使用
.getName()
检索该值

当您调用
usersRequest.getName()

那么

 SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
                " FROM USER WHERE NAME ='ENNIO'");
哪一个是成功的,第二个是成功的

SqlFieldsQuery sql = new SqlFieldsQuery("SELECT * " +
                " FROM USER WHERE NAME = "+usersRequest.getName());

失败的是用
Ennio
调用第二个,而不是先用
Ennio

调用-在…usersRequest.getName()之后缺少一个“')。第二,你能试试这个
“SELECT*FROM USER WHERE NAME=”+usersRequest.getName()+““
这将usersRequest.getName()括在单引号中,并将其附加到查询的末尾。您好@AdilKhalil,你说得对,可能是在复制我删除它的文本时!我马上试试你的解决办法,马上告诉你away@AdilKhalil将值连接到查询字符串中会使其容易受到SQL注入的攻击。坚持这种不安全的做法的建议不是一个好主意。@AdilKhalil你错了,猜猜如果
某个东西的值为
'或'='
,你现在有了一个条件
,其中name=''或'=''
,这总是正确的,这只是一种相对良性的SQL注入形式,更糟糕的事情可以这样做。仅仅在它周围加上引号并不能消除与连接相关的SQL注入风险。您要么需要正确地转义值,要么-更好地-使用参数。@MarkRotterVeel我站得住脚了。谢谢。首先-在…usersRequest.getName()之后缺少一个“')”。第二,你能试试这个
“SELECT*FROM USER WHERE NAME=”+usersRequest.getName()+““
这将usersRequest.getName()括在单引号中,并将其附加到查询的末尾。您好@AdilKhalil,你说得对,可能是在复制我删除它的文本时!我马上试试你的解决办法,马上告诉你away@AdilKhalil将值连接到查询字符串中会使其容易受到SQL注入的攻击。坚持这种不安全的做法的建议不是一个好主意。@AdilKhalil你错了,猜猜如果
某个东西的值为
'或'='
,你现在有了一个条件
,其中name=''或'=''
,这总是正确的,这只是一种相对良性的SQL注入形式,更糟糕的事情可以这样做。仅仅在它周围加上引号并不能消除与连接相关的SQL注入风险。您要么需要正确地转义值,要么-更好地-使用参数。@MarkRotterVeel我站得住脚了。非常感谢。