読者です 読者をやめる 読者になる 読者になる

liguofeng29’s blog

個人勉強用ブログだっす。

Hibernate - Set属性マッピング

Setを持つ永続化クラスの保存サンプル。

キーのAnnotaion

  • @ElementCollection
  • @ColletionTable
  • @Column
  • @OrderColumn

※ Listとは異なるのは、Setは順序がなく重複を許さないため、@OrderColumnは不要である!
※ SetのIFのみ使え、実装は使えない。

1. hibernate.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.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 接続情報 -->
        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">Int198429#</property>
        <!-- 各種設定 -->
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.min_size">1</property>
        <property name="hibernate.c3p0.timeout">5000</property>
        <!-- プール内最大Statement -->
        <property name="hibernate.c3p0.max_statements">100</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <property name="hibernate.c3p0.acquire_increment">2</property>

        <property name="hibernate.c3p0.validate">true</property>
        <!-- DB方言解消 -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <!-- 必要に応じて表生成 -->
        <property name="hbm2ddl.auto">update</property>
        <!-- 生成SQL表示 -->
        <property name="show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- マッピングテーブル -->
        <!--  mapping class="entity.Item"/ -->
        <!-- mapping class="set.Person"/>  -->
        <mapping class="map.Person"/>
    </session-factory>
</hibernate-configuration>

2. Person.java

package set;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;

@Entity
@Table(name = "person_inf")
public class Person {
    @Id
    @Column(name = "perosn_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private int age;

    // 集合属性
    @ElementCollection(targetClass = String.class)
    // マッピング表
    @CollectionTable(name = "school_inf", joinColumns = @JoinColumn(name = "person_id", nullable = false))
    // マッピング列
    @Column(name = "school_name", nullable=false)
    // ここはSetのみ使える
    private Set<String> schools = new HashSet<String>();

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

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

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

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

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

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

    public Set<String> getSchools() {
        return schools;
    }

    public void setSchools(Set<String> schools) {
        this.schools = schools;
    }
}

3. HibernateUtil.java

package set;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {
    public static final SessionFactory sessionFactory;

    static {
        try {
            Configuration cfg = new Configuration().configure();
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(cfg.getProperties()).build();
            sessionFactory = cfg.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    public static final ThreadLocal<Session> session = new ThreadLocal<Session>();

    public static Session currentSession() throws HibernateException {
        Session s = session.get();
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
    }

    public static void closeSession() throws HibernateException {
        Session s = session.get();
        if (s != null)
            s.close();
        session.set(null);
    }
}

4. PersonManager.java

package set;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class PersonManager {
    public static void main(String[] args) {
        PersonManager mgr = new PersonManager();
        mgr.createAndStorePerson();
        HibernateUtil.sessionFactory.close();
    }

    // Person生成&保存
    private void createAndStorePerson() {
        // セッション
        Session session = HibernateUtil.currentSession();
        // TX
        Transaction tx = session.beginTransaction();
        // Person生成
        Person person = new Person();
        // 属性
        person.setAge(18);
        person.setName("佐藤君");
        // 属性追加
        person.getSchools().add("小学校");
        person.getSchools().add("中学校");
        session.save(person);
        tx.commit();
        HibernateUtil.closeSession();
    }
}

実行結果

1. 表が自動生成される。
(この設定によってだ。 update

mysql> desc person_inf;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| perosn_id | int(11)      | NO   | PRI | NULL    | auto_increment |
| age       | int(11)      | NO   |     | NULL    |                |
| name      | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> desc school_inf;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| person_id   | int(11)      | NO   | PRI | NULL    |       |
| school_name | varchar(255) | NO   | PRI | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

2. データが二つのテーブルに挿入される。

mysql> select * from person_inf;
+-----------+-----+-----------+
| perosn_id | age | name      |
+-----------+-----+-----------+
|         1 |  18 | 佐藤君    |
+-----------+-----+-----------+
1 row in set (0.00 sec)

mysql> select * from school_inf;
+-----------+-------------+
| person_id | school_name |
+-----------+-------------+
|         1 | 中学校      |
|         1 | 小学校      |
+-----------+-------------+
2 rows in set (0.00 sec)