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