Какво е JDBC? Въведение в Java Database Connectivity

JDBC (Java Database Connectivity) е Java API, който управлява свързването към база данни, издава заявки и команди и обработва набори от резултати, получени от базата данни. Издаден като част от JDK 1.1 през 1997 г., JDBC е един от първите компоненти, разработени за Java персистентния слой.

JDBC първоначално е замислен като API от страна на клиента, позволяващ на Java клиент да взаимодейства с източник на данни. Това се промени с JDCB 2.0, който включва незадължителен пакет, поддържащ JDBC връзки от страна на сървъра. Всяко ново издание на JDBC оттогава включва актуализации както на клиентския пакет ( java.sql), така и на сървърния пакет ( javax.sql). JDBC 4.3, най-актуалната версия към настоящия момент, беше пусната като част от Java SE 9 през септември 2017 г.

Тази статия представя общ преглед на JDBC, последван от практическо въведение в използването на JDBC API за свързване на Java клиент с SQLite, лека релационна база данни.

Как работи JDBC

Разработен като алтернатива на C-базиран ODBC (Open Database Connectivity) API, JDBC предлага интерфейс на ниво програмиране, който обработва механиката на Java приложения, комуникиращи с база данни или RDBMS. Интерфейсът JDBC се състои от два слоя:

  1. JDBC API поддържа комуникация между Java приложението и JDBC мениджъра.
  2. JDBC драйверът поддържа комуникация между JDBC мениджъра и драйвера на базата данни.

JDBC е често срещаният API, с който кодът на приложението ви взаимодейства. Под това е JDBC-съвместимият драйвер за базата данни, която използвате.

Фигура 1 е архитектурен преглед на JDBC в слоя за устойчивост на Java.

JavaWorld /

Използване на JDBC за свързване към база данни

Един от щастливите факти за програмирането в екосистемата на Java е, че вероятно ще намерите стабилен JDBC конектор за база данни за каквато и да е база данни, която изберете. В този урок ще използваме SQLite, за да опознаем JDBC, главно защото е толкова лесен за използване.

Стъпките за свързване към база данни с JDBC са както следва:

  1. Инсталирайте или намерете базата данни, до която искате да осъществите достъп.
  2. Включете JDBC библиотеката.
  3. Уверете се, че JDBC драйверът, от който се нуждаете, е в пътя ви към класа.
  4. Използвайте библиотеката JDBC, за да получите връзка с базата данни.
  5. Използвайте връзката за издаване на SQL команди.
  6. Затворете връзката, когато приключите.

Ще преминем през тези стъпки заедно.

Намиране на JDBC драйвер

За да намерите драйвер за базата данни, която искате да използвате, просто направете уеб търсене за вашата база данни и JDBC. Например, ако въведете " mysql jdbc driver", ще се появи драйвер за MySQL. Предизвиквам ви да намерите съвместима с Java база данни без JDBC драйвер!

Стъпка 1. Изтеглете и инсталирайте SQLite

SQLite е много компактна база данни. Той не е предназначен за производствена употреба, но е чудесен избор за бързо изпробване на нещата. SQLite използва файл като своя функционална база данни, без да изисква инсталиране на услуга или демон.

За да започнете с тази демонстрация, продължете и изтеглете примерната база данни на SQLite. Разархивирайте .dbфайла и го запазете някъде, където няма да забравите.

Този файл съдържа както функционална база данни, базирана на файлове, така и примерна схема и данни, които можем да използваме.

SQL и JDBC

NoSQL стана популярно през последното десетилетие, но релационните бази данни остават най-често използваният тип хранилище на данни. А релационна база данни е структурирано хранилище, състояща се от таблици с колони и редове. SQL (Structured Query Language) е езикът, който архитектите на данни използват за създаване, четене, актуализиране и изтриване на нови записи в релационна база данни. JDBC е адаптерен слой от Java към SQL: той дава на разработчиците на Java общ интерфейс за свързване към база данни, издаване на заявки и команди и управление на отговори.

Стъпка 2. Импортирайте JDBC във вашето Java приложение

Можем да направим кодирането си в IDE, но кодирането директно в текстов редактор ще покаже по-добре простотата на JDBC. За начало ще трябва да имате съвместима JDK инсталация за вашата операционна система.

Ако приемем, че имате инсталирани инструменти за разработчици на Java платформа, можем да започнем със създаването на проста Java програма. Във вашия текстов редактор поставете кода, показан в Листинг 1. Извикайте този файл WhatIsJdbc.java.

Листинг 1. Проста Java програма

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

Сега компилира код, като въведете командата: javac WhatIsJdbc.java. Компилирането ще изведе WhatIsJdbc.classфайла. Изпълнение на този файл от командния ред с призива: java WhatIsJdbc.

[Вижте „Какво представлява JDK? Въведение в Java Developer Kit“ за повече информация относно взаимодействието с JDK в командния ред.]

След като имате основна Java програма, можете да включите JDBC библиотеките. Поставете кода от Листинг 2 в главата на вашата проста Java програма.

Листинг 2. Внос на JDBC

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

Всеки от тези импорти предоставя достъп до клас, който улеснява стандартната връзка с база данни на Java:

  • Connection представлява връзката с базата данни.
  • DriverManagerполучава връзката с базата данни. (Друга опция е DataSource, използвана за обединяване на връзки.)
  • SQLException обработва SQL грешки между приложението Java и базата данни.
  • ResultSetи Statementмоделира наборите от резултати от данни и SQL изрази.

Ще видим всеки от тях в действие скоро.

Стъпка 3. Добавете JDBC драйвер към вашия път към класа

След това ще добавите драйвера на SQLite към пътя си към класа. А JDBC драйвер е клас, който реализира JDBC API за конкретна база данни.

Изтеглете драйвера на SQLite от GitHub. Не забравяйте да вземете най-новия .jarфайл и да го съхраните някъде, където ще запомните.

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.

Докато JDBC е достатъчен за по-прости приложения, повечето разработчици в крайна сметка ще се обърнат към Java Persistence API (JPA), за да разработят по-официален слой за достъп до данни. JPA изисква повече предварителна работа и по-сложно разбиране на архитектурата на приложението, но ви свързва по-последователен, изолиран и добре дефиниран слой за достъп до данни. Вижте придружителя на тази статия, „Какво е JPA? Въведение в Java Persistent API“ за повече информация относно разработването на слоя за устойчивост на данни за вашите Java приложения.

Тази история „Какво е JDBC? Въведение в свързването на база данни на Java“ първоначално е публикувана от JavaWorld.