sql >> Database teknologi >  >> RDS >> Database

Forskellen mellem en JDBC-erklæring og en forberedt erklæring

Selvom det er rigtigt, at en grundlæggende SQL-sætning i mange tilfælde vil få arbejdet gjort for mange databaseændringer eller forespørgsler, er det ofte en bedste praksis at gøre brug af den fleksibilitet og fordele, du får ved at bruge PreparedStatements .

De primære forskelle mellem en standard JDBC-sætning og en PreparedStatement er bedst defineret af fordele at en PreparedStatement giver dig og din ansøgning. Nedenfor vil vi undersøge de tre kernefordele ved PreparedStatements over almindelige JDBC/SQL-sætninger.

SQL-injektionsforebyggelse

Den første fordel ved at bruge en PreparedStatement er du kan drage fordel af de mange .setXYZ() metoder, såsom .setString() , som tillader din kode automatisk at undslippe specialtegn såsom anførselstegn inden for den beståede SQL-sætning, hvilket forhindrer den altid farlige SQL injection angreb.

I en standard SQL-sætning kan det f.eks. være typisk at indsætte værdier direkte inline med sætningen, som sådan:

statement = "INSERT INTO books (title, primary_author, published_date) VALUES ('" + book.getTitle() + "', '" + book.getPrimaryAuthor() + "', '" + new Timestamp(book.getPublishedDate().getTime()) + "'";

Dette ville tvinge dig til at udføre din egen kode for at forhindre SQL-injektioner ved at undslippe anførselstegn og andre specialtegn fra de indsatte værdier.

Omvendt en PreparedStatement kan påberåbes som følger ved at bruge .setXYZ() metoder til at indsætte værdier med automatisk tegn-escape under metodeudførelse:

ps = connection.prepareStatement("INSERT INTO books (title, primary_author, published_date) VALUES (?, ?, ?)");
ps.setString(1, book.getTitle());
ps.setString(2, book.getPrimaryAuthor());
ps.setTimestamp(3, new Timestamp(book.getPublishedDate().getTime()));
ps.executeUpdate();

Pre-compilation

En anden fordel ved en PreparedStatement er, at selve SQL'en er pre-compiled en enkelt gang og derefter gemt i hukommelsen af ​​systemet, i stedet for at blive kompileret hver gang sætningen kaldes. Dette giver mulighed for hurtigere eksekvering, især når en PreparedStatement bruges sammen med batches , som giver dig mulighed for at udføre en serie (eller batch ) af SQL-sætninger på én gang under en enkelt databaseforbindelse.

For eksempel har vi her en funktion, der accepterer en List af bøger. For hver book på listen ønsker vi at udføre en INSERT erklæring, men vi vil tilføje dem alle til en batch af PreparedStatements og udføre dem alle i ét hug:

public void createBooks(List<Entity> books) throws SQLException {
  try (
    Connection connection = dataSource.getConnection();
    PreparedStatement ps = connection.prepareStatement("INSERT INTO books (title, primary_author, published_date) VALUES (?, ?, ?)");
  ) {
    for (Entity book : books) {
      ps.setString(1, book.getTitle());
      ps.setString(2, book.getPrimaryAuthor());
      ps.setTimestamp(3, new Timestamp(book.getPublishedDate().getTime()));

      ps.addBatch();
    }
    ps.executeBatch();
  }
}

Indsættelse af unormale datatyper i SQL-sætning

Den sidste fordel ved PreparedStatements som vi vil dække er evnen til at indsætte unormale datatyper i selve SQL-sætningen, såsom Timestamp , InputStream , og mange flere.

For eksempel kan vi bruge en PreparedStatement at tilføje et forsidebillede til vores bogjournal ved hjælp af .setBinaryStream() metode:

ps = connection.prepareStatement("INSERT INTO books (cover_photo) VALUES (?)");
ps.setBinaryStream(1, book.getPhoto());
ps.executeUpdate();

  1. Eksternt Oracle-tabeleksempel

  2. Sjovt med (columnstore) komprimering på et meget stort bord – del 3

  3. Hvorfor er usigneret heltal ikke tilgængelig i PostgreSQL?

  4. Indsæt array i MySQL-database med PHP