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)
);


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>


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>

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(); 
  }
}

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で使えるし。
マッピングファイルもすっきりしてるし。
それに余計なものを取ってこないから、メモリの節約にもなるはず。
でもこれって正しい使い方なのかな?