0
1

More than 3 years have passed since last update.

JavaにおけるDB操作(その2)

Last updated at Posted at 2021-03-20

この記事の続き。
長くなるので分けました。Hibernate(JPA)による操作。とりあえずは動いたがいまいち構成や依存関係がわからない。

事前知識(段取り)

Hibernateを利用する場合、おおよそ下記のものを作ることになるらしい。
Javaの世界は不慣れなので表現とかが間違ってるかもしれない。

  • hibernate.cfg.xml(DBの接続情報やクラスのマッピング等を指定)
  • Modelクラス(DBテーブルと対応するクラス)
  • SessionFactory(Config)クラス(xmlから設定を読み込んで利用できる状態にする?っぽい)
  • 実行ファイル(App.java)

準備

テンプレート生成

まずはテンプレートの生成。quickstartで特に問題ない。

mvn archetype:generate \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=RELEASE \
-DinteractiveMode=false \
-DgroupId=com.hoge \
-DartifactId=hibernate-test
cd hibernate-test

pom.xmlの編集

まずは依存ライブラリの指定。hibernateとmysqlを指定。
最新版についてはこちらで検索。

以下は抜粋になります。dependenciesに追加します。

pom.xml(抜粋)

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

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

実装

Hibernate.cfg.xmlの設定

クラスパスにhibernate.cfg.xmlを作成し、設定する。
ここではresoucesフォルダに作成する。

mkdir -p src/main/resources
touch src/main/resources/hibernate.cfg.xml

記述する。
ここで、DBの接続情報、テーブルの生成条件(hbm2ddl)、マッピングするクラスなどを指定する。

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>

        <property name="connection.url">jdbc:mysql://localhost:3306/testdb</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 'show_sql' set true to check sql statements on console else set to false -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <!-- 新規に作る場合はcreate, そうでない場合はupdate -->
        <property name="hbm2ddl.auto">update</property>

        <!-- JDBC connection pool -->
        <property name="connection.pool_size">5</property>
        <property name="current_session_context_class">thread</property>

        <!-- マップするモデルを記述 -->
        <mapping class="com.hoge.User" />

    </session-factory>
</hibernate-configuration>

Model(Entity)

id,name,ageの3つのプロパティしか持たないが、getterやsetterが必要なので冗長。lombokってのを使うと省略できるらしいが、とりあえず書く。アノテーションでテーブル生成、マッピングの際の条件を表現するみたい。

src/main/java/com/hoge/User.java
package com.hoge;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Column;

@Entity(name = "User")
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //AUTOだと既存テーブルだとIDがかぶる
    @Column(name = "id")
    private int id;

    @Column(name = "name", length = 32, nullable = true)
    private String name;

    @Column(name = "age")
    private int age;

    // getter, setter

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return this.age;
    }

    public void setAage(int age) {
        this.age = age;
    }

}

SessionFactory(Config)

SessionFactoryを戻すクラスを実装。読み込んだconfig情報をベースにsessionを生成し戻すみたい。
C#のコンテクストて感じかな?

src/main/java/com/hoge/UserSessionFactory.java
package com.hoge;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class UserSessionFactory {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable e) {
            System.err.println("build SeesionFactory failed :" + e);
            throw new ExceptionInInitializerError(e);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void close() {
        // Close all cached and active connection pools
        getSessionFactory().close();
    }
}

実行ファイル

実行ファイル内でいろいろ利用。

src/main/java/com/hoge/App.java
package com.hoge;

import java.util.List;
import org.hibernate.Session;
import org.hibernate.query.Query;

public class App {
    public static void main(String[] args) {
        // session
        Session session = UserSessionFactory.getSessionFactory().openSession();

        // insert
        session.beginTransaction();
        User user = new User();
        user.setName("Bar");
        user.setAage(11);
        session.save(user);
        session.getTransaction().commit();

        // select
        Query<User> query = session.createQuery("From User", User.class);
        List<User> results = query.list();
        System.out.println("number of users:" + results.size());

        for (User u : results) {
            System.out.println("User:" + u + " " + u.getName());
        }

    }
}

実行

vscodeのjava extensionの実行を利用しているが、下記ので実行可能。

mvn -q compile exec:java -Dexec.mainClass=com.hoge.App

実行するたびにユーザーが増えます。

User:com.hoge.User@60c97466 hoge
User:com.hoge.User@1e0e9702 foo
User:com.hoge.User@50b06f2c Bar
User:com.hoge.User@1f5b2c0c Bar
User:com.hoge.User@57a06b99 Bar
User:com.hoge.User@30bd1fba Bar

うーん。まあ雰囲気はわかったかな。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1