Перейти к основному содержимому

Подключить Java к базе данных MySQL

· 9 мин. чтения

1. Обзор

Есть много способов подключиться к базе данных MySQL из Java, и в этом руководстве мы рассмотрим несколько вариантов, чтобы увидеть, как этого добиться.

Мы начнем с рассмотрения, пожалуй, самых популярных вариантов использования JDBC и Hibernate.

Затем мы также рассмотрим некоторые внешние библиотеки, включая MyBatis, Apache Cayenne и Spring Data . Попутно мы приведем ряд практических примеров.

2. Предпосылки

Предположим, что у нас уже есть сервер MySQL, установленный и работающий на локальном хосте (порт по умолчанию 3306), и что у нас есть тестовая схема со следующей таблицей пользователей:

CREATE TABLE person 
(
ID INT,
FIRST_NAME VARCHAR(100),
LAST_NAME VARCHAR(100)
);

Нам также понадобится артефакт mysql-connector-java , который, как всегда, доступен в Maven Central :

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>

3. Подключение с помощью JDBC

JDBC (Java Database Connectivity) — это API для подключения и выполнения запросов к базе данных.

3.1. Общие свойства

В этой статье мы обычно будем использовать несколько общих свойств JDBC :

  • URL-адрес подключения — строка, которую драйвер JDBC использует для подключения к базе данных. Он может содержать такую информацию, как место поиска базы данных, имя базы данных для подключения и другие свойства конфигурации:
jdbc:mysql://[host][,failoverhost...]
[:port]/[database]
[?propertyName1][=propertyValue1]
[&propertyName2][=propertyValue2]...

Мы установим это свойство следующим образом: jdbc:mysql://localhost:3306/test?serverTimezone=UTC.

  • Класс драйвера — полное имя класса используемого драйвера . В нашем случае мы будем использовать драйвер MySQL: com.mysql.cj.jdbc.Driver
  • Имя пользователя и пароль — учетные данные учетной записи MySQL

3.2. Пример соединения JDBC

Давайте посмотрим, как мы можем подключиться к нашей базе данных и выполнить простой select-all через try-with-multiple-resources :

String sqlSelectAllPersons = "SELECT * FROM person";
String connectionUrl = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";

try (Connection conn = DriverManager.getConnection(connectionUrl, "username", "password");
PreparedStatement ps = conn.prepareStatement(sqlSelectAllPersons);
ResultSet rs = ps.executeQuery()) {

while (rs.next()) {
long id = rs.getLong("ID");
String name = rs.getString("FIRST_NAME");
String lastName = rs.getString("LAST_NAME");

// do something with the extracted data...
}
} catch (SQLException e) {
// handle the exception
}

Как мы видим, внутри тела try мы перебираем набор результатов и извлекаем значения из таблицы person.

4. Подключение с помощью ORM

Чаще всего мы подключаемся к нашей базе данных MySQL с помощью инфраструктуры объектно-реляционного сопоставления (ORM) . Итак, давайте посмотрим несколько примеров подключения с использованием более популярных из этих фреймворков.

4.1. Собственные API-интерфейсы Hibernate

В этом разделе мы увидим, как использовать Hibernate для управления соединением JDBC с нашей базой данных.

Во- первых, нам нужно добавить зависимость Hibernate-core Maven:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>

Hibernate требует, чтобы класс сущности был создан для каждой таблицы. Давайте продолжим и определим класс Person :

@Entity
@Table(name = "Person")
public class Person {
@Id
Long id;
@Column(name = "FIRST_NAME")
String firstName;

@Column(name = "LAST_NAME")
String lastName;

// getters & setters
}

Другим важным аспектом является создание файла ресурсов Hibernate, обычно называемого hibernate.cfg.xml , где мы определим информацию о конфигурации:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?serverTimezone=UTC</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!-- Validate the database schema on startup -->
<property name="hbm2ddl.auto">validate</property>

<!-- Names the annotated entity class -->
<mapping class="Person"/>
</session-factory>
</hibernate-configuration>

Hibernate имеет множество свойств конфигурации . Помимо стандартных свойств соединения, стоит упомянуть свойство диалекта, которое позволяет указать имя диалекта SQL для базы данных.

Это свойство используется платформой для правильного преобразования операторов Hibernate Query Language (HQL) в соответствующий SQL для нашей данной базы данных. Hibernate поставляется с более чем 40 диалектами SQL . Поскольку в этой статье мы сосредоточимся на MySQL, мы будем придерживаться диалекта MySQL5Dialect .

Наконец, Hibernate также необходимо знать полное имя класса сущности через тег сопоставления. После завершения настройки мы будем использовать класс SessionFactory , который отвечает за создание и объединение соединений JDBC.

Как правило, это нужно настроить только один раз для приложения:

SessionFactory sessionFactory;
// configures settings from hibernate.cfg.xml
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
try {
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Exception e) {
// handle the exception
}

Теперь, когда у нас настроено соединение, мы можем запустить запрос, чтобы выбрать всех людей из нашей таблицы пользователей:

Session session = sessionFactory.openSession();
session.beginTransaction();

List<Person> result = session.createQuery("from Person", Person.class).list();

result.forEach(person -> {
//do something with Person instance...
});

session.getTransaction().commit();
session.close();

4.2. Мой Батис

MyBatis был представлен в 2010 году и представляет собой среду сопоставления SQL, сила которой заключается в простоте . В другом туториале мы говорили о том, как интегрировать MyBatis с Spring и Spring Boot . Здесь мы сосредоточимся на том, как напрямую настроить MyBatis.

Чтобы использовать его, нам нужно добавить зависимость mybatis :

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>

Предполагая, что мы повторно используем приведенный выше класс Person без аннотаций, мы можем приступить к созданию интерфейса PersonMapper :

public interface PersonMapper {
String selectAll = "SELECT * FROM Person";

@Select(selectAll)
@Results(value = {
@Result(property = "id", column = "ID"),
@Result(property = "firstName", column = "FIRST_NAME"),
@Result(property = "lastName", column = "LAST_NAME")
})
List<Person> selectAll();
}

Следующий шаг посвящен настройке MyBatis:

Configuration initMybatis() throws SQLException {
DataSource dataSource = getDataSource();
TransactionFactory trxFactory = new JdbcTransactionFactory();

Environment env = new Environment("dev", trxFactory, dataSource);
Configuration config = new Configuration(env);
TypeAliasRegistry aliases = config.getTypeAliasRegistry();
aliases.registerAlias("person", Person.class);

config.addMapper(PersonMapper.class);
return config;
}

DataSource getDataSource() throws SQLException {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("test");
dataSource.setServerName("localhost");
dataSource.setPort(3306);
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerTimezone("UTC");

return dataSource;
}

Конфигурация состоит из создания объекта Configuration , который является контейнером для таких настроек, как Environment . Он также содержит настройки источника данных.

Затем мы можем использовать объект Configuration , который обычно настраивается один раз для приложения, чтобы создать SqlSessionFactory :

Configuration configuration = initMybatis();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper mapper = session.getMapper(PersonMapper.class);
List<Person> persons = mapper.selectAll();

// do something with persons list ...
}

4.3. Апач Кайенна

Apache Cayenne — это фреймворк персистентности, первый релиз которого датируется 2002 годом. Чтобы узнать о нем больше, предлагаем прочитать наше введение в Apache Cayenne .

Как обычно, добавим зависимость cayenne-server от Maven: ``

<dependency>
<groupId>org.apache.cayenne</groupId>
<artifactId>cayenne-server</artifactId>
<version>4.0.2</version>
</dependency>

Мы собираемся специально сосредоточиться на настройках подключения к MySQL. В этом случае мы настроим cayenne-project.xml :

<?xml version="1.0" encoding="utf-8"?>
<domain project-version="9">
<map name="datamap"/>
<node name="datanode"
factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy">
<map-ref name="datamap"/>
<data-source>
<driver value="com.mysql.cj.jdbc.Driver"/>
<url value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>
<connectionPool min="1" max="1"/>
<login userName="username" password="password"/>
</data-source>
</node>
</domain>

После автоматической генерации класса datamap.map.xml и Person в виде CayenneDataObject мы можем выполнять некоторые запросы.

Например, мы продолжим, как и раньше, с выбором всего:

ServerRuntime cayenneRuntime = ServerRuntime.builder()
.addConfig("cayenne-project.xml")
.build();

ObjectContext context = cayenneRuntime.newContext();
List<Person> persons = ObjectSelect.query(Person.class).select(context);

// do something with persons list...

5. Подключение с использованием данных Spring

Spring Data — это основанная на Spring модель программирования для доступа к данным. Технически Spring Data — это зонтичный проект, который содержит множество подпроектов, специфичных для данной базы данных.

Давайте посмотрим, как использовать два из этих проектов для подключения к базе данных MySQL.

5.1. Весенние данные / JPA

Spring Data JPA — это надежная среда, которая помогает сократить шаблонный код и предоставляет механизм для реализации основных операций CRUD через один из нескольких предопределенных интерфейсов репозитория . Помимо этого, у него есть много других полезных функций.

Обязательно ознакомьтесь с нашим введением в Spring Data JPA , чтобы узнать больше.

Артефакт spring-data-jpa можно найти на Maven Central :

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>

Мы продолжим использовать класс Person . Следующим шагом будет настройка JPA с использованием аннотаций:

@Configuration
@EnableJpaRepositories("packages.to.scan")
public class JpaConfiguration {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
dataSource.setUsername( "username" );
dataSource.setPassword( "password" );
return dataSource;
}

@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}

@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.MYSQL);
jpaVendorAdapter.setGenerateDdl(true);
return jpaVendorAdapter;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lemfb = new LocalContainerEntityManagerFactoryBean();
lemfb.setDataSource(dataSource());
lemfb.setJpaVendorAdapter(jpaVendorAdapter());
lemfb.setPackagesToScan("packages.containing.entity.classes");
return lemfb;
}
}

Чтобы позволить Spring Data реализовать операции CRUD, мы должны создать интерфейс, расширяющий интерфейс CrudRepository :

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

}

И, наконец, давайте посмотрим на пример select-all с Spring Data:

personRepository.findAll().forEach(person -> {
// do something with the extracted person
});

5.2. Весенние данные / JDBC

Spring Data JDBC — это ограниченная реализация семейства Spring Data, основной целью которой является обеспечение простого доступа к реляционным базам данных .

По этой причине он не предоставляет такие функции, как кэширование, грязное отслеживание, отложенная загрузка и многие другие функции JPA.

На этот раз нам нужна зависимость Maven: spring-data-jdbc :

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>

Конфигурация легче по сравнению с той, которую мы использовали в предыдущем разделе для Spring Data JPA:

@Configuration
@EnableJdbcRepositories("packages.to.scan")
public class JdbcConfiguration extends AbstractJdbcConfiguration {
// NamedParameterJdbcOperations is used internally to submit SQL statements to the database
@Bean
NamedParameterJdbcOperations operations() {
return new NamedParameterJdbcTemplate(dataSource());
}

@Bean
PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}

@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
}

В случае Spring Data JDBC мы должны определить новый класс Person или изменить существующий, чтобы добавить некоторые специфичные для Spring аннотации .

Это связано с тем, что Spring Data JDBC позаботится непосредственно о сопоставлении сущностей вместо Hibernate:

import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

@Table(value = "Person")
public class Person {
@Id
Long id;

@Column(value = "FIRST_NAME")
String firstName;

@Column(value = "LAST_NAME")
String lastName;

// getters and setters
}

С Spring Data JDBC мы также можем использовать интерфейс CrudRepository . Таким образом, объявление будет идентично тому, которое мы написали выше в примере Spring Data JPA. То же самое относится и к примеру с выбором всех.

6. Заключение

В этом руководстве мы рассмотрели несколько различных способов подключения к базе данных MySQL из Java . Мы начали с основного соединения JDBC. Затем мы рассмотрели часто используемые ORM, такие как Hibernate, Mybatis и Apache Cayenne. Наконец, мы рассмотрели Spring Data JPA и Spring Data JDBC.

Использование API JDBC или Hibernate означает больше шаблонного кода. Использование надежных фреймворков, таких как Spring Data или Mybatis, требует дополнительной настройки, но дает значительное преимущество, поскольку они предоставляют стандартные реализации и функции, такие как кэширование и отложенная загрузка.