J2EE と EJB

EntityManager と EJB QL
EJB 3.0 コース
第8回
2006年8月5日
1
ここでの目標

Entity Manager の使いかたと EJB QL につ
いて理解する。
2
EntityManagerの利用
3
EntityManager と
@PersistenceContext
@PersistenceContext(……)
private EntityManager em;


EntityManager は、データの永続管理を受け持つオブジェ
クト。データベースと接続して、さまざまな処理を行う。
@PersistenceContext は、Dependency Injection (依存性
注入)を行うためのアノテーション。EntityManager は、コン
テナによって依存性注入される。
4
EntityBeanのライフサイクル (1)


EntityBeanは、データベースのテーブルとの関係
において、ライフサイクルを持つ
Persistence Identity



EntityBeanのインスタンスを識別するためのもの
データベースのテーブル中の主キーと対応する
@Idアノテーションで修飾されたプロパティ
5
EntityBeanのライフサイクル (2)
Persistence
Identity を
持つかどうか
Persistence Context
との結びつき
new
持たない
結びついていない
managed
持つ
結びついている
detached
持つ
removed
持つ
結びついていない
(以前は結びついていた)
結びついている
(DBから削除予定)
6
EntityBeanのライフサイクル (3)





新しくEntityBeanが生成された → new
EntityManager#persist を実行 → managed
Persistence Context との関係性がなくなった (=
データベースとの関係性がなくなった) →
detached
EntityManager#merge(detachedなEntityBean)
→ managed
EntityManager#remove を実行 → removed
7
EntityManager#find
public Employee findEmployeeByEmpNo(int empNo) {
return ((Employee) em.find("Employee",empNo));
}

EntityManager の find メソッドは、データベースか
らempNo という主キーで指定したデータを検索し、
検索結果として Employee オブジェクトを返す。
8
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 に
9
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 にする
10
データベースの更新 (1)
// EmployeeClient.java より
Employee emp3 =
ef.findEmployeeByEmpNo(empNo);
emp3.setSal(100000);


クライアントプログラムでEmployeeの内容を変化さ
せても、データベースには反映されない。
SesionFacadeから渡されているemp3は、
detached になっている。
11
データベースの更新 (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);
}
12
データベースの更新 (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);
}
13
Java Persistence Query
Language
14
Java Persistence Query
Language とは何か
Java Persistence API でデータベースを操
作するためのクエリー言語
 オブジェクトをそのまま利用できる
 データベースに依存しないかたちでクエリー
を記述できる
 旧来の “EJB QL” を拡張したもの

15
例1
// Employee のコレクションを返す
public Collection<Employee> findAllEmployees() {
Collection<Employee> employees =
em.createQuery(
"SELECT employee FROM Employee employee”
).getResultList();
return employees;
}
16
例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;
}
17
例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;
}
18
例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();
}
19