Что такое JDBC? Введение в подключение к базе данных Java

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

Разработанный как альтернатива API ODBC (Open Database Connectivity) на основе C, JDBC предлагает интерфейс на уровне программирования, который управляет механизмами взаимодействия приложений Java с базой данных или СУБД. Интерфейс JDBC состоит из двух уровней:

  1. API JDBC поддерживает связь между приложением 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 (язык структурированных запросов) - это язык, который архитекторы данных используют для таких вещей, как создание, чтение, обновление и удаление новых записей в реляционной базе данных. 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 Persistence API» для получения дополнительной информации о разработке уровня сохранения данных для ваших приложений Java.

Этот рассказ «Что такое JDBC? Введение в возможности подключения к базам данных Java» был первоначально опубликован JavaWorld.