Hibernate - Map属性マッピング
Mapを持つ永続化クラスの保存サンプル。
キーのAnnotaion
- @ElementCollection
- @ColletionTable
- @Column
- @MapKeyColumn
<?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">xxxx</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="map.Person"/> </session-factory> </hibernate-configuration>
2. Person.java
package map; import java.util.HashMap; import java.util.Map; 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.MapKeyClass; import javax.persistence.MapKeyColumn; import javax.persistence.Table; @Entity @Table(name = "person_inf") public class Person { @Id @Column(name="person_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String name; private int age; // 集合属性 @ElementCollection(targetClass=Float.class) // マッピング表 @CollectionTable(name="score_inf", // ヨクカィア朎鉸ェscore_inf joinColumns=@JoinColumn(name="person_id" , nullable=false)) @MapKeyColumn(name="subject_name") // key @MapKeyClass(String.class) // value @Column(name="mark") private Map<String , Float> scores = new HashMap<>(); 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 Map<String, Float> getScores() { return scores; } public void setScores(Map<String, Float> scores) { this.scores = scores; } }
3. HibernateUtil.java
package map; 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 map; 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.getScores().put("数学", 90F); person.getScores().put("英語", 80F); session.save(person); tx.commit(); HibernateUtil.closeSession(); } }
実行結果
1. 表が自動生成される。
(この設定によってだ。
mysql> desc person_inf; +-----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+----------------+ | person_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 score_inf; +--------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+-------+ | person_id | int(11) | NO | PRI | NULL | | | mark | float | YES | | NULL | | | subject_name | varchar(255) | NO | PRI | NULL | | +--------------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec)
2. データが二つのテーブルに挿入される。
mysql> select * from person_inf; +-----------+-----+-----------+ | person_id | age | name | +-----------+-----+-----------+ | 1 | 18 | 佐藤君 | +-----------+-----+-----------+ 1 row in set (0.00 sec) mysql> select * from score_inf; +-----------+------+--------------+ | person_id | mark | subject_name | +-----------+------+--------------+ | 1 | 90 | 数学 | | 1 | 80 | 英語 | +-----------+------+--------------+ 2 rows in set (0.00 sec)