DTOへ直接入れちゃえ
- one-to-many
- many-to-one
とか面倒なので、HQLで直接DTOへ入れてしまおうと思います。
下記の3つのテーブルを結合したものをEmployeeDetail(DTO)へマッピングしたいと思います。
- テーブル
社員 create table EMPLOYEE ( employeeid integer generated by default as identity (start with 1), name varchar(255), departmentid integer, branchid integer ); 部署 create table DEPARTMENT ( departmentid integer generated by default as identity (start with 1), name varchar(255) ); 支店 create table BRANCH ( branchid integer generated by default as identity (start with 1), name varchar(255) );
- Employee.java
package myproject.model; import java.io.Serializable; /** * 社員 */ public class Employee implements Serializable { private int employeeid; private String name; private int departmentid; private int branchid; public Employee(){}; public Employee(String name,int departmentid,int branchid){ this.name = name; this.departmentid = departmentid; this.branchid = branchid; } }
- Employee.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="myproject.model" auto-import="false"> <class name="Employee" table="EMPLOYEE" dynamic-insert="true" dynamic-update="true"> <id name="employeeid" type="int" access="field"> <generator class="native"/> </id> <property name="name" type="java.lang.String" access="field"/> <property name="departmentid" type="int" access="field"/> <property name="branchid" type="int" access="field"/> </class> </hibernate-mapping>
- Department.java
package myproject.model; import java.io.Serializable; /** * 部署 */ public class Department implements Serializable { private int departmentid; private String name; public Department(){}; public Department(String name){ this.name = name; } }
- Department.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="myproject.model" auto-import="false"> <class name="Department" table="DEPARTMENT" dynamic-insert="true" dynamic-update="true"> <id name="departmentid" type="int" access="field"> <generator class="native"/> </id> <property name="name" type="java.lang.String" access="field"/> </class> </hibernate-mapping>
- Branch.java
package myproject.model; import java.io.Serializable; /** * 支店 */ public class Branch implements Serializable { private int branchid; private String name; public Branch(){}; public Branch(String name){ this.name = name; } }
- Branch.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="myproject.model" auto-import="false"> <class name="Branch" table="BRANCH" dynamic-insert="true" dynamic-update="true"> <id name="branchid" type="int" access="field"> <generator class="native"/> </id> <property name="name" type="java.lang.String" access="field"/> </class> </hibernate-mapping>
- EmployeeDetail.java
package myproject.model; import java.io.Serializable; /** * 社員詳細 */ public class EmployeeDetail implements Serializable { private int employeeid; private String name; private String departmentName; private String branchName; public EmployeeDetail(int employeeid, String name, String departmentName, String branchName) { this.employeeid = employeeid; this.name = name; this.departmentName = departmentName; this.branchName = branchName; } public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("社員ID["); sb.append(this.employeeid); sb.append("] 名前["); sb.append(this.name); sb.append("] 部署["); sb.append(this.departmentName); sb.append("] 支店["); sb.append(this.branchName); sb.append("]"); return sb.toString(); } }
- DtoTest.java
package myproject; import java.util.Iterator; import java.util.List; import myproject.model.Branch; import myproject.model.Department; import myproject.model.Employee; import myproject.model.EmployeeDetail; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.Transaction; import net.sf.hibernate.cfg.Configuration; /** * DTO詰め替えテスト */ public class DtoTest { public static void main(String[] args) { try { Configuration config = new Configuration(); config.addClass(Employee.class).addClass(Department.class) .addClass(Branch.class); SessionFactory sessionFactory = config.buildSessionFactory(); Session session = null; Transaction tx = null; try { session = sessionFactory.openSession(); tx = session.beginTransaction(); session.save(new Department("開発")); session.save(new Department("研究")); session.save(new Department("営業")); session.save(new Branch("大阪支店")); session.save(new Branch("東京支店")); session.save(new Branch("アメリカ支店")); session.save(new Employee("ジミー大西", 1, 1)); session.save(new Employee("曙 太郎", 2, 1)); session.save(new Employee("浜崎 あゆみ", 3, 1)); session.save(new Employee("劇団ひとり", 1, 1)); session.save(new Employee("木村 拓哉", 1, 2)); session.save(new Employee("山口 智子", 3, 2)); session.save(new Employee("平井 賢", 3, 2)); session.save(new Employee("えなりかずき", 3, 2)); session.save(new Employee("ウィルスミス", 2, 3)); session.save(new Employee("トムクルーズ", 2, 3)); tx.commit(); StringBuffer hql = new StringBuffer(); hql.append("select"); hql.append(" new myproject.model.EmployeeDetail("); hql.append("emp.employeeid"); hql.append(",emp.name"); hql.append(",dep.name"); hql.append(",bra.name)"); hql.append(" from myproject.model.Employee emp"); hql.append(",myproject.model.Department dep"); hql.append(",myproject.model.Branch bra"); hql.append(" where emp.departmentid = dep.departmentid"); hql.append(" and emp.branchid = bra.branchid"); hql.append(" order by emp.employeeid"); List list = session.find(hql.toString()); for (Iterator ite = list.iterator(); ite.hasNext();) { EmployeeDetail detail = (EmployeeDetail) ite.next(); System.out.println(detail.toString()); } } catch (Exception e) { e.printStackTrace(); if (tx != null) { tx.rollback(); } } finally { sessionFactory.close(); } } catch (Exception e) { e.printStackTrace(); } } }
- 実行結果
社員ID[1] 名前[ジミー大西] 部署[開発] 支店[大阪支店] 社員ID[2] 名前[曙 太郎] 部署[研究] 支店[大阪支店] 社員ID[3] 名前[浜崎 あゆみ] 部署[営業] 支店[大阪支店] 社員ID[4] 名前[劇団ひとり] 部署[開発] 支店[大阪支店] 社員ID[5] 名前[木村 拓哉] 部署[開発] 支店[東京支店] 社員ID[6] 名前[山口 智子] 部署[営業] 支店[東京支店] 社員ID[7] 名前[平井 賢] 部署[営業] 支店[東京支店] 社員ID[8] 名前[えなりかずき] 部署[営業] 支店[東京支店] 社員ID[9] 名前[ウィルスミス] 部署[研究] 支店[アメリカ支店] 社員ID[10] 名前[トムクルーズ] 部署[研究] 支店[アメリカ支店]
ばっちり。
いちいちone-to-manyとかするよりこっちの方が使いやすい。
このままViewで使えるし。
マッピングファイルもすっきりしてるし。
それに余計なものを取ってこないから、メモリの節約にもなるはず。
でもこれって正しい使い方なのかな?