
ããŒã¿ããŒã¹ã䜿çšããŠæ°ããæ©èœãéçºããå Žåãéçºãµã€ã¯ã«ã«ã¯éåžžãæ¬¡ã®æ®µéãå«ãŸããŸãïŒãã ãããããã«éå®ãããŸããïŒ
ãSQLç§»è¡ã®èšè¿°âã³ãŒãã®èšè¿°âãã¹ãâãªãªãŒã¹âç£èŠã
ãã®èšäºã§ã¯ãå質ãäœäžãããã®ã§ã¯ãªããåäžããããšåæã«ãåæ®µéã§ãã®ãµã€ã¯ã«ã®æéãççž®ããæ¹æ³ã«ã€ããŠãããã€ãã®å®çšçãªã¢ããã€ã¹ãå ±æããããšæããŸãã
äŒç€Ÿã§PostgreSQLã䜿çšããJavaã§ãµãŒããŒã³ãŒããèšè¿°ããŠãããããäŸã¯ãã®ã¹ã¿ãã¯ã«åºã¥ããŠããŸãããã»ãšãã©ã®ã¢ã€ãã¢ã¯äœ¿çšããããŒã¿ããŒã¹ãããã°ã©ãã³ã°èšèªã«äŸåããŠããŸããã
SQLã®ç§»è¡
èšèšåŸã®éçºã®æåã®æ®µéã¯ãSQLç§»è¡ã®èšè¿°ã§ããäž»ãªã¢ããã€ã¹-ããŒã¿ã¹ããŒãã«æåã§å€æŽãå ããããšã¯ãããŸããããåžžã«ã¹ã¯ãªãããä»ããŠè¡ãããããã1ãæã«ä¿åããŸãã
åœç€Ÿã§ã¯ãéçºè ãSQLç§»è¡ãèªåã§äœæããããããã¹ãŠã®ç§»è¡ã¯ã¡ã€ã³ã³ãŒããšãšãã«ãªããžããªã«ä¿åãããŸããäžéšã®äŒæ¥ã§ã¯ãããŒã¿ããŒã¹ç®¡çè ãã¹ããŒãã®å€æŽã«é¢äžããŠããŸãããã®å Žåãç§»è¡ã¬ãžã¹ããªã¯ã©ããã«ãããŸãããããã«ããããã®ã¢ãããŒãã«ã¯æ¬¡ã®å©ç¹ããããŸãã
- æ°ããããŒã¹ãæåããç°¡åã«äœæããããæ¢åã®ããŒã¹ãçŸåšã®ããŒãžã§ã³ã«ã¢ããã°ã¬ãŒããããã§ããŸããããã«ãããæ°ãããã¹ãç°å¢ãšããŒã«ã«éçºç°å¢ããã°ããå±éã§ããŸãã
- ãã¹ãŠã®æ ç¹ã®ã¬ã€ã¢ãŠãã¯åãã§ãããµãŒãã¹ã«é©ãã¯ãããŸããã
- ãã¹ãŠã®å€æŽïŒããŒãžã§ã³ç®¡çïŒã®å±¥æŽããããŸãã
ãäž¡æ¹ã®åæ¥ããã³ç¡æã®ãã®ããã»ã¹ãèªååããããã®å€ãã®æ¢è£œã®ããŒã«ããããŸãïŒãã©ã€ãŠã§ã€ãLiquiBaseããsqitchç§ãæ¯èŒããŠãæé«ã®ããŒã«ãéžæããªãã§ãããããã®èšäºã§ã¯ãªã©ã¯ã -ããã¯ãå¥ã®å€§ããªããŒãã§ããããããŠããªãã¯ããã«å€ãã®èšäºãèŠã€ããããšãã§ããŸã..ã
ç§ãã¡ã¯ãã©ã€ãŠã§ã€ã䜿çšããŠããã®ã§ãããã«ããã«ã€ããŠã®å°ãã®æ å ±ããããŸãïŒ
- ç§»è¡ã«ã¯ãsqlããŒã¹ãšjavaããŒã¹ã®2çš®é¡ããããŸãã
- SQLã®ç§»è¡ã¯äžå€ïŒäžå€ïŒã§ããæåã®å®è¡åŸãSQLç§»è¡ã¯å€æŽã§ããŸãããFlywayã¯ãç§»è¡ãã¡ã€ã«ã®å 容ã®ãã§ãã¯ãµã ãèšç®ããå®è¡ãããã³ã«ãããæ€èšŒããŸããJavaã®ç§»è¡ãäžå€ã«ããã«ã¯ã远å ã®æåæäœãå¿ èŠã§ãã
- flyway_schema_history ( schema_version). , , , .
å éšå¥çŽã«ãããšããã¹ãŠã®ããŒã¿ã¹ããŒãã®å€æŽã¯ãSQLã®ç§»è¡ã«ãã£ãŠã®ã¿è¡ãããŸãããããã®äžå€æ§ã«ããããã¹ãŠã®ç°å¢ãšå®å šã«åäžã®å®éã®ã¹ããŒããåžžã«ååŸã§ããŸãã
Javaç§»è¡ã¯ãçŽç²ãªSQLã§èšè¿°ã§ããªãDMLã«ã®ã¿äœ¿çšãããŸããç§ãã¡ã«ãšã£ãŠããã®ãããªç¶æ³ã®å žåçãªäŸã¯ãå¥ã®ããŒã¿ããŒã¹ããPostgresã«ããŒã¿ã転éããããã®ç§»è¡ã§ãïŒRedisããPostgresã«ç§»è¡ããŠããŸãããããã¯ãŸã£ããå¥ã®è©±ã§ãïŒããã1ã€ã®äŸã¯ã倧ããªããŒãã«ã®ããŒã¿ãæŽæ°ããããšã§ããããã¯ãããŒãã«ã®ããã¯æéãæå°éã«æããããã«è€æ°ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ãããŸãã Postgresã®11çªç®ã®ããŒãžã§ã³ãããããã¯plpgsqlã®SQLããã·ãŒãžã£ã䜿çšããŠå®è¡ã§ããããšã¯èšããŸã§ããããŸããã
Javaã³ãŒããå€ããªã£ãŠããå Žåãã¬ã¬ã·ãŒãçæããªãããã«ç§»è¡ãåé€ã§ããŸãïŒJavaç§»è¡ã¯ã©ã¹èªäœã¯æ®ããŸãããå éšã¯ç©ºã§ãïŒãç§ãã¡ã®åœã§ã¯ãããã¯æ¬çªç°å¢ãžã®ç§»è¡åŸ1ãæä»¥å ã«çºçããå¯èœæ§ããããŸããããã¯ããã¹ãŠã®ãã¹ãç°å¢ãšããŒã«ã«éçºç°å¢ãæŽæ°ããã®ã«ååãªæéã§ãããšèããŠããŸããJavaã®ç§»è¡ã¯DMLã«ã®ã¿äœ¿çšããããããããããåé€ããŠããæ°ããããŒã¿ããŒã¹ãæåããäœæããããšã«ã¯ãŸã£ãã圱é¿ããªãããšã«æ³šæããŠãã ããã
pg_bouncerã䜿çšãã人ã«ãšã£ãŠéèŠãªãã¥ã¢ã³ã¹
Flywayã¯ãç§»è¡äžã«ããã¯ãé©çšããŠãè€æ°ã®ç§»è¡ãåæã«å®è¡ãããªãããã«ããŸããç°¡ç¥åãããšã次ã®ããã«æ©èœããŸãã
- ããã¯ããã£ããã£ãããŠããŸã
- åå¥ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§ç§»è¡ãå®è¡ãã
- ãããã¯ãè§£é€ããŸãã
Postgresã®å Žåãã»ãã·ã§ã³ã¢ãŒãã§ã¢ããã€ã¶ãªããã¯ã䜿çšããŸããã€ãŸããæ£ããæ©èœããã«ã¯ãããã¯ã®ãã£ããã£ãšè§£æŸäžã«ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãåãæ¥ç¶ã§å®è¡ãããŠããå¿ èŠããããŸãããã©ã³ã¶ã¯ã·ã§ã³ã¢ãŒãïŒæãäžè¬çïŒãŸãã¯ã·ã³ã°ã«ãªã¯ãšã¹ãã¢ãŒãã§pg_bouncerã䜿çšãããšããã©ã³ã¶ã¯ã·ã§ã³ããšã«æ°ããæ¥ç¶ãè¿ãããå Žåããããflywayã¯ç¢ºç«ãããããã¯ãè§£æŸã§ããŸããã
ãã®åé¡ã解決ããããã«ãã»ãã·ã§ã³ã¢ãŒãã®pg_bouncerã§åå¥ã®å°ããªæ¥ç¶ããŒã«ã䜿çšããŸããããã¯ç§»è¡ã®ã¿ãç®çãšããŠããŸããã¢ããªã±ãŒã·ã§ã³ã®åŽããã¯ã1ã€ã®æ¥ç¶ãå«ãå¥ã®ããŒã«ãããããªãœãŒã¹ã浪費ããªãããã«ãç§»è¡åŸã«ã¿ã€ã ã¢ãŠãã«ãã£ãŠéããããŸãã
ã³ãŒãã£ã³ã°
ç§»è¡ãäœæãããŸãããçŸåšãã³ãŒããèšè¿°ããŠããŸãã
ã¢ããªã±ãŒã·ã§ã³åŽããããŒã¿ããŒã¹ãæäœããã«ã¯ã次ã®3ã€ã®ã¢ãããŒãããããŸãã
- ORMã®äœ¿çšïŒJavaã«ã€ããŠè©±ãå ŽåãäŒæ¢ç¶æ ã¯äºå®äžæšæºã§ãïŒ
- ãã¬ãŒã³sql + jdbcTemplateãªã©ã䜿çšããŸãã
- DSLã©ã€ãã©ãªã®äœ¿çšã
ORMã䜿çšãããšãSQLã®ç¥èã®èŠä»¶ãæžããããšãã§ããŸã-å€ããèªåçã«çæãããŸãïŒ
- ããŒã¿ã¹ããŒãã¯ãã³ãŒãã§äœ¿çšå¯èœãªxml-descriptionãŸãã¯Java-entityããäœæã§ããŸãã
- ãªããžã§ã¯ãã®é¢ä¿ã¯ã宣èšçãªèª¬æã䜿çšããŠå®çŸ©ãããŸã-ORMãçµåãè¡ããŸã
- Spring Data JPAã䜿çšãããšããªããžããªã¡ãœããã®çœ²åã«åºã¥ããŠããã«ããªãããŒãªã¯ãšãªãèªåçã«çæããããšãã§ããŸãã
ãã1ã€ã®ãããŒãã¹ãã¯ãããã«äœ¿çšã§ããããŒã¿ãã£ãã·ã¥ã®ååšã§ãïŒäŒæ¢ç¶æ ã®å Žåããããã¯3ã¬ãã«ã®ãã£ãã·ã¥ã§ãïŒã
ãã ããORMã¯ãä»ã®åŒ·åãªããŒã«ãšåæ§ã«ã䜿çšãããšãã«ç¹å®ã®è³æ Œãå¿ èŠã§ããããšã«æ³šæããããšãéèŠã§ããé©åãªæ§æããªããšãã³ãŒãã¯æ©èœããå¯èœæ§ãé«ããªããŸãããæé©ãšã¯èšããŸããã
å察ã«ãSQLãæåã§äœæããŸããããã«ããããªã¯ãšã¹ããå®å šã«å¶åŸ¡ã§ããŸããäœæããå å®¹ãæ£ç¢ºã«å®è¡ãããé©ãããšã¯ãããŸãããããããæããã«ãããã¯æäœæ¥ã®éãå¢ãããéçºè ã®è³æ Œã®èŠä»¶ãå¢ãããŸãã
DSLã©ã€ãã©ãª
ãããã®ã¢ãããŒãã®ã»ãŒäžéã«ãDSLã©ã€ãã©ãªïŒjOOQãQuerydslãªã©ïŒã®äœ¿çšãããªãå¥ã®ã¢ãããŒãããããŸãããããã¯éåžžãORMãããã¯ããã«è»œéã§ãããå®å šã«æåã®ããŒã¿ããŒã¹äœæ¥ããã䟿å©ã§ããDSLã®äœ¿çšã¯ããŸãäžè¬çã§ã¯ãªãããããã®èšäºã§ã¯ãã®ã¢ãããŒãã«ã€ããŠç°¡åã«èª¬æããŸãã
ã©ã€ãã©ãªã®1ã€ã§ããjOOQã«ã€ããŠèª¬æããŸãã圌女ã¯äœãæäŸããŠããŸããïŒ
- ããŒã¿ããŒã¹æ€æ»ãšã¯ã©ã¹ã®èªåçæ
- ãªã¯ãšã¹ããæžãããã®æµæ¢ãªAPIã
jOOQã¯ORMã§ã¯ãããŸãã-ã¯ãšãªããã£ãã·ã³ã°ã®èªåçæã¯ãããŸããããåæã«ãå®å šã«æåã®ã¢ãããŒãã®åé¡ã®ããã€ãã¯éããããŠããŸãã
- ããŒãã«ããã¥ãŒã颿°ãªã©ã®ã¯ã©ã¹ãããŒã¿ããŒã¹ãªããžã§ã¯ãã¯èªåçã«çæãããŸãã
- ãªã¯ãšã¹ãã¯Javaã§èšè¿°ãããŠãããããã¿ã€ãã»ãŒããä¿èšŒãããŸããæ§æçã«æ£ãããªããªã¯ãšã¹ãããééã£ãã¿ã€ãã®ãã©ã¡ãŒã¿ãæã€ãªã¯ãšã¹ãã¯ã³ã³ãã€ã«ãããŸãããIDEã¯ããã«ãšã©ãŒãèŠæ±ããã¢ããªã±ãŒã·ã§ã³ãèµ·åããŠãªã¯ãšã¹ãã®æ£ç¢ºãã確èªããããã«æéãç¡é§ã«ããå¿ èŠã¯ãããŸãããããã«ãããéçºããã»ã¹ãã¹ããŒãã¢ãããããšã©ãŒã®å¯èœæ§ãæžå°ããŸãã
ã³ãŒãã§ã¯ããªã¯ãšã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
BookRecord book = dslContext.selectFrom(BOOK)
.where(BOOK.LANGUAGE.eq("DE"))
.orderBy(BOOK.TITLE)
.fetchAny();
å¿ èŠã«å¿ããŠããã¬ãŒã³sqlã䜿çšã§ããŸãã
Result<Record> records = dslContext.fetch("SELECT * FROM BOOK WHERE LANGUAGE = ? ORDER BY TITLE LIMIT 1", "DE");
æããã«ããã®å Žåãã¯ãšãªã®æ£ç¢ºããšçµæã®åæã¯å®å šã«ããªãã®è©ã«ããã£ãŠããŸãã
jOOQã¬ã³ãŒããšPOJO
äžèšã®äŸã®BookRecordã¯ãããã¯ããŒãã«ã®è¡ã®ã©ãããŒã§ãããã¢ã¯ãã£ããªã¬ã³ãŒããã¿ãŒã³ãå®è£ ããŸãããã®ã¯ã©ã¹ã¯ïŒç¹å®ã®å®è£ ãé€ããŠïŒããŒã¿ã¢ã¯ã»ã¹ã¬ã€ã€ãŒã®äžéšã§ãããããã¢ããªã±ãŒã·ã§ã³ã®ä»ã®ã¬ã€ã€ãŒã«è»¢éããããªãå ŽåããããŸãããç¬èªã®ããçš®ã®pojoãªããžã§ã¯ãã䜿çšããŸããã¬ã³ãŒãã®å€æã«äŸ¿å©ãªããã«ã<â> pojo jooqã«ã¯ãèªåãšæåã®ã¡ã«ããºã ãããã€ãçšæãããŠããŸããäžèšã®ãªã³ã¯ã®ããã¥ã¡ã³ãã«ã¯ãããŸããŸãªèªã¿åã䜿çšäŸããããŸãããæ°ããããŒã¿ã®æ¿å ¥ãšæŽæ°ã®äŸã¯ãããŸããããã®ã®ã£ãããåããŸãããïŒ
private static final RecordUnmapper<Book, BookRecord> unmapper =
book -> new BookRecord(book.getTitle(), ...); // -
public void create(Book book) {
context.insertInto(BOOK)
.set(unmapper.unmap(book))
.execute();
}
ã芧ã®ãšããããã¹ãŠãéåžžã«åçŽã§ãã
ãã®ã¢ãããŒãã«ãããããŒã¿ã¢ã¯ã»ã¹ã¬ã€ã€ãŒã¯ã©ã¹å ã®å®è£ ã®è©³çްãé衚瀺ã«ããã¢ããªã±ãŒã·ã§ã³ã®ä»ã®ã¬ã€ã€ãŒãžã®ããªãŒã¯ããåé¿ã§ããŸãã
ãŸããjooqã¯ãäžé£ã®åºæ¬çãªã¡ãœããã䜿çšããŠDAOã¯ã©ã¹ãçæããããŒãã«ããŒã¿ã®æäœãç°¡çŽ åããæåã³ãŒãã®éãæžããããšãã§ããŸãïŒããã¯Spring Data JPAãšéåžžã«ãã䌌ãŠããŸãïŒã
public interface DAO<R extends TableRecord<R>, P, T> {
void insert(P object) throws DataAccessException;
void update(P object) throws DataAccessException;
void delete(P... objects) throws DataAccessException;
void deleteById(T... ids) throws DataAccessException;
boolean exists(P object) throws DataAccessException;
...
}
äŒç€Ÿã§ã¯ãDAOã¯ã©ã¹ã®èªåçæã䜿çšããŠããŸãããããŒã¿ããŒã¹ãªããžã§ã¯ãã®ã©ãããŒãçæããèªåã§ã¯ãšãªãäœæããã ãã§ããã©ãããŒã®çæã¯ãç§»è¡ãä¿åãããå¥ã®mavenã¢ãžã¥ãŒã«ãåæ§ç¯ããããã³ã«çºçããŸããå°ãåŸã§ããããã©ã®ããã«å®è£ ããããã«ã€ããŠã®è©³çްããããŸãã
ãã¹ã
ãã¹ãã®äœæã¯éçºããã»ã¹ã®éèŠãªéšåã§ããåªãããã¹ãã¯ã³ãŒãã®å質ãä¿èšŒããã³ãŒããç¶æããªããæéãç¯çŽããŸããåæã«ããã®éãåœãŠã¯ãŸããšèšã£ãŠãéèšã§ã¯ãããŸããããã¹ããæªããšãé«å質ã®ã³ãŒãã®é¯èŠãçãããšã©ãŒãé ãããéçºããã»ã¹ãé ããªãå¯èœæ§ããããŸãããããã£ãŠããã¹ããäœæããããšã決å®ããã ãã§ã¯ååã§ã¯ãªããæ£ããå®è¡ããå¿ èŠããããŸããåæã«ããã¹ãã®æ£ç¢ºãã®æŠå¿µã¯éåžžã«ææ§ã§ããã誰ããå°ãç¬èªã®ãã®ãæã£ãŠããŸãã
ãã¹ãåé¡ã®åé¡ã«ã€ããŠãåãããšãèšããŸãããã®èšäºã§ã¯ã次ã®åå²ãªãã·ã§ã³ã®äœ¿çšãææ¡ããŠããŸãã
- ãŠããããã¹ãïŒãŠããããã¹ãïŒ
- çµ±åãã¹ã
- ãšã³ãããŒãšã³ããã¹ãïŒãšã³ãããŒãšã³ãïŒã
ãŠããããã¹ãã§ã¯ãåã ã®ã¢ãžã¥ãŒã«ã®æ©èœãäºãã«åé¢ããŠãã§ãã¯ããŸããã¢ãžã¥ãŒã«ã®ãµã€ãºãæªå®çŸ©ã®ãã®ã§ããå¥ã®ã¡ãœããã§ããå Žåãããã°ãã¯ã©ã¹ã§ããå ŽåããããŸããåé¢ãšã¯ãä»ã®ãã¹ãŠã®ã¢ãžã¥ãŒã«ãã¢ãã¯ãŸãã¯ã¹ã¿ãã§ããããšãæå³ããŸãïŒãã·ã¢èªã§ã¯ããããã¯æš¡å£ãŸãã¯ã¹ã¿ãã§ãããã©ãããããããããŸãè¯ãèãããŸããïŒããã®ãªã³ã¯ããã©ã£ãŠã2ã€ã®éãã«é¢ããMartinFowlerã®èšäºãèªãã§ãã ããããŠããããã¹ãã¯å°ãããŠé«éã§ãããåã ã®ãŠãããã®ããžãã¯ã®æ£ç¢ºããä¿èšŒããããšããã§ããŸããã
çµ±åãã¹ããŠããããã¹ããšã¯ç°ãªããè€æ°ã®ã¢ãžã¥ãŒã«ã®çžäºäœçšããã§ãã¯ããŸããããŒã¿ããŒã¹ã®æäœã¯ãçµ±åãã¹ããçã«ããªã£ãŠããå Žåã®è¯ãäŸã§ããããŒã¿ããŒã¹ã®ãã¹ãŠã®ãã¥ã¢ã³ã¹ãèæ ®ããŠãé«å質ã§ããŒã¿ããŒã¹ããããã¯ãããããšã¯éåžžã«é£ããããã§ããã»ãšãã©ã®å Žåãçµ±åãã¹ãã¯ãä»ã®ã¿ã€ãã®ãã¹ããšæ¯èŒããŠãããŒã¿ããŒã¹ããã¹ãããéã®å®è¡é床ãšå質ä¿èšŒã®éã®é©åãªåŠ¥åç¹ã§ãããããã£ãŠããã®èšäºã§ã¯ããã®ã¿ã€ãã®ãã¹ãã«ã€ããŠè©³ãã説æããŸãã
ãšã³ãããŒãšã³ãã®ãã¹ãã¯æãåºç¯å²ã§ãããããå®è¡ããããã«ã¯ãç°å¢å šäœãé«ããå¿ èŠããããŸãã補åã®å質ã«å¯Ÿããæé«ã¬ãã«ã®ä¿¡é Œæ§ãä¿èšŒããŸãããæãé ããæãé«äŸ¡ã§ãã
çµ±åãã¹ã
ããŒã¿ããŒã¹ã§åäœããã³ãŒãã®çµ±åãã¹ãã«é¢ããŠã¯ãã»ãšãã©ã®éçºè ã¯ãããŒã¿ããŒã¹ãèµ·åããæ¹æ³ãåæããŒã¿ã§ç¶æ ãåæåããæ¹æ³ãããã³å¯èœãªéãè¿ éã«å®è¡ããæ¹æ³ã«ã€ããŠèªåããŸãã
å°ãåãŸã§ã¯ãh2ã®äœ¿çšã¯çµ±åãã¹ãã§ã¯ããªãäžè¬çãªæ¹æ³ã§ãããããã¯ãJavaã§èšè¿°ãããã¡ã¢ãªå ããŒã¿ããŒã¹ã§ãããæãäžè¬çãªããŒã¿ããŒã¹ãšã®äºææ§ã¢ãŒãããããŸããããŒã¿ããŒã¹ãã€ã³ã¹ããŒã«ããå¿ èŠããªããh2ã®æ±çšæ§ã«ãããç¹ã«ã¢ããªã±ãŒã·ã§ã³ãç¹å®ã®ããŒã¿ããŒã¹ã«äŸåãããSQLæšæºã«å«ãŸããŠãããã®ã®ã¿ã䜿çšããå ŽåïŒåžžã«ããã§ãããšã¯éããŸããïŒãå®éã®ããŒã¿ããŒã¹ã®éåžžã«äŸ¿å©ãªä»£æ¿åã«ãªããŸããã
ãã ããåé¡ã¯ãh2ã§ãµããŒããå®è£ ãããŠããªãããªãããŒãªããŒã¿ããŒã¹æ©èœïŒãŸãã¯æ°ããããŒãžã§ã³ããã®å®å šã«æ°ããæ©èœïŒã䜿çšãããšãã«å§ãŸããŸãããŸããäžè¬ã«ãããã¯ç¹å®ã®DBMSã®ãã·ãã¥ã¬ãŒã·ã§ã³ãã§ãããããåäœã«ã¯åžžã«ããã€ãã®éãããããŸãã
å¥ã®ãªãã·ã§ã³ã¯ãåã蟌ãŸããpostgresã䜿çšããããšã§ããããã¯å®éã®Postgresã§ãããã¢ãŒã«ã€ããšããŠåºè·ãããã€ã³ã¹ããŒã«ã¯å¿ èŠãããŸãããããã«ãããéåžžã®PostgresããŒãžã§ã³ã®ããã«äœæ¥ã§ããŸãã YandexãšopenTable
ããæã人æ°ã®ããããã€ãã®å®è£ ããããŸã..ã瀟å ã§ã¯Yandexã®ããŒãžã§ã³ã䜿çšããŸããããã€ãã¹é¢ã®ãã¡ãèµ·åæã«éåžžã«æéãããããŸãïŒã¢ãŒã«ã€ããè§£åãããããŒã¿ããŒã¹ãèµ·åããããã³ã«ãã³ã³ãã¥ãŒã¿ãŒã®èœåã«ããããŸããã2ã5ç§ããããŸãïŒãå ¬åŒãªãªãŒã¹ããŒãžã§ã³ããã®é ãã«ãåé¡ããããŸãããŸããã³ãŒãã忢ããããšããåŸããšã©ãŒãçºçããPostgresããã»ã¹ãOSã§ãã³ã°ãããŸãŸã«ãªããšããåé¡ã«çŽé¢ããŸãããããã¯ãæåã§åŒ·å¶çµäºããå¿ èŠããããŸããã
ãã¹ãã³ã³ãã
3çªç®ã®ãªãã·ã§ã³ã¯dockerã䜿çšããããšã§ããJavaã®å Žåãã³ãŒãããdockerã³ã³ãããæäœããããã®apiãæäŸããtestcontainersã©ã€ãã©ãªããããŸãããããã£ãŠãdockerã€ã¡ãŒãžãæã€ã¢ããªã±ãŒã·ã§ã³ã®äŸåé¢ä¿ã¯ãtestcontainersã䜿çšãããã¹ãã§çœ®ãæããããšãã§ããŸãããŸããå€ãã®äžè¬çãªãã¯ãããžãŒã«ã¯ã䜿çšããã€ã¡ãŒãžã«å¿ããŠããã䟿å©ãªapiãæäŸããåå¥ã®æ¢è£œã®ã¯ã©ã¹ããããŸãã
- ããŒã¿ããŒã¹ïŒPostgresãOracleãCassandraãMongoDBãªã©ïŒã
- nginx
- ã«ãã«ãªã©
ã¡ãªã¿ã«ãtescontainersãããžã§ã¯ããéåžžã«äººæ°ã«ãªã£ããšããyandexéçºè ã¯ãçµã¿èŸŒã¿postgresãããžã§ã¯ãã®éçºã忢ããããšãå ¬åŒã«çºè¡šããtestcontainersã«åãæ¿ããããã«ã¢ããã€ã¹ããŸããã
é·æã¯äœã§ããïŒ
- testcontainersã¯é«éã§ãïŒç©ºã®Postgresã®èµ·åã«ã¯1ç§ãããããŸããïŒ
- postgresã³ãã¥ããã£ã¯ãæ°ããããŒãžã§ã³ããšã«å ¬åŒã®ããã«ãŒç»åããªãªãŒã¹ããŸã
- testcontainersã«ã¯ãããã°ã©ã ã§å®è¡ããªãéããjvmãã·ã£ããããŠã³ããåŸã«ã¶ãäžãã£ãŠããã³ã³ããã匷å¶çµäºããç¹å¥ãªããã»ã¹ããããŸãã
- testcontainerã䜿çšãããšãçµ±äžãããã¢ãããŒãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®å€éšäŸåé¢ä¿ããã¹ãã§ããŸããããã«ãããæããã«äœæ¥ãç°¡åã«ãªããŸãã
Postgresã䜿çšãããã¹ã äŸïŒ
@Test
public void testSimple() throws SQLException {
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>()) {
postgres.start();
ResultSet resultSet = performQuery(postgres, "SELECT 1");
int resultSetInt = resultSet.getInt(1);
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
}
}
testcontainersã«ã€ã¡ãŒãžçšã®åå¥ã®ã¯ã©ã¹ããªãå Žåãã³ã³ãããŒã®äœæã¯æ¬¡ã®ããã«ãªããŸãã
public static GenericContainer redis = new GenericContainer("redis:3.0.2")
.withExposedPorts(6379);
JUnit4ãJUnit5ããŸãã¯Spockã䜿çšããŠããå Žåãtestcontainersã«ã¯è¿œå ã®æ©èœããããŸãããããã®ãã¬ãŒã ã¯ãŒã¯ã®ãµããŒããããã«ããããã¹ãã®äœæã容æã«ãªããŸãã
ãã¹ãã³ã³ããã䜿çšãããã¹ãã®é«éå
åã蟌ãŸããpostgresããtestcontainersã«åãæ¿ãããšãPostgresãããéãå®è¡ããããšã§ãã¹ããããéããªããŸããããæéã®çµéãšãšãã«ãã¹ãã¯åã³é ããªãå§ããŸãããããã¯ãflywayãèµ·åæã«å®è¡ããSQLç§»è¡ã®æ°ãå¢å ããããã§ããç§»è¡åæ°ã100ãè¶ ãããšãå®è¡æéã¯çŽ7ã8ç§ã«ãªãããã¹ãã®é床ãå€§å¹ ã«äœäžããŸãããããã¯æ¬¡ã®ããã«æ©èœããŸããïŒ
- 次ã®ãã¹ãã¯ã©ã¹ã®åã«ãPostgresãåãããã¯ãªãŒã³ãªãã³ã³ãããçºå£²ãããŸãã
- ãã©ã€ãŠã§ã€ã¯ç§»è¡ãå®è¡ããŸãã
- ãã®ã¯ã©ã¹ã®ãã¹ããå®è¡ãããŸãã
- ã³ã³ããã忢ãããåé€ãããŸãã
- 次ã®ãã¹ãã¯ã©ã¹ã«ã€ããŠãé ç®1ããç¹°ãè¿ããŸãã
æããã«ãæéã®çµéãšãšãã«ã2çªç®ã®ã¹ãããã«ã¯ãŸããŸãæéãããããŸããã
ãã®åé¡ã解決ããããšãããšããã¹ãŠã®ãã¹ãã®åã«1åã ãç§»è¡ãå®è¡ããã³ã³ãããŒã®ç¶æ ãä¿åããŠããããã®ã³ã³ãããŒããã¹ãŠã®ãã¹ãã§äœ¿çšããã ãã§ååã§ããããšãããããŸããããã®ãããã¢ã«ãŽãªãºã ã倿ŽãããŸããã
- ãã¹ãŠã®ãã¹ãã®åã«ãPostgresãåãããã¯ãªãŒã³ãªãã³ã³ãããèµ·åãããŸã
- flywayã¯ç§»è¡ãå®è¡ããŸã
- ã³ã³ããã®ç¶æ ãæç¶ãã
- 次ã®ãã¹ãã¯ã©ã¹ã®åã«ãäºåã«æºåãããã³ã³ãããèµ·åãããŸã
- ãã®ã¯ã©ã¹ã®ãã¹ããå®è¡ãããŸã
- ã³ã³ããã忢ããåé€ãããŸã
- 次ã®ãã¹ãã¯ã©ã¹ã«ã€ããŠãæé 4ããç¹°ãè¿ããŸãã
çŸåšãåã ã®ãã¹ãã®å®è¡æéã¯ç§»è¡ã®æ°ã«äŸåãããçŸåšã®ç§»è¡ã®æ°ïŒ200以äžïŒã§ã¯ãæ°ããã¹ããŒã ã¯ãã¹ãŠã®ãã¹ãã®å®è¡ããšã«æ°åãç¯çŽããŸãã
ãããå®è£ ããæ¹æ³ã«é¢ããæè¡çãªè©³çŽ°ãæ¬¡ã«ç€ºããŸãã
Dockerã«ã¯ãcommitã³ãã³ãã䜿çšããŠå®è¡äžã®ã³ã³ãããŒããæ°ããã€ã¡ãŒãžãäœæããããã®çµã¿èŸŒã¿ã¡ã«ããºã ããããŸããããšãã°ãèšå®ã倿Žããããšã§ãç»åãã«ã¹ã¿ãã€ãºã§ããŸãã
éèŠãªãã¥ã¢ã³ã¹ã¯ãã³ãã³ããããŠã³ããããããŒãã£ã·ã§ã³ã®ããŒã¿ãä¿åããªãããšã§ãããã ããå ¬åŒã®Postgres dockerã€ã¡ãŒãžãååŸãããšãããŒã¿ãä¿åãããŠããPGDATAãã£ã¬ã¯ããªã¯å¥ã®ã»ã¯ã·ã§ã³ã«é 眮ãããããïŒã³ã³ãããŒã®åèµ·ååŸã«ããŒã¿ã倱ãããªãããã«ããããïŒãã³ããããå®è¡ããããšãã«ããŒã¿ããŒã¹èªäœã®ç¶æ ã¯ä¿åãããŸããã
解決çã¯ç°¡åã§ããPGDATAã®ã»ã¯ã·ã§ã³ã¯äœ¿çšãããããŒã¿ãã¡ã¢ãªã«ä¿æããŸããããã¯ããã¹ãã§ã¯ããæ®éã®ããšã§ãããããè¡ãã«ã¯2ã€ã®æ¹æ³ããããŸã-dockerfileã䜿çšããŸãïŒãã®ãããªãã®ïŒã»ã¯ã·ã§ã³ãäœæããã«ããŸãã¯å ¬åŒã³ã³ããã®éå§æã«PGDATA倿°ããªãŒããŒã©ã€ãããŸãïŒã»ã¯ã·ã§ã³ã¯æ®ããŸããã䜿çšãããŸããïŒã2çªç®ã®æ¹æ³ã¯ã¯ããã«ç°¡åã«èŠããŸãïŒ
PostgreSQLContainer<?> container = ...
container.addEnv("PGDATA", "/var/lib/postgresql/data-no-mounted");
container.start();
ã³ãããããåã«ãpostgresããã§ãã¯ãã€ã³ãããŠã倿Žãå ±æãããã¡ãŒããããã£ã¹ã¯ãïŒãªãŒããŒã©ã€ããããPGDATA倿°ã«å¯Ÿå¿ïŒã«ãã©ãã·ã¥ããããšããå§ãããŸãã
container.execInContainer("psql", "-c", "checkpoint");
ã³ãããèªäœã¯æ¬¡ã®ããã«ãªããŸãã
CommitCmd cmd = container.getDockerClient().commitCmd(container.getContainerId())
.withMessage("Container for integration tests. ...")
.withRepository(imageName)
.withTag(tag);
String imageId = cmd.exec();
æºåãããç»åã䜿çšãããã®ã¢ãããŒãã¯ãä»ã®å€ãã®ç»åã«ãé©çšã§ãããããçµ±åãã¹ããå®è¡ããéã®æéãç¯çŽã§ããããšã¯æ³šç®ã«å€ããŸãã
ãã«ãæéã®æé©åã«ã€ããŠããå°ã
åè¿°ã®ããã«ãç§»è¡ã䜿çšããŠåå¥ã®mavenã¢ãžã¥ãŒã«ãã¢ã»ã³ãã«ããå Žåãç¹ã«ãããŒã¿ããŒã¹ãªããžã§ã¯ãã«å¯ŸããŠjavaã©ãããŒãçæãããŸãããã®ããã«ãã¡ã€ã³ã³ãŒããã³ã³ãã€ã«ããåã«èµ·åãããæ¬¡ã®3ã€ã®ã¢ã¯ã·ã§ã³ãå®è¡ããèªäœã®mavenãã©ã°ã€ã³ã䜿çšãããŸãã
- postgresã§ãã¯ãªãŒã³ãªãããã«ãŒã³ã³ãããå®è¡ããŸã
- Flywayãèµ·åããŸããããã¯ããã¹ãŠã®ããŒã¿ããŒã¹ã«å¯ŸããŠsqlç§»è¡ãå®è¡ããããã«ãã£ãŠãããã®æå¹æ§ããã§ãã¯ããŸãã
- Jooqãå®è¡ããŸããããã¯ãããŒã¿ããŒã¹ã¹ããŒããæ€æ»ããããŒãã«ããã¥ãŒã颿°ãããã³ãã®ä»ã®ã¹ããŒããªããžã§ã¯ãã®Javaã¯ã©ã¹ãçæããŸãã
ç°¡åã«ãããããã«ãæåã®2ã€ã®æé ã¯ããã¹ãã®å®è¡æã«å®è¡ãããæé ãšåãã§ããã³ã³ããã®èµ·åãšãã¹ãåã®ç§»è¡ã®å®è¡ã«ãããæéãç¯çŽããããã«ãã³ã³ããã®ç¶æ ã®ä¿åããã©ã°ã€ã³ã«ç§»åããŸããããããã£ãŠãã¢ãžã¥ãŒã«ãåæ§ç¯ããçŽåŸã«ãã³ãŒãã§äœ¿çšãããŠãããã¹ãŠã®ããŒã¿ããŒã¹ã®çµ±åãã¹ãçšã®æ¢è£œã®ã€ã¡ãŒãžããdockerã€ã¡ãŒãžã®ããŒã«ã«ãªããžããªã«è¡šç€ºãããŸãã
ãã詳现ãªã³ãŒãäŸ
( «start»):
save-state stop .
:
@ThreadSafe
public class PostgresContainerAdapter implements PostgresExecutable {
private static final String ORIGINAL_IMAGE = "postgres:11.6-alpine";
@GuardedBy("this")
@Nullable
private PostgreSQLContainer<?> container; // not null if it is running
@Override
public synchronized String start(int port, String db, String user, String password)
{
Preconditions.checkState(container == null, "postgres is already running");
PostgreSQLContainer<?> newContainer = new PostgreSQLContainer<>(ORIGINAL_IMAGE)
.withDatabaseName(db)
.withUsername(user)
.withPassword(password);
newContainer.addEnv("PGDATA", "/var/lib/postgresql/data-no-mounted");
// workaround for using fixed port instead of random one chosen by docker
List<String> portBindings = new ArrayList<>(newContainer.getPortBindings());
portBindings.add(String.format("%d:%d", port, POSTGRESQL_PORT));
newContainer.setPortBindings(portBindings);
newContainer.start();
container = newContainer;
return container.getJdbcUrl();
}
@Override
public synchronized void saveState(String name) {
try {
Preconditions.checkState(container != null, "postgres isn't started yet");
// flush all changes
doCheckpoint(container);
commitContainer(container, name);
} catch (Exception e) {
stop();
throw new RuntimeException("Saving postgres container state failed", e);
}
}
@Override
public synchronized void stop() {
Preconditions.checkState(container != null, "postgres isn't started yet");
container.stop();
container = null;
}
private static void doCheckpoint(PostgreSQLContainer<?> container) {
try {
container.execInContainer("psql", "-c", "checkpoint");
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
private static void commitContainer(PostgreSQLContainer<?> container, String image)
{
String tag = "latest";
container.getDockerClient().commitCmd(container.getContainerId())
.withMessage("Container for integration tests. It uses non default location for PGDATA which is not mounted to a volume")
.withRepository(image)
.withTag(tag)
.exec();
}
// ...
}
( «start»):
@Mojo(name = "start")
public class PostgresPluginStartMojo extends AbstractMojo {
private static final Logger logger = LoggerFactory.getLogger(PostgresPluginStartMojo.class);
@Nullable
static PostgresExecutable postgres;
@Parameter(defaultValue = "5432")
private int port;
@Parameter(defaultValue = "dbName")
private String db;
@Parameter(defaultValue = "userName")
private String user;
@Parameter(defaultValue = "password")
private String password;
@Override
public void execute() throws MojoExecutionException {
if (postgres != null) {
logger.warn("Postgres already started");
return;
}
logger.info("Starting Postgres");
if (!isDockerInstalled()) {
throw new IllegalStateException("Docker is not installed");
}
String url = start();
testConnection(url, user, password);
logger.info("Postgres started at " + url);
}
private String start() {
postgres = new PostgresContainerAdapter();
return postgres.start(port, db, user, password);
}
private static void testConnection(String url, String user, String password) throws MojoExecutionException {
try (Connection conn = DriverManager.getConnection(url, user, password)) {
conn.createStatement().execute("SELECT 1");
} catch (SQLException e) {
throw new MojoExecutionException("Exception occurred while testing sql connection", e);
}
}
private static boolean isDockerInstalled() {
if (CommandLine.executableExists("docker")) {
return true;
}
if (CommandLine.executableExists("docker.exe")) {
return true;
}
if (CommandLine.executableExists("docker-machine")) {
return true;
}
if (CommandLine.executableExists("docker-machine.exe")) {
return true;
}
return false;
}
}
save-state stop .
:
<build>
<plugins>
<plugin>
<groupId>com.miro.maven</groupId>
<artifactId>PostgresPlugin</artifactId>
<executions>
<!-- running a postgres container -->
<execution>
<id>start-postgres</id>
<phase>generate-sources</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<db>${db}</db>
<user>${dbUser}</user>
<password>${dbPassword}</password>
<port>${dbPort}</port>
</configuration>
</execution>
<!-- applying migrations and generation java-classes -->
<execution>
<id>flyway-and-jooq</id>
<phase>generate-sources</phase>
<goals>
<goal>execute-mojo</goal>
</goals>
<configuration>
<plugins>
<!-- applying migrations -->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<executions>
<execution>
<id>migration</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<url>${dbUrl}</url>
<user>${dbUser}</user>
<password>${dbPassword}</password>
<locations>
<location>filesystem:src/main/resources/migrations</location>
</locations>
</configuration>
</execution>
</executions>
</plugin>
<!-- generation java-classes -->
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
<executions>
<execution>
<id>jooq-generate-sources</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<jdbc>
<url>${dbUrl}</url>
<user>${dbUser}</user>
<password>${dbPassword}</password>
</jdbc>
<generator>
<database>
<name>org.jooq.meta.postgres.PostgresDatabase</name>
<includes>.*</includes>
<excludes>
#exclude flyway tables
schema_version | flyway_schema_history
# other excludes
</excludes>
<includePrimaryKeys>true</includePrimaryKeys>
<includeUniqueKeys>true</includeUniqueKeys>
<includeForeignKeys>true</includeForeignKeys>
<includeExcludeColumns>true</includeExcludeColumns>
</database>
<generate>
<interfaces>false</interfaces>
<deprecated>false</deprecated>
<jpaAnnotations>false</jpaAnnotations>
<validationAnnotations>false</validationAnnotations>
</generate>
<target>
<packageName>com.miro.persistence</packageName>
<directory>src/main/java</directory>
</target>
</generator>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</configuration>
</execution>
<!-- creation an image for integration tests -->
<execution>
<id>save-state-postgres</id>
<phase>generate-sources</phase>
<goals>
<goal>save-state</goal>
</goals>
<configuration>
<name>postgres-it</name>
</configuration>
</execution>
<!-- stopping the container -->
<execution>
<id>stop-postgres</id>
<phase>generate-sources</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
ãªãªãŒã¹
ã³ãŒããæžããããã¹ããããŸãã-ãªãªãŒã¹ããæãæ¥ãŸãããäžè¬ã«ããªãªãŒã¹ã®è€éãã¯æ¬¡ã®èŠå ã«ãã£ãŠç°ãªããŸãã
- ããŒã¿ããŒã¹ã®æ°ïŒ1ã€ä»¥äžïŒ
- ããŒã¿ããŒã¹ã®ãµã€ãºã«ã€ããŠ
- ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã®æ°ïŒ1ã€ä»¥äžïŒ
- ã·ãŒã ã¬ã¹ãªãªãŒã¹ãã©ããïŒã¢ããªã±ãŒã·ã§ã³ã®ããŠã³ã¿ã€ã ãèš±å¯ãããŠãããã©ããïŒã
ã»ãšãã©ã®å Žåããã¹ãŠã®ããŒã¿ããŒã¹ãšãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãåæã«æŽæ°ããããšã¯äžå¯èœã§ãããããé ç®1ãš3ã¯ãã³ãŒãã«äžäœäºææ§ã®èŠä»¶ã課ããŸããããŒã¿ããŒã¹ã®ã¹ããŒããç°ãªãããµãŒããŒã®ã³ãŒãã®ããŒãžã§ã³ãç°ãªãå Žåãåžžã«ãããŸãã
ããŒã¿ããŒã¹ã®ãµã€ãºã¯ç§»è¡æéã«åœ±é¿ããŸããããŒã¿ããŒã¹ã倧ããã»ã©ãé·ãç§»è¡ãå®è¡ããå¿ èŠãçããå¯èœæ§ãé«ããªããŸãã
ã·ãŒã ã¬ã¹æ§ã¯éšåçã«çµæãšããŠçããèŠå ã§ã-ãªãªãŒã¹ãã·ã£ããããŠã³ïŒããŠã³ã¿ã€ã ïŒã§å®è¡ãããå Žåãæåã®3ã€ã®ãã€ã³ãã¯ããã»ã©éèŠã§ã¯ãªããã¢ããªã±ãŒã·ã§ã³ãå©çšã§ããªãæéã«ã®ã¿åœ±é¿ããŸãã
ç§ãã¡ã®ãµãŒãã¹ã«ã€ããŠè©±ãå Žåããããã¯æ¬¡ã®ãšããã§ãã
- çŽ30ã®ããŒã¿ããŒã¹ã¯ã©ã¹ã¿ãŒ
- 1ã€ã®ããŒã¹ã®ãµã€ãº200ã400 GB
- ( 100),
- .
ã«ããªã¢ãªãªãŒã¹ ã䜿çšããŸããã¢ããªã±ãŒã·ã§ã³ã®æ°ããããŒãžã§ã³ãæåã«å°æ°ã®ãµãŒããŒã«è¡šç€ºããïŒãã¬ãªãªãŒã¹ãšåŒã°ããŸãïŒããã°ããããŠããã¬ãªãªãŒã¹ã§ãšã©ãŒãèŠã€ãããªãå Žåã¯ãä»ã®ãµãŒããŒã«ãªãªãŒã¹ãããŸãããããã£ãŠãå®çšŒåãµãŒããŒã¯ããŸããŸãªããŒãžã§ã³ã§å®è¡ã§ããŸãã
èµ·åæã«ãåã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã¯ããœãŒã¹ã³ãŒãã«ããã¹ã¯ãªããã®ããŒãžã§ã³ã䜿çšããŠããŒã¿ããŒã¹ã®ããŒãžã§ã³ããã§ãã¯ããŸãïŒãã©ã€ãŠã§ã€ã®èгç¹ãããããã¯æ€èšŒãšåŒã°ããŸãïŒãããããç°ãªãå ŽåããµãŒããŒã¯èµ·åããŸãããããã«ãããã³ãŒããšããŒã¿ããŒã¹ã®äºææ§ãä¿èšŒãããŸããããšãã°ãç§»è¡ããµãŒããŒã®å¥ã®ããŒãžã§ã³ã§è¡ãããŠããããã«ãã³ãŒãããŸã äœæãããŠããªãããŒãã«ã§æ©èœããå Žåãç¶æ³ã¯çºçããŸããã
ãã ããããšãã°ãæ°ããããŒãžã§ã³ã®ã¢ããªã±ãŒã·ã§ã³ã§ãå€ãããŒãžã§ã³ã®ãµãŒããŒã§äœ¿çšã§ããããŒãã«ã®åãåé€ããç§»è¡ãããå Žåãããã¯ãã¡ããåé¡ã解決ããŸãããçŸåšããã®ãããªç¶æ³ã¯ã¬ãã¥ãŒæ®µéã§ã®ã¿ãã§ãã¯ããŠããŸãïŒå¿ é ã§ãïŒããå奜çãªæ¹æ³ã§è¿œå ãå°å ¥ããå¿ èŠããããŸããCI / CDãµã€ã¯ã«ã§ãã®ãããªãã§ãã¯ãè¡ãã¹ããŒãžã
ç§»è¡ã«æéããããå ŽåãããïŒããšãã°ã倧ããªããŒãã«ããããŒã¿ãæŽæ°ããå ŽåïŒãåæã«ãªãªãŒã¹ã®é床ãäœäžãããªãããã«ãçµã¿åããç§»è¡ã®ææ³ã䜿çšããŸãã..ããã®çµã¿åããã¯ãå®è¡äžã®ãµãŒããŒã§æåã§ç§»è¡ãå®è¡ãïŒç®¡çããã«ãä»ããŠããã©ã€ãŠã§ã€ãªãã§ããããã£ãŠç§»è¡å±¥æŽã«èšé²ããã«ïŒããµãŒããŒã®æ¬¡ã®ããŒãžã§ã³ã§åãç§»è¡ã®ãéåžžã®ãåºåãå®è¡ããããšã§æ§æãããŸãããããã®ç§»è¡ã«ã¯ã次ã®èŠä»¶ãé©çšãããŸãã
- ãŸããé·æéã®å®è¡äžã«ã¢ããªã±ãŒã·ã§ã³ããããã¯ããªãããã«äœæããå¿ èŠããããŸãïŒããã§ã®éèŠãªãã€ã³ãã¯ãDBã¬ãã«ã§é·æããã¯ãååŸããªãããšã§ãïŒããããè¡ãããã«ãç§»è¡ã®èšè¿°æ¹æ³ã«é¢ããéçºè åãã®å éšã¬ã€ãã©ã€ã³ããããŸããå°æ¥çã«ã¯ãHabréã§ãå ±æããå¯èœæ§ããããŸãã
- 次ã«ããéåžžã®ãèµ·åäžã®ç§»è¡ã§ã¯ããã§ã«æåã¢ãŒãã§å®è¡ãããŠããããšã確èªãããã®å Žåã¯äœãå®è¡ããªãã§ãã ãããå±¥æŽã«æ°ããã¬ã³ãŒããã³ãããããã ãã§ããSQLç§»è¡ã®å Žåããã®ãããªãã§ãã¯ã¯ã倿Žã«ã€ããŠSQLã¯ãšãªãå®è¡ããããšã«ãã£ãŠå®è¡ãããŸããJavaç§»è¡ã®å¥ã®ã¢ãããŒãã¯ãæåå®è¡åŸã«èšå®ãããä¿åãããããŒã«ãã©ã°ã䜿çšããããšã§ãã

ãã®ã¢ãããŒãã¯2ã€ã®åé¡ã解決ããŸãïŒ
- ãªãªãŒã¹ã¯é«éã§ãïŒæåã¢ã¯ã·ã§ã³ã§ã¯ãããŸããïŒ
- ( ) - .
ãªãªãŒã¹ããããšãéçºãµã€ã¯ã«ã¯çµäºããŸãããæ°ããæ©èœãæ©èœãããã©ããïŒããã³ã©ã®ããã«æ©èœãããïŒãçè§£ããã«ã¯ãã¡ããªãã¯ã§ãå²ããå¿ èŠããããŸãããããã¯ãããžãã¹ãšã·ã¹ãã ã®2ã€ã®ã°ã«ãŒãã«åããããšãã§ããŸãã
æåã®ã°ã«ãŒãã¯ãµããžã§ã¯ãé åã«åŒ·ãäŸåããŸããã¡ãŒã«ãµãŒããŒã®å Žåãéä¿¡ãããæåã®æ°ããã¥ãŒã¹ãªãœãŒã¹ã®å Žåã1æ¥ãããã®äžæã®ãŠãŒã¶ãŒã®æ°ãªã©ãç¥ã£ãŠãããšäŸ¿å©ã§ãã
2çªç®ã®ã°ã«ãŒãã®ã¡ããªãã¯ã¯ããµãŒããŒã®æè¡çç¶æ ïŒcpuãã¡ã¢ãªããããã¯ãŒã¯ãããŒã¿ããŒã¹ãªã©ïŒã決å®ããŸãã
æ£ç¢ºã«ç£èŠããå¿ èŠããããã®ãšãã®æ¹æ³ã¯ããã¹ãŠã®äººã«ãšã£ãŠã»ãŒåãã§ãã ããã¯ãèšå€§ãªæ°ã®åå¥ã®èšäºã®ãããã¯ã§ãããããã§ã¯è§ŠããŸãããæãåºæ¬çãªïŒãã£ããã³ã§ããïŒããšã ããæãåºããããïŒ
äºåã«ã¡ããªãã¯ãå®çŸ©ãã
åºæ¬çãªã¡ããªãã¯ã®ãªã¹ããå®çŸ©ããå¿ èŠããããŸãããŸããã·ã¹ãã ã§äœãèµ·ãã£ãŠããã®ããããããªãå Žåã¯ãæåã®ã€ã³ã·ãã³ãã®åŸã§ã¯ãªãããªãªãŒã¹åã«äºåã«è¡ãå¿ èŠããããŸãã
èªåã¢ã©ãŒããèšå®ãã
ããã«ãããåå¿æéãççž®ãããæåç£èŠã®æéãç¯çŽãããŸããçæ³çã«ã¯ããŠãŒã¶ãŒãåé¡ãæããŠããªãã«æçŽãæžãåã«ãåé¡ã«ã€ããŠç¥ã£ãŠããå¿ èŠããããŸãã
ãã¹ãŠã®ããŒãããã¡ããªãã¯ãåéãã
ãã°ã®ããã«ãã¡ããªãã¯ãå€ãããããšã¯ãããŸãããã·ã¹ãã ã®åããŒãïŒã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãããŒã¿ããŒã¹ãæ¥ç¶ããŒã©ãŒããã©ã³ãµãŒãªã©ïŒããã®ããŒã¿ã®ååšã«ããããã®ç¶æ ã®å šäœåãææ¡ã§ããå¿ èŠã«å¿ããŠãåé¡ããã°ããç¹å®ã§ããŸãã
ç°¡åãªäŸïŒWebããŒãžã®ããŒã¿ã®èªã¿èŸŒã¿ãé ããªãå§ããŸãããå€ãã®çç±ãèããããŸãïŒ
- WebãµãŒããŒãéè² è·ã«ãªããèŠæ±ãžã®å¿çã«æéãããããŸã
- SQLã¯ãšãªã®å®è¡ã«æéãããã
- ãã¥ãŒãæ¥ç¶ããŒã«ã«èç©ãããã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã鷿鿥ç¶ãåä¿¡ã§ããªã
- ãããã¯ãŒã¯ã®åé¡
- ä»ã®äœã
ææšããªããã°ãåé¡ã®æ ¹æ¬åå ãèŠã€ããã®ã¯ç°¡åã§ã¯ãããŸããã
å®äºã®ä»£ããã«
ç¹å¹è¬ããªããã©ã¡ãã®ã¢ãããŒããéžæãããã¯ç¹å®ã®ã¿ã¹ã¯ã®èŠä»¶ã«äŸåããä»ã®äººã«ãšã£ãŠããŸãããããšã¯ããªãã«ã¯åœãŠã¯ãŸããªããããããªããšããäºå®ã«ã€ããŠãéåžžã«å¹³å¡ãªèšãæ¹ãããããšæããŸããããããããªããç¥ã£ãŠããã¢ãããŒããå€ããã°å€ãã»ã©ããã®éžæããã培åºçãã€å®æ§çã«è¡ãããšãã§ããŸãããã®èšäºãããããªããå°æ¥ããªããå©ããã§ãããããªãèªèº«ã®ããã«äœãæ°ããããšãåŠãã ããšãé¡ã£ãŠããŸããããŒã¿ããŒã¹ã®æäœããã»ã¹ãæ¹åããããã«ã©ã®ãããªã¢ãããŒãã䜿çšããŠãããã«ã€ããŠã³ã¡ã³ããããŠããã ããŸãã