JPAã®åé¡ç¹
JPAã«ã¯é常ã«æå¾ ãã¦ãã人ãå¤ãã§ããããç§ããã®ä¸äººã§ããå®éã«ããã¸ã§ã¯ãã§ä½¿ã£ã¦ã¿ã¦ãè¦ãã¦ããåé¡ç¹ãæ¸ãã¦ã¿ã¾ããJPAã®å®è£ ã¨ãã¦ã¯ï½¤Hibernate3.2ã使ã£ã¦ãã¾ãã
- å¦ç¿ã³ã¹ããé«ãã
- JPAã®å ¨æ©è½ã®ãã¡ï½¤ããã¸ã§ã¯ãã§ä½¿ããã®ã«çµãè¾¼ãã§æè²ããã¨ã3æ¥ç¨åº¦ã§æãããã¨ãã§ããã®ã§ãã、ãããã使ããããã«ãªãã«ã¯ï½¤2ã4é±éãããã¾ããããã¯ãHibernate in Actionã«ãæ¸ãã¦ããã®ã§ãããããã®ãªãã§ãããã
- ãã©ãã«ã·ã¥ã¼ãã£ã³ã°ãé£ããã
- å¤ãã®ããã¸ã§ã¯ãã§å®éã«ããã«ã®ã¯ããã§ãããããã¡ã®ããã¸ã§ã¯ãã§ã¯ï½¤Hibernateè·äººã§ããå°æãããããã«ããããããããããè¦å´ãã¾ãããHibernateè·äººã®ããªãããã¸ã§ã¯ãã§ä½¿ãã®ã¯å³ããã®ã§ã¯ãªããã¨æãã¾ãã
- SQLã®æ±ãã貧弱ã
- JPQLã¯ãSQLã®ããªã貧弱ãªãµãã»ãããªã®ã§ï½¤SQLã使ãå¿ è¦ãããå ´åãããããããã®ã§ãã、JPAã®SQLã®æ±ãã¯è²§å¼±ã§ããSQLã®çµæãåç¬ã®Entityã«ã¤ãã¦è¿ãå ´åã¯ããã®ã§ãã、è¤æ°ã®Entityãè¿ããã¨ããã¨Objectã®é åã«åã ã®Entityãã¤ãããã¦è¿ã£ã¦ããã®ã§ãEmployee emp = (Employee) obj[0];ã®ãããªæãã§ãã£ã¹ããã¦ä½¿ãã®ã§ããããã£ã¦ããã¾ãã ãããææªã¯ï½¤Entity以å¤ã«ãããã³ã°ããå ´åã§ï½¤ãªãã¨Objectã®é åã§è¿ã£ã¦ããã®ã§ããLong id = (Long) obj[0];String ename = (String) obj[1];ãªã£ã¦ããå¿ è¦ããããªãã¦ãè¶ ããã¾ããKuinaDaoã¯ãS2Daoã®ããã«SQLã®çµæãDTOã«ãããã³ã°ã§ããã®ã§ããã®ã±ã¼ã¹ã¯å¤§ä¸å¤«ãªã®ã§ããï½¤ç´ ã®JPAã使ãã¨ãã£ã¨å°ãã§ã¯ãªããã¨æãã¾ãã
- æ°è¦ã·ã¹ãã 以å¤ã§ä½¿ãã®ã¯é£ããã
- å®éã®éçºã§ã¯ï½¤æ¬å½ã«æ°è¦ã·ã¹ãã ã¨ãããã¨ã¯ãã¾ããªã、æ¢ã«ããã·ã¹ãã ãä½ãç´ãã±ã¼ã¹ãå¤ããã®ã§ãããã®ãããªå ´å、æ¢ã«ãã¼ãã«ãSQLã¯åå¨ããã®ã§ãã、ãããJPAãã¼ã¹ã«ç½®ãæããã®ã¯ï½¤å¤§å¤ã§ããç¹ã«SQLãJPQLã«å¤æ´ãããã¨ã¨ï½¤ã¬ã¬ã·ã¼ãªã·ã¹ãã ã§idã使ããã¦ããªãå ´åãªã©ãããªã大å¤ã
- ããã©ã¼ãã³ã¹ãã¥ã¼ãã³ã°ãå¾ããçºçããã
- JPAã使ãå ´åã¯ï½¤Entityéã®é¢é£ã¯lazyã«ããã®ãåºæ¬ã§ããããããã¨æåã«å°éã®ãã¼ã¿ã§éçºãã¦ããã¨ãã¯åé¡ãèµ·ãããªãã®ã§ãã、çµåãã¹ãã®ãã§ã¼ãºã«ãªã£ã¦æ¬çªã«è¿ããã¼ã¿ãæ±ãããã«ãªãã¨lazy loadingã«ããN+1 SELECTåé¡ãçºçã、ããã©ã¼ãã³ã¹ãå£åãã¾ããFetch Joinã§å¯¾å¿ã§ããã°ã¾ã 楽ãªã®ã§ãã、ããã¯è¡ããªãå ´å、SQLãæ¸ãå¿ è¦ããã、åã«æ¸ããSQLã®æ±ãã貧弱ãªåé¡ã«ã¶ã¡å½ããã¾ãã
- View層ã«ãããlazy loadingåé¡
- View層ã§Entityãç´æ¥æ±ãã¨ãView層ã§Entityã®é¢é£ããã©ãå¿ è¦ããã、ããã§lazy loading(SELECTæã®å®è¡)ãèµ·ããå¯è½æ§ãããã¾ããTransactionã¹ã³ã¼ããªEnityManagerã使ãå ´å、View層ã§ãã©ã³ã¶ã¯ã·ã§ã³ãå¶å¾¡ããå¿ è¦ãããã¾ããããã£ã¦ããã¾ããããããSeasar2ã®å ´åã¯ï½¤S2Dxoã使ã£ã¦ã¹ãã¼ãã«ãã®åé¡ã解決ã§ãã¾ãã
- ç«ã¡ä¸ãæã®åæåãé
ã
- ãã¹ãããã¨ãã«ï½¤JPAã®ç°å¢ããã¹ããã¨ã«åæåããã¨ãã¾ãã«é ããã£ã¦ããã¾ãããSeasar2ã§ã¯ãã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯å´ã§å¯¾å¿ãã¦ãã¾ãã、ããããã®ããªãã¨ãã¹ããããã®ã大å¤ã§ãã
- çç£æ§ãS2Daoããæªã
- æ¢åã®SQLãå©ç¨ã§ãããããªéçºã ã¨ï½¤å§åçã«S2Daoã®æ¹ããçç£æ§ãä¸ããã¾ããæ°è¦ã«éçºããå ´åã§ã、JPAã®æ¹ãè¤éãªãã、ãã©ãã«ã±ã¼ã¹ãå¤ãæå¤ã¨ã³ã¹ãããããã¾ããã¾ããæ¸ããªããã°ãããªãã³ã¼ãã®éãJPAã®æ¹ãå§åçã«å¤ããªãã¾ããKuinaDaoã使ãã°ï½¤æ¸ããªããã°ãããªãã³ã¼ãã®éã¯S2Dao並ã«å°ãªããªãã®ã§ãã、è¤éã ã¨ããåé¡ã¯è§£æ±ºã§ãã¾ããã
JPAã使ã£ã¦æã楽ãããã«ã¯ï½¤StatefulSessionBeanã¨ExtendedãªEntityManagerã使ããã¨ã§ããView層ã®lazy loadingã®åé¡ããªãã、detachãããEntityãmergeããå¿
è¦ããªãã、SessionBeanãçãã¦ããéã¯ï½¤ä¸åº¦ã¢ã¯ã»ã¹ããEntityã¯ãã£ãã·ã¥ããã¦ããã®ã§ï½¤ããã©ã¼ãã³ã¹ãåä¸ãã¾ããåé¡ç¹ã¯ï½¤ä¸åº¦ã¢ã¯ã»ã¹ããã¨ã³ãã£ãã£ããã£ãã·ã¥ãã¦ããã®ã§ï½¤ã¡ã¢ãªã大éã«æ¶è²»ãããã¨ã§ããç¾å¨ã®JPAã§ã¯ããã£ãã·ã¥ãå
¨é¨ã¯ãªã¢ããã¨ãã大éæãªã¡ã½ããããç¨æããã¦ããªãã®ã§å°ãè
ã§ããã¾ããStatefulSessionBeanããã¡ãã¨åé¤ãã¦ãããªãã¨ãã£ãã·ã¥ãããEntityã解æ¾ãããªãã¨è¨ãåé¡ãããã¾ããããã¯ãSeamã§ã¯ãStatefulSessionBeanã®ã©ã¤ããµã¤ã¯ã«ãèªåçã«ç®¡çããã®ã§ï½¤è§£æ±ºããã¦ããããã«æãã¾ãã、ã¦ã¼ã¶ãæå¾ã¾ã§å¦çãè¡ããã«ãéä¸ã§å¦çãæ¢ããå ´åã¯ï½¤StatefulSessionBeanãåé¤ãããã«æ®ã£ã¦ãã¾ãã®ã§ã¯ãªããã¨æãã¾ããSeamã«è©³ãã人、ééã£ã¦ãããæãã¦ãã ããã
çµè«ãæ¸ãã¨ãä»ã®JPAã¯ãããªãã®åé¡ãæ±ãã¦ãã¾ããç´ ã§ä½¿ãã®ã¯ãå§ããã¾ãããJPAã¯ãJPAã®ãã¨ãè¯ãç¥ã£ã¦ãããã¬ã¼ã ã¯ã¼ã¯ã¨çµã¿åããããã¨ããå§ããã¾ããä»ã®æç¹ã§ï½¤JPAã使ãã®ã«è¯ãã¨æããã¬ã¼ã ã¯ã¼ã¯ã¯ï½¤Seasar2ã®Easy Enterpriseãã¡ããªã¼ã¨Seamã§ããEasy Enterpriseãã¡ããªã¼ã¯ãSQLã®åé¡ãView層ã«ãããlazy loadingåé¡ã解決ãã¦ããã®ã§ãããæ大ã®åé¡ã¯ï½¤S2Hibernate-JPAã¨KuinaDaoãæ£å¼ãªãªã¼ã¹ããã¦ããªããã¨ãæ©ããªãªã¼ã¹ãã¦ãã ãã¼ã¼ãã
Seamã¯ã大éã«ã¡ã¢ãªã使ããã¨ãè¦ã«ãªããªããããªã·ã¹ãã ãªã、è¯ãã®ã§ã¯ãªãã§ãããããSQLã®æ±ãã貧弱ãªåé¡ç¹ã¯ï½¤Hibernateã®Sessionãç´ã«å¼ã¶ãã¨ã§è§£æ±ºã§ããã§ãããã
Uuji(ãã¼ã)
JPAã§ã¯ãçç£æ§ã®åä¸ã«ã¯ã¤ãªãããªãã¨è¨ããã¨ãåãã£ãã®ã§ï½¤çç£æ§ãåä¸ãããæ°¸ç¶å層ã®ãã¬ã¼ã ã¯ã¼ã¯ã¨ãã¦ãUujiãä½ããã¨ãæãã¤ãã¾ããã
å½åãUujiã¯ã極åJavaã®ã¯ã©ã¹ãã³ã¼ããæ¸ããã«ããã¼ã¿ãã¼ã¹ã«ã¢ã¯ã»ã¹ãããã¨ãç®æãã¦è¨è¨ãã¾ãããå
·ä½çã«ã¯ï½¤è¦ç´ããSQLãçæã、ãã¼ã¿ãã¼ã¹ã®ããåãã«ã¯ï½¤Mapã使ãã¾ãã
ããã¯ãããã§é¢ç½ãã¨æã£ãã®ã§ãã、Seasarã«ã³ãã¡ã¬ã³ã¹ä»¥éãè²ã
ãã¢ãªã³ã°ããã¿ã¦ãã©ããè©å¤ã¯ä»ã²ã¨ã¤ã§ãã(è¦ç¬)ã
ããã§ãããä¸åº¦ãã³ã³ã»ãããç·´ãç´ãã¦åè¨è¨ãããã¨ã«ãã¾ãããæ°ã³ã³ã»ããã¯ï½¤ãªã¬ã¼ã·ã§ãã«ã¢ãã«(RDB)ãã§ããéãçãããããã¨ã§ããJPAããã¡ã¤ã³ã¢ãã«ãæ§ç¯ãããã¨ãç®çã¨ãã¦ï½¤SQL(JPQL)ã®æ©è½ãéå®ãã¦ããã®ã¨ãé常ã«å¯¾ç
§çã§ã¯ãªããã¨æãã¾ãã
ããã§ã¯ãS2Daoã¨ã®éãã¯ä½ã§ãããããS2Daoã¯ãSQLãæ¸ããã¨ãåºæ¬ã§ããSQLæã®èªåçæãã§ãã¾ãã、ãã¾ãç¨åº¦ã ã¨æã£ãã»ããè¯ãã§ããããããã«å¯¾ã、Uujiã¯ãã¢ããªã±ã¼ã·ã§ã³ã§ä½¿ã90%以ä¸ã®SQLæã¯èªåçæãããã¨ãæ³å®ãã¦ãã¾ããã¾ãã1:Nããã¹ãããN:1ã®é¢é£ããµãã¼ããã¾ããN:Nã¯ã1:N,N:1ã¨ãã¦è¡¨ç¾ããã»ãããã¼ã¿ã¢ãã«ã¨ãã¦æ確ã§è¯ãã¨æã£ã¦ããã®ã§ãµãã¼ããã¾ããã
ã¾ããUujiã¯ãã³ã¼ãã¸ã§ãã¬ã¼ã¿(Dolteng)ã¨ç¸æ§ã®è¯ãè¨è¨ã«ãã¾ããDoltengãæåã«åãåºãã³ã¼ãã§æ°¸ç¶åãã¸ãã¯ã®90%以ä¸ãã«ãã¼ã§ããã¨èãã¦ãããã、çç£æ§ãé«ãã¨è¨ããã¦ããS2Daoã®ããã«10åã®çç£æ§ããããåºãå¯è½æ§ãããã¾ãã
ããã©ã¼ãã³ã¹ãS2Daoããããªãåä¸ããã¾ããç¾å¨ã®S2Daoã§ã¯ãæåã«ã¢ã¯ã»ã¹ãããã¨ãã«ï½¤ãã¼ãã«ã®ã¡ã¿æ
å ±ãåå¾ãã¦ï½¤Javaä¸ã§ã¯è¡¨ç¾ããã¦ããªãæ
å ±ãè£å®ãã¦ãã¾ãã、ãã®ã¡ã¿ãã¼ã¿ã¸ã®ã¢ã¯ã»ã¹ãæ¢ãã¾ããããã§ã¯ãã©ããã足ããªãæ
å ±ãä¿ç®¡ãããã¨ããã¨ãè¦ç´ãã§ããè¦ç´éè¦ãããã«å¾¹åºããã¾ãããã®è¦ç´ã¯ï½¤ããã¸ã§ã¯ããã¨ã«ã«ã¹ã¿ãã¤ãºã§ããããã«ãã¾ããããã«ãåRDBMSã®æ©è½ã使ãåããã¨ã§ããã©ã¼ãã³ã¹ã®åä¸ãå³ãã¾ããä¾ãã°ï½¤Pagingã§ãªã©ã¯ã«ãªãrownumã使ãã ã¨ããåãããããä¾ã§ãã
ããã§ã¯ãUujiãå®æããã¨ãã®ã¤ã¡ã¼ã¸ãè¦ã¦ã¿ã¾ãããã次ã®ãããªãã¼ãã«ãããã¾ãã
- emp
- emp_id
- emp_name
- mgr_id
- dept_id
- emp_version
- emp_inserted_timestamp
- emp_updateed_timestamp
- emp_deleted_timestamp
- dept
- dept_id
- dept_name
- dept_version
Doltengã«ã½ã¼ã¹ã³ã¼ããèªåçæããã¾ãããã
Emp.java, EmpCriteria.java, EmpDao, Dept.java, DeptCriteria.java, DeptDao.javaãèªåçæããã¾ãã
Criteriaãªãã¸ã§ã¯ãã®ç解ãUujiã®èã¨ãã£ã¦ãéè¨ã§ã¯ããã¾ãããå ·ä½çãªä½¿ãæ¹ãè¦ã¦ããã¾ããããæåã¯ï½¤deptIdã10ã®ãã®ãæ¤ç´¢ãã¦ã¿ã¾ãããã
class Emp {
private Long empId;
private String empName;
private Long mgrId;
private Long deptId;
private Integer empVersion;
private Timestamp empInsertedTimestamp;
private Timestamp empUpdatedTimestamp;
private Timestamp empDeletedTimestamp;
private Emp mgr;
private Listemps;
private Dept dept;
...
}
class Dept {
private Long deptId;
private String deptName;
private Integer deptVersion;
private Listemps;
...
}
class EmpCriteria extends Emp {
private String orderby;
private Integer firstResult;
private Integer maxResults;
private String[] fetchJoins;
...
}
class DeptCriteria extends Dept {
...
}
interface EmpDao {
Emp findFirst(EmpCriteria criteria);
ListfindAll(EmpCriteria criteria);
Emp fill(Emp entity, String... fetchJoins);
int count(EmpCriteria criteria);
void insert(Emp entity);
void insertBatch(Listentities);
void update(Emp entity);
void updateUnlessNull(Emp entity);
void updateBatch(Listentities);
int updateAll(Emp entity, EmpCriteria entity);
void delete(Emp entity);
void deleteBatch(Listentities);
int deleteAll(EmpCriteria entity);
}
equalsæ¤ç´¢ã¯ï½¤ããããã£ã«å¤ãå ¥ããã ãã§ããè¤æ°ã®ããããã£ã«å¤ãè¨å®ãããandæ¤ç´¢ã«ãªãã¾ãããã®è¾ºã¯æ³å®ã©ããã§ããããããã§ã¯ãdeptIdã10ã¨20ã®ãã®ãæ¤ç´¢ãã¦ã¿ã¾ããããããããinã§ãããDoltengã§EmpCriteriaãå³ã¯ãªãã¯ã、Criteriaã®è¨å®ãé¸ã³ã¾ããã¦ã£ã¶ã¼ããèµ·åããã®ã§ï½¤deptIdã®INã®ãã§ãã¯ããã¯ã¹ãã¯ãªãã¯ãã¦ãã ãããOKãæ¼ãã¨æ¬¡ã®ã³ã¼ããEmpCriteriaã«è¿½å ããã¦ãã¾ãã
EmpCriteria criteria = new EmpCcriteria();
criteria.setDeptId(10);
Listemps = dao.findAll(criterial);
ããã§ã¯æ¤ç´¢ããã³ã¼ããæ¸ãã¦ã¿ã¾ãããã
private Integer[] deptId_IN;
...
deptNameãACCOUNTã®ãã®ãæ¤ç´¢ãã¦ã¿ã¾ããããå ã»ã©ã¨åãããã«Doltengãå¼ã³åºãã¾ããdeptã®ããªã¼ãã¯ãªãã¯ãã¦ãã¼ããéã、deptNameã®EQããã§ãã¯ãã¦OKãã¿ã³ãæ¼ãã¾ãã次ã®ã³ã¼ããEmpCriteriaã«è¿½å ããã¦ãã¾ãã
EmpCriteria criteria = new EmpCcriteria();
criteria.setDeptId_IN(10, 20);
Listemps = dao.findAll(criterial);
ããã§ã¯æ¤ç´¢ããã³ã¼ããæ¸ãã¦ã¿ã¾ãããã
private String dept$deptName;
...
Uujiã¯ãcreteria.fetchJoinsãæå®ããªãéã、é¢é£ã®ã¨ã³ãã£ãã£ãåå¾ãããã¨ã¯ãã¾ãããããã§ã¯ãEmpã¨åæã«Deptã®ãã¼ã¿ãåå¾ãã¦ã¿ã¾ãããã
EmpCriteria criteria = new EmpCcriteria();
criteria.setDept$deptName("ACCOUNT");
Listemps = dao.findAll(criterial);
emp.deptã«ã¯ãã£ããå¤ãå ¥ã£ã¦ãã¾ããFetchJoinã®ããã©ã«ãã¯ï½¤outerã§ãããdept innerã®ããã«inner joinã«ãããã¨ãã§ãã¾ããèªåã®é¨ä¸ãåå¾ãã¦ã¿ã¾ããããé¨ä¸ã¯ååé ã«åå¾ãã¾ãã
EmpCriteria criteria = new EmpCriteria();
criteria.setFetchJoins("dept");
Listemps = dao.findAll(criterial);
Criteriaã®orderbyã¯ã½ã¼ãé ãæå®ãããã®ã§ããfirstResultã¯Pagingã®offsetãmaxResultã¯Pagingã®limitã§ãã
criteria.setFetchJoins("dept", "emps orderby emps.empName");
Daoã®fillã¡ã½ããã¯ï½¤é¢é£ã解決ãããã®ã§ããdao.fill(emp, "dept", "emps orderby emps.empName");Web層ã§ãµããããããããã¼ã¿ã«ã¯ï½¤é¢é£ã¯ã»ããããã¦ããªãã®ã§ï½¤æ¥åãã¸ãã¯å´ã§é¢é£ã解決ããã¨ãã«ä½¿ãã¾ãã
updateã¯ããã¼ã¿ãã¼ã¹ããåå¾ãããã¼ã¿ã¨ç°ãªãå¤ãæã¤ã«ã©ã ã ããæ´æ°ããã¾ãã
ãã¼ãã«å_inserted_timestampã®ã«ã©ã ãããã°ï½¤ãã¼ã¿ãã¼ã¹ã®ç¾å¨æå»(ãªã©ã¯ã«ãªãsysdate)ãèªåçã«æ¿å ¥ãã¾ãããã¼ãã«å_updated_timestampãåæ§ã§ãããã¼ãã«å_deleted_timestampã¯ãè«çåé¤ç¨ã§ãããã¼ãã«å_deleted_timestampã®ã«ã©ã ã®ãããã¼ãã«ã§deleteã¡ã½ãããå¼ã³åºãããã¨updateæã§deleted_timestampãæ¿å ¥ããã¾ããfindã®æã«ã¯ï½¤SELECTæã®WHEREå¥ã«deleted_timestamp == nullã®æ¡ä»¶ãèªåçã«è¿½å ããã¾ãã
90%ã®ä½æ¥ã¯ä¸è¨ã®ãã¨ãç¥ã£ã¦ããã°ããªããã§ããããå¦ç¿ã³ã¹ããé常ã«ä½ããã¨ãåãã£ã¦ããã ããã®ã§ã¯ãªãã§ããããã