- Как использовать базу данных MySQL в Java
- Подключаем базу данных MySQL с помощью JDBC
- Программа на Java, которая использует базу данных
- Получаем данные с помощью SELECT-запроса в JDBC
- Добавляем данные с помощью INSERT-запроса в JDBC
- Полезные ссылки
- Подключаемся к базе данных из Java-приложения
- JDBC Driver Manager
- Подключаемся к MySQL-серверу
Как использовать базу данных MySQL в Java
В этой статье мы научимся подключаться к базе данных MySQL из Java-кода и выполнять простые запросы для получения и обновления данных. Для того, чтобы получить доступ к базе данных, мы будем использовать JDBC (Java Database Connectivity) API, который входит в стандартную библиотеку Java. JDBC позволяет подключиться к любой базе данных: Postgres, MySQL, SQL Server, Oracle и т. д. — при наличии соответствующей реализации драйвера, необходимого для подключения. Для базы данных MySQL мы будем использовать драйвер Type 4 JDBC из пакета mysql-connector-java-5.1.23-bin.jar . Он написан на чистой Java, а значит, нам не понадобятся какие-либо нативные библиотеки или ODBC-мост. Все, что нам надо будет сделать — это положить JAR-файл в директорию, содержащуюся в CLASSPATH. JAR-файл содержит класс com.mysql.jdbc.Driver , необходимый для подключения к MySQL. Если его не окажется в CLASSPATH, во время выполнения программы выбросится исключение java.lang.ClassNotFoundException , поэтому убедитесь, что вы правильно настроили пути.
Кстати, если вы ищете хорошую книгу по использованию JDBC, обратите внимание на Practical Database Programming with Java (Ying Bai). Это относительно новая книга, и в ней рассматриваются две самые популярные базы данных: Oracle и SQL Server 2008. В книге используется IDE NetBeans для примеров и описываются все инструменты, необходимые для работы с базами данных в Java. Это отличная книга для начинающих и опытных программистов.
Подключаем базу данных MySQL с помощью JDBC
Для того, чтобы подключить базу данных MySQL, нам потребуется четыре вещи:
- Строка подключения JDBC (например:
jdbc:mysql://localhost:3306/test). - Имя пользователя (root).
- Пароль (root).
- База данных с некоторым количеством таблиц для примера (например, база данных книг).
Строка подключения для MySQL начинается с jdbc:mysql . Это название протокола соединения, за которым следуют хост и порт подключения, на которых запущена база данных. В нашем случае это localhost с портом по умолчанию 3306 (если вы его не поменяли при установке). Следующая часть — test — имя базы данных, которая уже существует в MySQL. Мы можем создать таблицу Books :
CREATE TABLE `books` ( `id` int(11) NOT NULL, `name` varchar(50) NOT NULL, `author` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
и наполнить её хорошими книгами:
INSERT INTO test.books (id, `name`, author) VALUES (1, 'Effective Java', 'Joshua Bloch'); INSERT INTO test.books (id, `name`, author) VALUES (2, 'Java Concurrency in Practice', 'Brian Goetz');
Программа на Java, которая использует базу данных
Теперь давайте напишем программу на Java, которая будет подключаться к нашей базе данных, запущенной на localhost . Важно помнить о том, что необходимо закрывать соединение, запросы и результат выполнения после завершения работы с ними. Также важно закрывать их в finally-блоке, со своей try/catch оберткой, поскольку сам метод close() может кинуть исключение, что приведет к утечке ресурсов. За подробной информацией вы можете обратиться к этой статье. Кроме того, вы можете использовать обертку try-with-resource, которая появилась в Java 7. Более того, это стандартный способ работы с ресурсами в Java 1.7.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * Simple Java program to connect to MySQL database running on localhost and * running SELECT and INSERT query to retrieve and add data. * @author Javin Paul */ public class JavaToMySQL < // JDBC URL, username and password of MySQL server private static final String url = "jdbc:mysql://localhost:3306/test"; private static final String user = "root"; private static final String password = "root"; // JDBC variables for opening and managing connection private static Connection con; private static Statement stmt; private static ResultSet rs; public static void main(String args[]) < String query = "select count(*) from books"; try < // opening database connection to MySQL server con = DriverManager.getConnection(url, user, password); // getting Statement object to execute query stmt = con.createStatement(); // executing SELECT query rs = stmt.executeQuery(query); while (rs.next()) < int count = rs.getInt(1); System.out.println("Total number of books in the table : " + count); >> catch (SQLException sqlEx) < sqlEx.printStackTrace(); >finally < //close connection ,stmt and resultset here try < con.close(); >catch(SQLException se) < /*can't do anything */ >try < stmt.close(); >catch(SQLException se) < /*can't do anything */ >try < rs.close(); >catch(SQLException se) < /*can't do anything */ >> > >
При первом запуске у вас, возможно, будет ошибка No suitable driver found for jdbc:mysql , если драйвера MySQL нет в CLASSPATH:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test/book at java.sql.DriverManager.getConnection(DriverManager.java:689) at java.sql.DriverManager.getConnection(DriverManager.java:247) at JavaToMySQL.main(JavaToMySQL.java:29) Exception in thread "main" java.lang.NullPointerException at JavaToMySQL.main(JavaToMySQL.java:46) Java Result: 1
Добавим нужный JAR-файл в путь и снова запустим программу. Другая частая ошибка — указать таблицу в строке соединения: jdbc:mysql://localhost:3306/test/book . В этом случае вылетит следущее исключение:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'test/book' at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:408) at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) at com.mysql.jdbc.Util.getInstance(Util.java:386) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053)
Успешный запуск программы выведет на экран следующее:
Total number of books in the table: 2
Результат верный, поскольку у нас в таблице только две книги: «Effective Java» и «Java Concurrency in Practice».
Кстати, если у вас был драйвер при компиляции, но отсутствует при запуске, вы получите исключение java.lang.ClassNotFoundException: com.mysql.jdbc.Driver . О том, как исправить эту ошибку, вы можете прочитать здесь.
Получаем данные с помощью SELECT-запроса в JDBC
Для получения данных из БД вы можете выполнить SELECT-запрос. В первом примере мы уже его использовали, но получили только количество строк. Теперь мы вернем сами строки. Большая часть программы останется без изменений, за исключением SQL-запроса и кода, возвращающего данные из объекта ResultSet :
String query = "select id, name, author from books"; rs = stmt.executeQuery(query); while (rs.next())
Этот код выведет на экран следующее:
id: 1, name: Effective Java, author: Joshua Bloch id: 2, name: Java Concurrency in Practice, author: Brian Goetz
Тут есть пара моментов, на которые следует обратить внимание. Метод rs.getInt(1) используется для получения столбца с целочисленным типом, в нашем случае это столбец «id». Индексы в JDBC начинаются с единицы, поэтому rs.getInt(1) вернет значение первого столбца как целое число. В случае, если вы укажете неверный индекс (многие разработчики вызывают rs.getInt(0) для получения первого столбца), выбросится исключение InvalidColumnIndexException . Доступ к столбцам по индексу чреват ошибками, поэтому лучше использовать имя столбца, например, rs.getInt(«id») . Подробнее об этом вы можете прочитать в этой статье. Метод getString() используется для получения строковых значений из базы (например, VARCHAR ). Цикл будет выполняться, пока rs.next() не вернет false . Это значит, что строки закончились. В нашем случае в таблице две строки, поэтому цикл выполнится два раза, выводя информацию о книгах из таблицы на экран.
Добавляем данные с помощью INSERT-запроса в JDBC
Добавление данных мало отличается от их получения: мы просто используем INSERT-запрос вместо SELECT-запроса и метод executeUpdate() вместо executeQuery() . Этот метод используется для запросов INSERT, UPDATE и DELETE, а также для SQL DDL выражений, таких как CREATE, ALTER или DROP. Эти команды не возвращают результата, поэтому мы убираем все упоминания ResultSet ‘а в коде и изменяем запрос соответственно:
String query = "INSERT INTO test.books (id, name, author) \n" + " VALUES (3, 'Head First Java', 'Kathy Sieara');"; // executing SELECT query stmt.executeUpdate(query);
После запуска программы вы можете проверить таблицу в СУБД. На этот раз вы увидите три записи в таблице:
Теперь вы умеете подключаться к MySQL из Java-приложения и выполнять SELECT, INSERT, DELETE и UPDATE-запросы так же, как и в MySQL GUI. Для подключения мы используем объект Connection , для чтения результатов запроса — ResultSet . Убедитесь перед подключением, что сервер MySQL запущен и mysql-connector-java-5.1.17-bin.jar находится в CLASSPATH, чтобы избежать ClassNotFoundException .
Когда разберетесь с подключением и простыми запросами, имеет смысл изучить, как использовать подготавливаемые запросы (Prepared Statement) в Java для избежания SQL-инъекции. В боевом коде всегда следует использовать подготавливаемые запросы и связывание переменных.
Если вам понравилось это руководство и не терпится узнать больше о подключении и работе с базой данных из Java-программ, обратите внимание на следующие статьи:
Полезные ссылки
- Если у вас нет базы данных MySQL, вы можете ее скачать здесь;
- Есди у вас нет драйвера MySQL для JDBC, вы можете скачать его отсюда;
- Рекомендованную книгу «Practical Database Programming with Java» можно купить на Amazon.
Подключаемся к базе данных из Java-приложения
Ты знаешь основы SQL. Это хорошо. Но сегодня тебе станет еще лучше. Сегодня ты начнешь изучать, как работать с базой данных из Java-приложения.
Различных СУБД очень много, поэтому создатели Java решили стандартизировать работу Java-приложения с базами данных. И назвали они этот стандарт – JDBC : Java DataBase Connectivity.
В JDBC есть 3 основных интерфейса:
- Connection – отвечает за соединение с базой данных
- Statement – отвечает за запрос к базе данных
- ResultSet – отвечает за результат запроса к базе данных
Фактически, это все. И мы даже не будем изучать все методы всех интерфейсов. Только рабочие примеры, которые понемногу будем усложнять.
JDBC чем-то напоминает работу с сервлетами. Создатели JDBC написали несколько интерфейсов и гордо назвали это Java DataBase API. А реализацию этих интерфейсов возложили на… создателей СУБД. Как оно там реализовано – никого не интересует. Работает и ладно.
Есть четыре версии JDBC и мы будет изучать самую последнюю. И не потому, что она самая крутая, а потому что она самая простая.
JDBC Driver Manager
Java-приложение и база данных общаются друг с другом посредством библиотеки, которая называется JDBC Driver. Это набор классов, которые реализуют JDBC API для конкретной СУБД.
Правильные JDBC драйвер же выбирается с помощью класса под названием DriverManager. Их взаимодействие можно представить такой картинкой:
Штука в том, что ты можешь использовать In-Memory-DB, No-SQL-DB или даже базу данных, встроенную в Android-приложение. Тебя, как Java-разработчика, эти нюансы вообще не касаются. Driver Manager выберет вам правильный JDBC драйвер и все будет работать как часы.
Кстати, а как он это делает?
Подключаемся к MySQL-серверу
Помнишь, что тебе было нужно, чтобы подключиться к локальному SQL-серверу через MySQL Workbench? Если забыл, то я напомню, тебе были нужны три вещи:
С логином и паролем все понятно, а host, если ты помнишь – это имя компьютера, на котором расположен сервер. Если он расположен у тебя на локальном компьютере, то в качестве имени хоста нужно указать localhost. А если не на локальном?
Тогда нужно использовать … URL. URL расшифровывается как Universal Resource Locator. Его можно использовать для указания месторасположения чего-угодно в сети: сайта, принтера, SQL-сервера. На самом деле URL используется и для доступа к локальному SQL-серверу. Он имеет примерно такой вид:
mysql://localhost:3306/db_scheme
- mysql – это протокол работы с сервером
- localhost – имя хоста в сети
- 3306 – порт, по которому идут запросы
- db_scheme – имя схемы (имя базы данных)
Примечание. Имя базы данных можно не указывать. Но если сервер хранит много схем баз данных, то обычно к ним создают разных пользователей и разными правами доступа. И если у пользователя, под которым ты логинишься на SQL-сервер нет доступа ко всем базам, то тебе обязательно нужно указать имя конкретной базы, к которой у тебя есть доступ.
В конце этого url могут идти различные параметры, типы кодировки, timezone, которые считаются параметрами для нового устанавливаемого соединения с базой данных.
Также протокол может быть составным. Если все общение с сервером базы данных идет по зашифрованному каналу с помощью SSH-протокола, тогда URL может быть указан так:
ssh:mysql://localhost:3306/db_scheme
Протокол – это не обязательно внешняя программа. Например, если ты работаешь с сервером по протоколу JNDI, то можешь указать его так:
jndi:mysql://localhost:3306/db_scheme
А если хочешь работать по протоколу JDBC API, то нужно писать так:
jdbc:mysql://localhost:3306/db_scheme
Когда ты пытаешься создать подключение к базе данных, то JDBC Driver Manager анализирует ваш SQL-db-URL и определяет имя JDBC-драйвера по имени протокола. Вот такая вот маленькая хитрость.