S2JDBCのテーブル結合 1対多

多対一関連定義には、@ManyToOne

@Entity
public class Emp {
    @ManyToOne
    public Dept dept;
}



一対多関連定義には、@OneToMany
一対多の関連の型は、 List<エンティティ型>

@Entity
public class Dept {
    @OneToMany(mappedBy = "dept")
    public List<Emp> emp;
}

【参考サイト】
Seasar2 - S2JDBC - エンティティ

S2JDBCで外部SQL

S2JDBCで外部SQLを実行する。

//ロジッククラス
public class EmpService extends AbstractService<Emp> {
    public List<Emp> outSqlSelectAll(){
        return selectBySqlFile(Emp.class, "selectAll.sql").getResultList();
    }
}
//ロジッククラスのスーパークラス
public abstract class AbstractService<ENTITY> extends S2AbstractService<ENTITY> {
 //オーバーライド
  protected void setEntityClass(Class<ENTITY> entityClass) {
    this.entityClass = entityClass;
    sqlFilePathPrefix = "sql/";
  }
}



SQLファイルをresource/sqlフォルダを作成し、
sqlフォルダにファイル"selectAll.sql"を作成する。

select * from emp

パラメータ有(1個)

  public List<Emp> outSqlSelectWhere(){
   return selectBySqlFile(Emp.class,"selectWhereSal.sql",2000).getResultList();
  }

SQL

select * from emp 
where sal > /*salMin*/1000

パラメータ有(複数)

SQLファイルのパラメータが複数の場合は、
selectBySqlFile() の3番目の引数をJavaBeansまたは
Map にして、 パラメータの名前と
JavaBeansのプロパティ名または Map のキーを一致させます。

  public List<Emp> outSqlSelectWhereMult(){
    Map map = new HashMap();
    map.put("salMin", 2000);
    map.put("deptId", 2);
    return selectBySqlFile(Emp.class, "selectWhereMult.sql",map).getResultList();
  }

SQL

select * from emp 
where sal > /*salMin*/1000
and dept_id = /*deptId*/1


【参考サイト】
Seasar2 - S2JDBC - JdbcManager - SQLファイルによる操作
http://bw2hr.cocolog-nifty.com/blog/2009/01/s2jdbcsql-8af1.html

SAStrutsのUnitテスト

アクションクラスのUnitテスト

Tomcatを起動した状態でUnitテストを実行する。

public class EmpActionTest extends S2TestCase{
	
  protected EmpService empService;

  @Before
  public void setUp() throws Exception {
    include("app.dicon");
    super.setUp();
  }

  @Test
  public void testIndex() {
    EmpAction action = new EmpAction();
    //メンバ設定
    action.empService = empService;
    String rtn = action.index();
    assertNotNull("遷移先がnull.", rtn);
    assertEquals("list.jspへ遷移されない","list.jsp", rtn);
    assertFalse(action.empItems.size() == 0);
  }
}



dao(serviceクラス)のUnitテスト

直接DBから取得した情報と、S2JDBCで取得した情報を比較

/**
 * EmpServiceのUnitテストクラス
 */
public class EmpServiceTest extends S2TestCase{

  protected EmpService empService;
  protected Connection con;
	
  /**
   * 初期設定
   */
  @Before
  public void setUp() throws Exception {
    include("app.dicon");
    super.setUp();
    setDb();
  }	
  /**
   * 直接DB接続
   * @throws Exception
   */
  private void setDb() throws Exception{
    Class.forName("com.mysql.jdbc.Driver");
    String url = "jdbc:mysql://localhost:3306/test";
    con = DriverManager.getConnection(url,"root","root");
  }
	
  /**
   * 直接DBより取得
   * @param id
   * @return
   */
  private Emp getEmpFromDb(int id){
    Emp emp = null;//復帰値
    String sql ="SELECT * FROM EMP WHERE ID = ?";
    PreparedStatement ps;
    try {
      ps = con.prepareStatement(sql);
      ps.setInt(1, id);
      ResultSet rs = ps.executeQuery();
      while(rs.next()){
        emp = new Emp();
	emp.id = rs.getInt("ID");
	emp.empNo = rs.getInt("EMP_NO");
	emp.empName = rs.getString("EMP_NAME");
	emp.mgrId = rs.getInt("MGR_ID");
	emp.hiredate = rs.getDate("HIREDATE");
	emp.sal = rs.getBigDecimal("SAL");
	emp.deptId = rs.getInt("DEPT_ID");
	emp.versionNo = rs.getInt("VERSION_NO");
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
    return emp;
  }

  /**
   * FindByIdメソッドUnitテスト
   */
  @Test
  public void testFindById() {
    Emp result = empService.findById(0);
    assertNull("NULLでない。",result);
		
    Emp tempEmp = getEmpFromDb(2);
    result = empService.findById(2);
    assertNotNull("empEntityがnull",result);
    assertEquals("idが違う", Integer.valueOf(2), result.id);
    assertEquals("idの不一致", tempEmp.id, result.id);
    assertEquals("empNoの不一致", tempEmp.empNo, result.empNo);
    assertEquals("empNameの不一致", tempEmp.empName, result.empName);
    assertEquals("mgrIdの不一致", tempEmp.mgrId, result.mgrId);
    assertEquals("hiredateの不一致", tempEmp.hiredate, result.hiredate);
    assertEquals("salの不一致", tempEmp.sal, result.sal);
    assertEquals("deptIdの不一致", tempEmp.deptId, result.deptId);
    assertEquals("versionNoの不一致", tempEmp.versionNo, result.versionNo);
  }
}
/**
 * EMPのServiceクラス
 */
public class EmpService extends AbstractService<Emp> {
    public Emp findById(Integer id) {
        return select().id(id).getSingleResult();
    }
}



INSRET処理のUnitテスト

INSRET後のテーブルデータをExcelファイルより読み込み、
INSRET後のSQL文の実行結果との比較

  /**
   * 登録メソッドUnitテスト
   */
  @Test
  public void testInsertTx() {
    //新規登録テスト
    Emp emp = new Emp();
    emp.empNo = 7952;
    emp.empName = "DAM";
    emp.mgrId = 6;
    try {
      emp.hiredate = DateFormat.getDateInstance().parse("1981/05/14");
    } catch (ParseException e) {
      e.printStackTrace();
    }
    emp.sal = new BigDecimal(2100.00);
    emp.deptId = 1;
    emp.versionNo = 1;
    int cnt = empService.insert(emp);
    //登録件数チェック
    assertEquals(1, cnt);
    //①SQL文実行結果をDataSetオブジェクトに設定し、登録後のDB内容と比較する。
    DataTable empDt = readDbBySql("SELECT * FROM EMP", "EMP");
    //②予想結果のDB内容をExcelファイルより読み込む
    DataSet  empXls = readXls("emp.xls");
    //①と②の内容を比較する。
    assertEquals(empXls.getTable("EMP"), empDt);
  }

Excelファイルは、テストクラスと同じパッケージに配置。
※Unitテストに〜〜Tx()とすると、
テストメソッドの直前にトランザクションを開始し、
テストメソッドの直後にトランザクションロールバックするようになる。
(AutoIncrementは、増加する。)




【参考サイト】
S2Unit
http://wiki.paulownia.jp/java/sastruts
SeasarV2によるテスト機能:Seaser Projectの全貌を探る(4) - @IT