JavaをMySQLデータベースに接続する
1. 概要
JavaからMySQLデータベースに接続する方法はたくさんあります。このチュートリアルでは、これを実現する方法を確認するためにいくつかのオプションを検討します。
まず、JDBCとHibernateを使用した最も人気のあるオプションを見ていきます。
次に、MyBatis、Apache Cayenne、SpringDataなどの外部ライブラリについても説明します。 その過程で、いくつかの実用的な例を提供します。
2. 前提条件
MySQLサーバーがすでにローカルホスト(デフォルトポート3306)にインストールされて実行されており、次のpersonテーブルを持つテストスキーマがあると想定します。
CREATE TABLE person
(
ID INT,
FIRST_NAME VARCHAR(100),
LAST_NAME VARCHAR(100)
);
mysql-connector- java アーティファクトも必要です。これは、いつものように MavenCentralから入手できます。
<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接続の例
データベースに接続し、try-with-multiple-resourcesを介して単純なselect-allを実行する方法を見てみましょう。
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を使用した接続
より一般的には、オブジェクトリレーショナルマッピング(ORM)フレームワークを使用してMySQLデータベースに接続します。 それでは、これらのフレームワークのより一般的なものを使用したいくつかの接続例を見てみましょう。
4.1. ネイティブHibernateAPI
このセクションでは、Hibernateを使用してデータベースへのJDBC接続を管理する方法を説明します。
まず、 hibernate-coreMaven依存関係を追加する必要があります。
<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
}
もう1つの重要な側面は、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接続の作成とプールを担当するクラスです。
通常、これはアプリケーションに対して1回だけ設定する必要があります。
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();
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
MyBatisは2010年に導入され、その強みとしてシンプルさを備えたSQLマッパーフレームワークです。 別のチュートリアルでは、MyBatisをSpringおよびSpringBootと統合する方法について説明しました。 ここでは、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 オブジェクトを使用できます。これは通常、アプリケーションが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
Apache Cayenne は永続性フレームワークであり、最初のリリースは2002年にさかのぼります。 詳細については、 ApacheCayenneの概要を読むことをお勧めします。
いつものように、 cayenne-serverMaven依存関係を追加しましょう。
<dependency>
<groupId>org.apache.cayenne</groupId>
<artifactId>cayenne-server</artifactId>
<version>4.0.2</version>
</dependency>
<?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. SpringDataを使用した接続
Spring Data は、データアクセス用のSpringベースのプログラミングモデルです。 技術的には、Spring Dataは、特定のデータベースに固有の多くのサブプロジェクトを含む包括的なプロジェクトです。
これらのプロジェクトのうち2つを使用してMySQLデータベースに接続する方法を見てみましょう。
5.1. 春のデータ/JPA
Spring Data JPAは、ボイラープレートコードの削減に役立つ堅牢なフレームワークであり、いくつかの事前定義されたリポジトリインターフェイスの1つを介して基本的なCRUD操作を実装するためのメカニズムを提供します。 これに加えて、それは他の多くの便利な機能を持っています。
詳細については、 Spring DataJPAの概要を確認してください。
spring-data-jpa アーティファクトは、 MavenCentralにあります。
<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> {
}
最後に、SpringDataを使用したselect-allの例を見てみましょう。
personRepository.findAll().forEach(person -> {
// do something with the extracted person
});
5.2. Spring Data / 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>
構成は、SpringDataJPAの前のセクションで使用したものと比較して軽量です。
@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 DataJDBCが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インターフェースを使用することもできます。 したがって、宣言は、上記のSpringDataJPAの例で記述したものと同じになります。 同様に、同じことがselect-allの例にも当てはまります。
6. 結論
このチュートリアルでは、JavaからMySQLデータベースに接続するいくつかの異なる方法を見てきました。 基本的なJDBC接続から始めました。 次に、Hibernate、Mybatis、ApacheCayenneなどの一般的に使用されるORMを調べました。 最後に、SpringDataJPAとSpringDataJDBCについて見ていきました。
JDBCまたはHibernateAPIを使用すると、ボイラープレートコードが増えることになります。 Spring DataやMybatisなどの堅牢なフレームワークを使用するには、より多くの構成が必要ですが、キャッシュや遅延読み込みなどのデフォルトの実装と機能を提供するため、大きな利点があります。