Vad är JDBC? Introduktion till Java-databasanslutning

JDBC (Java Database Connectivity) är Java API som hanterar anslutning till en databas, utfärdande av frågor och kommandon och hantering av resultatuppsättningar som erhållits från databasen. Släpptes som en del av JDK 1.1 1997 var JDBC en av de första komponenterna som utvecklats för Java-persistenslagret.

JDBC var ursprungligen tänkt som ett API på klientsidan, vilket gjorde det möjligt för en Java-klient att interagera med en datakälla. Det ändrades med JDCB 2.0, som inkluderade ett valfritt paket som stöder JDBC-anslutningar på serversidan. Varje ny JDBC-release sedan dess har uppdateringar för både paketet på klientsidan ( java.sql) och paketet på serversidan ( javax.sql). JDBC 4.3, den senaste versionen i skrivande stund, släpptes som en del av Java SE 9 i september 2017.

Den här artikeln presenterar en översikt över JDBC, följt av en praktisk introduktion till att använda JDBC API för att ansluta en Java-klient med SQLite, en lätt relationsdatabas.

Hur JDBC fungerar

JDBC har utvecklats som ett alternativ till det C-baserade ODBC (Open Database Connectivity) API och erbjuder ett gränssnitt på programmeringsnivå som hanterar mekaniken i Java-applikationer som kommunicerar med en databas eller RDBMS. JDBC-gränssnittet består av två lager:

  1. JDBC API stöder kommunikation mellan Java-applikationen och JDBC-chefen.
  2. JDBC-drivrutinen stöder kommunikation mellan JDBC-chefen och databasdrivrutinen.

JDBC är det vanliga API som din applikationskod interagerar med. Under det finns den JDBC-kompatibla drivrutinen för den databas du använder.

Figur 1 är en arkitektonisk översikt av JDBC i Java-persistenslagret.

JavaWorld /

Använda JDBC för att ansluta till en databas

En av de lyckliga fakta vid programmering i Java-ekosystemet är att du sannolikt kommer att hitta en stabil JDBC-databaskontakt för vilken databas du än väljer. I den här handledningen använder vi SQLite för att lära känna JDBC, främst för att det är så enkelt att använda.

Stegen för anslutning till en databas med JDBC är följande:

  1. Installera eller lokalisera databasen du vill komma åt.
  2. Inkludera JDBC-biblioteket.
  3. Se till att JDBC-drivrutinen du behöver finns på din klassväg.
  4. Använd JDBC-biblioteket för att få en anslutning till databasen.
  5. Använd anslutningen för att utfärda SQL-kommandon.
  6. Stäng anslutningen när du är klar.

Vi går igenom dessa steg tillsammans.

Hitta en JDBC-drivrutin

För att hitta en drivrutin för den databas du vill använda, gör du bara en webbsökning för din databas och JDBC. Om du till exempel skriver in " mysql jdbc driver" kommer en drivrutin för MySQL att visas. Jag utmanar dig att hitta en Java-kompatibel databas utan JDBC-drivrutin!

Steg 1. Ladda ner och installera SQLite

SQLite är en mycket kompakt databas. Den är inte avsedd för produktionsanvändning, men är ett utmärkt val för att snabbt prova saker. SQLite använder en fil som sin funktionella databas, utan att det krävs några service- eller demoninstallationer.

För att komma igång med denna demo, gå vidare och ladda ner SQLite-exempeldatabasen. Packa upp .dbfilen och spara den någonstans du inte kommer att glömma.

Den här filen innehåller både en funktionell filbaserad databas och ett provschema och data vi kan använda.

SQL och JDBC

NoSQL har blivit populärt under det senaste decenniet, men relationsdatabaser är fortfarande den vanligaste typen av datalager som används. En relationsdatabas är en strukturerad databas som består av tabeller med kolumner och rader. SQL (Structured Query Language) är den språkdata som arkitekter använder för att göra saker som att skapa, läsa, uppdatera och ta bort nya poster i en relationsdatabas. JDBC är ett adapterskikt från Java till SQL: det ger Java-utvecklare ett gemensamt gränssnitt för anslutning till en databas, utfärdande av frågor och kommandon och hantering av svar.

Steg 2. Importera JDBC till ditt Java-program

Vi skulle kunna göra vår kodning i en IDE, men kodning direkt i en textredigerare visar bättre JDBC: s enkelhet. För att börja måste du ha en kompatibel JDK-installation för ditt operativsystem.

Förutsatt att du har Java-plattformens utvecklingsverktyg installerat kan vi börja med att skapa ett enkelt Java-program. Klistra in koden i listan i textredigeraren 1. Ring den här filen WhatIsJdbc.java.

Listing 1. Ett enkelt Java-program

 class WhatIsJdbc{ public static void main(String args[]){ System.out.println("Hello JavaWorld"); } } 

Nu kompilera koden genom att ange kommandot: javac WhatIsJdbc.java. Kompilering kommer att mata ut WhatIsJdbc.classfilen. Kör den här filen från kommandoraden med samtalet: java WhatIsJdbc.

[Se "Vad är JDK? Introduktion till Java Developer Kit" för mer information om interaktion med JDK på kommandoraden.]

När du väl har ett grundläggande Java-program kan du inkludera JDBC-biblioteken. Klistra in koden från Listing 2 i spetsen för ditt enkla Java-program.

Listning 2. JDBC-import

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; 

Var och en av dessa importer ger åtkomst till en klass som underlättar standard Java-databasanslutningen:

  • Connection representerar anslutningen till databasen.
  • DriverManagerfår anslutningen till databasen. (Ett annat alternativ är DataSource, används för poolning av anslutningar.)
  • SQLException hanterar SQL-fel mellan Java-applikationen och databasen.
  • ResultSetoch Statementmodellera dateresultatuppsättningarna och SQL-uttalanden.

Vi ser var och en av dessa i aktion snart.

Steg 3. Lägg till JDBC-drivrutinen till din klassväg

Därefter lägger du till SQLite-drivrutinen i din klassväg. En JDBC-drivrutin är en klass som implementerar JDBC API för en specifik databas.

Ladda ner SQLite-drivrutinen från GitHub. Var noga med att få den senaste .jarfilen och förvara den någonstans du kommer ihåg.

The next time you execute your Java program, you will pull that .jar file in via the classpath. There are several ways to set the classpath. Listing 3 shows how to do it using a command-line switch.

Listing 3. Executing SQLite driver on the Java classpath

 java.exe -classpath /path-to-driver/sqlite-jdbc-3.23.1.jar:. WhatIsJdbc 

Notice that we've set the classpath to point at the driver and the local directory; this way Java will still find our class file.

Step 4. Obtain a database connection

The classpath now has access to the driver. Now, change your simple Java application file to look like the program in Listing 4.

Listing 4. Using the JDBC Connection class to connect to SQLite

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; class WhatIsJdbc{ public static void main(String[] args) { Connection conn = null; try { String url = "jdbc:sqlite:path-to-db/chinook/chinook.db"; conn = DriverManager.getConnection(url); System.out.println("Got it!"); } catch (SQLException e) { throw new Error("Problem", e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException ex) { System.out.println(ex.getMessage()); } } } } 

Compile and execute this code. Assuming all goes well, you will get an affirming message.

No suitable driver found?

If you've received an error that looks like "No suitable driver found for jdbc:sqlite," then you need to revisit the classpath and make sure it points to the driver you downloaded. Failed driver connection is the most common stumbling block for beginners using JDBC. Don't sweat it; just fix it.

Now we're ready for some SQL commands.

Step 5. Query the database

With the live connection object in hand, we can do something useful, like querying the database. Listing 5 shows how to query SQLite using the JDBC Connection and Statement objects.

Listing 5. Querying the database with JDBC

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; class WhatIsJdbc{ public static void main(String[] args) { Connection conn = null; try { String url = "jdbc:sqlite:path-to-db-file/chinook/chinook.db"; conn = DriverManager.getConnection(url); Statement stmt = null; String query = "select * from albums"; try { stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String name = rs.getString("title"); System.out.println(name); } } catch (SQLException e ) { throw new Error("Problem", e); } finally { if (stmt != null) { stmt.close(); } } } catch (SQLException e) { throw new Error("Problem", e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException ex) { System.out.println(ex.getMessage()); } } } } 

In Listing 5 we use our Connection object to obtain a Statement object: conn.createStatement(). We then use this object to execute an SQL query: stmt.executeQuery(query).

The executeQuery command returns a ResultSet object, which we then use to iterate over the data with while (rs.next()). In this example, you should see the album titles we've queried on as output.

Notice that we also closed the connection, via a call to conn.close().

Network connections with JDBC

The database connection string in Listing 5 is for a local connection: jdbc:sqlite:path-to-db-file/chinook/chinook.db. To access the database via a network, the connection string would need to include the network URL and (usually) credentials for accessing it.

Doing more with JDBC

So far we've covered the basics of using JDBC to connect to a database and issue SQL commands. While Statementss and ResultSets work well for common scenarios, you'll likely need additional options for larger or more complex applications. Fortunately, the JDBC library continues evolving to meet most database access needs.

PreparedStatements

One easy way to increase the flexibility of your code is to replace the Statement class with PreparedStatement, as shown in Listing 6.

Listing 6. Using JDBC PreparedStatements

 String prepState = "insert into albums values (?, ?);"; PreparedStatement prepState = connection.prepareStatement(sql); prepState.setString(1, "Uprising"); prepState.setString(2, "Bob Marley and the Wailers "); int rowsAffected = preparedStatement.executeUpdate(); 

PreparedStatement replaces Statement's hard-coded values with question marks (?). Using PreparedStatements optimizes your code for reuse: a PreparedStatement is compiled only once, and can then be reused with a variety of parameters. As your code base grows, you simply insert new values into the statement, instead of hacking the string object itself.

Batch updates

Whenever an application has several updates to issue, doing them in batches can greatly benefit performance. The essence of batching is to take the multiple updates and collect them together, then issue them all at once. Listing 7 uses JDBC's batch methods to perform a batch update of several PreparedStatements.

Listing 7. Batching with PreparedStatement

 prepState.setString(1, "Uprising"); prepState.setString(2, "Bob Marley and the Wailers"); preparedStatement.addBatch(); prepState.setString(1, "Wildflowers"); prepState.setString(2, "Tom Petty and the Heartbreakers"); preparedStatement.addBatch(); int[] rowsAffected = preparedStatement.executeBatch(); 

JDBC transactions

Transactions in relational databases allow for a set of updates to be wrapped in an interaction that either succeeds or fails altogether. The basics of using a transaction via JDBC are to tell the system to turn off auto-commit, and then manually tell the system to commit when you are done. By default, auto-commit is on, which means whenever an executeUpdate or executeInsert is run, the command is committed.

Listing 8 shows a small slice of a JDBC transaction.

Listing 8. JDBC transactions

 connection.setAutoCommit(false); // Use executeUpdate multiple times connection.commit(); 

When connection.commit() is encountered, all the updates wrapped inside will be attempted, and if any fail, they all will be rolled back.

There are many more features in JDBC 4.3 worth exploring, including using CallableStatement for stored procedures, using DataSource objects for improved application performance (especially via connection pooling), and converting a JDBC ResultSet to a Java Stream.

Database-specific features

Although every JDBC-compliant database offers the same core features for connecting and interacting with a database via SQL, some databases do more than others. As an example, Oracle DB offers result caching, which is not required by the JDBC specification. Here's an example:

 conn.prepareStatement ("select /*+ result_cache */ * from employees where employee_id < : 1"); 

This example is taken from the documentation for Oracle's JDBC OCI Driver.

Conclusion

JDBC is one of Java's oldest APIs, providing an easy-to-use solution for one of the perennial needs of Java application development. Knowing just the few JDBC calls demonstrated in this article will get you started using JDBC to connect to virtually any database. Once you've got those commands down, you can begin to explore some of the more sophisticated options that have been built into JDBC.

Medan JDBC räcker för enklare applikationer kommer de flesta utvecklare så småningom att titta på Java Persistence API (JPA) för att utveckla ett mer formellt åtkomstlager för data. JPA kräver mer tidigt arbete och en mer sofistikerad förståelse för applikationsarkitekturen, men det ger dig ett mer konsekvent, isolerat och väldefinierat dataåtkomstlager. Se följeslagaren till den här artikeln, "Vad är JPA? Introduktion till Java Persistence API" för mer information om hur du utvecklar datapersentionsskiktet för dina Java-applikationer.

Denna berättelse, "Vad är JDBC? Introduktion till Java Database Connectivity" publicerades ursprungligen av JavaWorld.