EntityManager と EJB QL EJB 3.0 コース 第8回 2006年8月5日
ここでの目標 Entity Manager の使いかたと EJB QL について理解する。
EntityManagerの利用
EntityManager と @PersistenceContext private EntityManager em; EntityManager は、データの永続管理を受け持つオブジェクト。データベースと接続して、さまざまな処理を行う。 @PersistenceContext は、Dependency Injection (依存性注入)を行うためのアノテーション。EntityManager は、コンテナによって依存性注入される。
EntityBeanのライフサイクル (1) Persistence Identity EntityBeanのインスタンスを識別するためのもの データベースのテーブル中の主キーと対応する @Idアノテーションで修飾されたプロパティ
EntityBeanのライフサイクル (2) Persistence Identity を 持つかどうか Persistence Context との結びつき new 持たない 結びついていない managed 持つ 結びついている detached (以前は結びついていた) removed (DBから削除予定)
EntityBeanのライフサイクル (3) 新しくEntityBeanが生成された → new EntityManager#persist を実行 → managed Persistence Context との関係性がなくなった (= データベースとの関係性がなくなった) → detached EntityManager#merge(detachedなEntityBean) → managed EntityManager#remove を実行 → removed
EntityManager#find public Employee findEmployeeByEmpNo(int empNo) { return ((Employee) em.find("Employee",empNo)); } EntityManager の find メソッドは、データベースからempNo という主キーで指定したデータを検索し、検索結果として Employee オブジェクトを返す。
EntityManager#persist public void addEmployee(int empNo, String eName, double sal) { Employee emp = new Employee(); emp.setEmpNo(empNo); emp.setEname(eName); emp.setSal(sal); em.persist(emp); } EntityManager の persist メソッドで、Entity Bean を永続化している。つまり、データをデータベースで管理するようにしている。 new から managed に
EntityManager#remove @Stateless public class EmployeeDemoSessionEJB implements EmployeeDemoSession { public void removeEmployee(Integer employeeId) { Employee employee = (Employee)em.find("Employee", employeeId); em.remove(employee); } EntityManager の remove メソッドで、データベースで管理されているオブジェクトを削除できる。 removed にする
データベースの更新 (1) // EmployeeClient.java より Employee emp3 = ef.findEmployeeByEmpNo(empNo); emp3.setSal(100000); クライアントプログラムでEmployeeの内容を変化させても、データベースには反映されない。 SesionFacadeから渡されているemp3は、detached になっている。
データベースの更新 (2) このようにしてみる // EmployeeClient.java より Employee emp3 = ef.findEmployeeByEmpNo(empNo); emp3.setSal(100000); ef.updateEmployee(emp3); // EmployeeFacadeBean.java より // detouched な EntityBean が managed に public void updateEmployee(Employee emp) { em.merge(emp); }
データベースの更新 (3) 別解 // EmployeeClient.java ef.setSal(1, 50.0); // EmployeeFacadeBean.java // Facadeの中で find したものを操作すればOK public void setSal(int empNo, Double sal) { emp = (Employee)em.find(Employee.class, empNo); emp.setSal(sal); }
Java Persistence Query Language
Java Persistence Query Language とは何か Java Persistence API でデータベースを操作するためのクエリー言語 オブジェクトをそのまま利用できる データベースに依存しないかたちでクエリーを記述できる 旧来の “EJB QL” を拡張したもの
例1 // Employee のコレクションを返す public Collection<Employee> findAllEmployees() { Collection<Employee> employees = em.createQuery( "SELECT employee FROM Employee employee” ).getResultList(); return employees; }
例2 // パラメータの設定 public Collection<Employee> findEmployeesByLastName(String lastName) { Collection<Employee> employees = em.createQuery( "SELECT employee FROM Employee employee WHERE employee.lastName = :lastname") .setParameter("lastname", lastName) .getResultList(); return employees; }
例3 // UPDATEやDELETEも使える public int changeCityName(String oldName, String newName) { int result = em.createQuery( "UPDATE address SET address.city = :newName WHERE address.city = :oldName") .setParameter("newName", newName) .setParameter("oldName", oldName) .executeUpdate(); return result; }
例4 // クエリーをあらかじめ用意 @NamedQuery( name="findProjectByName", queryString="SELECT project FROM Project project WHERE project.name = :name" ) public class ... { Project proj = (Project)em.createNamedQuery("findProjectByName") .setParameter("name", name) .getSingleResult(); }