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 :
mysql mysql-connector-java 8.0.19
3. Подключение с помощью JDBC
JDBC (Java Database Connectivity) – это API для подключения и выполнения запросов к базе данных.
3.1. Общие свойства
В ходе этой статьи мы обычно будем использовать несколько общих свойств JDBC :
- URL-адрес подключения – строка, которую драйвер JDBC использует для подключения к базе данных. Он может содержать такую информацию, как место поиска базы данных, имя базы данных для подключения и другие свойства конфигурации:
Мы установим это свойство следующим образом: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
- Класс драйвера – полное имя класса драйвера для использования. В нашем случае мы будем использовать драйвер MySQL: com.mysql.cj.jdbc.Driver
- Имя пользователя и пароль – учетные данные учетной записи MySQL
3.2. Пример подключения JDBC
Давайте посмотрим, как мы можем подключиться к нашей базе данных и выполнить простой выбор-все через попытку с несколькими ресурсами:
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. Подключение с помощью ORMs
Как правило, мы подключаемся к нашей базе данных MySQL с помощью фреймворка объектно-реляционного отображения (ORM) . Итак, давайте рассмотрим несколько примеров подключения с использованием более популярных из этих фреймворков.
4.1. Собственные API гибернации
В этом разделе мы рассмотрим, как использовать Hibernate для управления подключением JDBC к нашей базе данных.
Во-первых, нам нужно добавить зависимость hibernate-core Maven:
org.hibernate hibernate-core 5.4.10.Final
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 , где мы определим информацию о конфигурации:
com.mysql.cj.jdbc.Driver jdbc:mysql://localhost:3306/test?serverTimezone=UTC username password org.hibernate.dialect.MySQL5Dialect validate
Hibernate имеет множество свойств конфигурации . Помимо стандартных свойств подключения, стоит упомянуть свойство dialect, которое позволяет нам указать имя диалекта 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 }
Теперь, когда у нас настроено соединение, мы можем запустить запрос, чтобы выбрать всех людей из нашей таблицы person:
Session session = sessionFactory.openSession(); session.beginTransaction(); Listresult = session.createQuery("from Person", Person.class).list(); result.forEach(person -> { //do something with Person instance... }); session.getTransaction().commit(); session.close();
4.2. MyBatis
MyBatis был представлен в 2010 году и представляет собой платформу SQL mapper с простотой в качестве ее сильной стороны . В другом уроке мы говорили о как интегрировать MyBatis с Spring и Spring Boot . Здесь мы сосредоточимся на том, как настроить MyBatis напрямую.
Чтобы использовать его, нам нужно добавить зависимость mybatis :
org.mybatis mybatis 3.5.3
Предполагая, что мы повторно используем класс 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") }) ListselectAll(); }
Следующий шаг касается конфигурации 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); Listpersons = mapper.selectAll(); // do something with persons list ... }
4.3. Кайенский перец Apache
Apache Cayenne – это фреймворк персистентности, первый выпуск которого датируется 2002 годом. Чтобы узнать больше об этом, мы предлагаем прочитать наше введение в Apache Cayenne .
Как обычно, давайте добавим зависимость |/cayenne-server Maven:
org.apache.cayenne cayenne-server 4.0.2
Мы собираемся специально сосредоточиться на настройках подключения к MySQL. В этом случае мы настроим cayenne-project.xml :
После автоматической генерации datamap.map.xml и Person class в виде CayenneDataObject , мы можем выполнить некоторые запросы.
Например, мы продолжим, как и ранее, с выбором всех:
ServerRuntime cayenneRuntime = ServerRuntime.builder() .addConfig("cayenne-project.xml") .build(); ObjectContext context = cayenneRuntime.newContext(); Listpersons = ObjectSelect.query(Person.class).select(context); // do something with persons list...
5. Подключение С Использованием Данных Spring
Spring Data -это модель программирования на основе пружин для доступа к данным. Технически Spring Data-это зонтичный проект, который содержит множество подпроектов, специфичных для данной базы данных.
Давайте посмотрим, как использовать два из этих проектов для подключения к базе данных MySQL.
5.1. Весенние данные/JPA
Spring Data JPA-это надежная платформа, которая помогает сократить шаблонный код и обеспечивает механизм для реализации основных операций CRUD через один из нескольких предопределенных интерфейсов репозитория . В дополнение к этому, он имеет много других полезных функций.
Обязательно ознакомьтесь с нашим введением в Spring Data JPA, чтобы узнать больше.
Артефакт spring-data-jpa можно найти на Maven Central :
org.springframework.data spring-data-jpa 2.2.4.RELEASE
Мы продолжим использовать класс 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{ }
И, наконец, давайте рассмотрим пример select-all с данными Spring:
personRepository.findAll().forEach(person -> { // do something with the extracted person });
5.2. Весенние данные/JDBC
Spring Data JDBC-это ограниченная реализация семейства Spring Data, основная цель которой-обеспечить простой доступ к реляционным базам данных .
По этой причине он не предоставляет таких функций, как кэширование, грязное отслеживание, ленивая загрузка и многие другие функции JPA.
На этот раз нам нужна зависимость Maven spring-data-jdbc :
org.springframework.data spring-data-jdbc 1.1.4.RELEASE
Конфигурация легче по сравнению с той, которую мы использовали в предыдущем разделе для 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 будет непосредственно заботиться о сопоставлении сущностей, а не о спящем режиме:
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. Аналогично, то же самое относится и к примеру select-all.
6. Заключение
В этом уроке мы рассмотрели несколько различных способов подключения к базе данных MySQL из Java . Мы начали с основного соединения JDBC. Затем мы рассмотрели обычно используемые ORM, такие как Hibernate, Mybatis и Apache Cayenne. Наконец, мы взглянули на Spring Data JPA и Spring Data JDBC.
Использование API JDBC или Hibernate означает больше шаблонного кода. Использование надежных фреймворков, таких как Spring Data или Mybatis, требует большей конфигурации, но дает значительное преимущество, поскольку они предоставляют реализации по умолчанию и такие функции, как кэширование и отложенная загрузка.