简体   繁体   English

准备好的语句如何在 Java 中工作?

[英]How does prepared statement work in Java?

What is prepared statement good for.准备好的陈述有什么用。 I read is good for performance when you execute same sql query multiple times just with different values.当您使用不同的值多次执行相同的 sql 查询时,我读到对性能有好处。

//Line 1
ps = c.prepareStatement("INSERT INTO STUDENT VALUES (?, ?)"); 

So here I created a prepared statement.所以在这里我创建了一个准备好的语句。 Will this be sent to the database and stay there?这会被发送到数据库并留在那里吗? Then I only have to send the values to database.然后我只需要将值发送到数据库。 Right??正确的??

//This is created only once 
//Once created, the PreparedStatement is compiled automatically.    
ps.setInt(1, 111);   
ps.setString(2, "Bob");   
ps.executeUpdate();

Here I set the values which are sent to database without the actual query.在这里,我设置了在没有实际查询的情况下发送到数据库的值。 Right?正确的?

They have two purposes.他们有两个目的。 The one you stated, but that's a very minor benefit.你说的那个,但这是一个非常小的好处。 It is, in fact, not guaranteed at all;实际上,根本无法保证。 a JDBC driver is free to just 'fill in the blanks', so to speak, and send the SQL otherwise verbatim to the DB layer every time.一个 JDBC 驱动程序可以自由地“填空”,可以这么说,并且每次都将 SQL 否则逐字发送到 DB 层。 If your DB engine supports precompiling SQL statements, then PreparedStatement is how to get this benefit, but a JDBC driver does not have to support this (but it must support PreparedStatement; it implement it without precompiling anything, though).如果您的数据库引擎支持预编译 SQL 语句,那么 PreparedStatement 是如何获得此好处的,但是 JDBC 驱动程序不必支持此(但它必须支持 PreparedStatement;它无需预编译任何东西即可实现它)。 Besides, if you're looking for a 'bulk' job (do the same thing many many times), often there are better tools available.此外,如果您正在寻找“批量”工作(多次做同样的事情),通常有更好的工具可用。 For example, if you want to insert 1 million records into a table, there are far more efficient ways than just.. create a prepared statement, and rerun it with different set values a million times.例如,如果你想将 100 万条记录插入到一个表中,有仅仅创建一个准备好的语句并使用不同的设置值重新运行它一百万次更有效的方法。 You'd turn off all constraint checking and index updating, and/or COPY or some other bulk insertion process specifically designed for this, then turn checks and indices back on.您将关闭所有约束检查和索引更新,和/或COPY或一些专门为此设计的其他批量插入过程,然后重新打开检查和索引。

No, the 99%+ reason to use PreparedStatement over Statement is security .不,使用 PreparedStatement 而不是 Statement 的 99% 以上的原因是安全

Statement is not secure.语句不安全。

imagine this one:想象一下:

String name = getNameFromWebForm();
String id = getNextAvailableStudentId();
connection.executeUpdate("INSERT INTO STUDENT (name, id) VALUES ('" + name + "', '" + id + "');");

and now some enterprising clown decides to try this name on for size:现在一些有进取心的小丑决定试试这个名字的大小:

Alicia', '1'); DROP TABLE STUDENT; EXEC 'rm -rf /*'; --

As in, they literally type all that jazz (or more likely paste it) into the web form that reads: "Name:".就像在里面一样,他们将所有爵士乐(或更可能是将其粘贴)输入到 web 表格中,上面写着:“姓名:”。 With the quotes and the dashes and the semicolons, all of it.加上引号、破折号和分号,所有这些。

They click 'form submit' and a few moments later the table is deleted and with some luck the entire server disk is obliterated.他们点击“表单提交”,片刻之后表格被删除,幸运的是整个服务器磁盘都被抹掉了。

You can't solve this by going: Eh, no prob, I'll just find quotes and eliminate them;你不能通过以下方式解决这个问题:嗯,没问题,我会找到引号并删除它们; you have no idea what the DB does and does not allow for quoting and the like, maybe this DB allows backquotes.您不知道数据库做什么和不允许引用等,也许这个数据库允许反引号。 Maybe this one allows unicode escapes.也许这个允许 unicode 转义。 The only party that knows is the JDBC driver and the database, and you unlock their abilities to escape things by using PreparedStatement .唯一知道的是 JDBC 驱动程序和数据库,您可以使用PreparedStatement解锁它们逃避事物的能力。

TL;DR: Anytime you have 'parameters' in your query, you MUST use PreparedStatement. TL;DR:只要您的查询中有“参数”,就必须使用 PreparedStatement。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM