เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชธเซ‡เชธ

เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชธเซ‡เชธ

เช† เชฒเซ‡เช– เชœเชฎเชพเชตเชŸเชฎเชพเช‚ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชธเช‚เช—เชคเชคเชพ เชธเชฎเชธเซเชฏเชพเช“เชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช‰เช•เซ‡เชฒเชตเชพ เชคเซ‡ เชตเชฟเช—เชคเชตเชพเชฐ เชธเชฎเชœเชพเชตเซ‡ เช›เซ‡. เช…เชฎเซ‡ เชคเชฎเชจเซ‡ เชœเชฃเชพเชตเซ€เชถเซเช‚ เช•เซ‡ เชœเซ‹ เชคเชฎเซ‡ เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชคเซˆเชฏเชพเชฐเซ€ เชตเชฟเชจเชพ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเชถเซ‹ เชคเซ‹ เชคเชฎเชพเชฐเซ€ เชชเซเชฐเซ‹เชกเช•เซเชถเชจ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซเชธเชจเซเช‚ เชถเซเช‚ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡. เชชเช›เซ€ เช…เชฎเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชœเซ€เชตเชจเชšเช•เซเชฐเชจเชพ เชคเชฌเช•เซเช•เชพเช“เชฎเชพเช‚เชฅเซ€ เชชเชธเชพเชฐ เชฅเชˆเชถเซเช‚ เชœเซ‡ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ (เช†เชถเชฐเซ‡ เชฒเซ‡เชจ: เช†เช—เชณ - เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ). เช…เชฎเชพเชฐเซ€ เช•เชพเชฎเช—เซ€เชฐเซ€เชจเซเช‚ เชชเชฐเชฟเชฃเชพเชฎ เชชเชพเช›เชณเชจเซ€-เช…เชธเช‚เช—เชค เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเชจเซ‡ เชชเชพเช›เชณเชจเซ€-เชธเซเชธเช‚เช—เชค เชฐเซ€เชคเซ‡ เชฒเชพเช—เซ เช•เชฐเชตเชพเชจเซเช‚ เชนเชถเซ‡.

เชœเซ‹ เชคเชฎเซ‡ เชฒเซ‡เช–เชฎเชพเช‚เชฅเซ€ เช•เซ‹เชก เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชธเชฎเชœเชตเชพ เชฎเชพเช‚เช—เชคเชพ เชนเซ‹, เชคเซ‹ เชคเชฎเซ‡ เชคเซ‡เชจเซ‡ เช…เชนเซ€เช‚เชฅเซ€ เชถเซ‹เชงเซ€ เชถเช•เซ‹ เช›เซ‹ GitHub.

เชชเชฐเชฟเชšเชฏ

เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ

เชถเซเช‚ เชฐเชนเชธเซเชฏเชตเชพเชฆเซ€ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ? เชคเชฎเซ‡ เช† เชคเซเชฏเชพเชฐเซ‡ เช•เชนเซ€ เชถเช•เซ‹ เช›เซ‹ เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชเชตเซ€ เชฐเซ€เชคเซ‡ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช•เซ‡ เชคเชฎเซ‡ เช‰เชคเซเชชเชพเชฆเชจเชฎเชพเช‚ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เชธเชซเชณเชคเชพเชชเซ‚เชฐเซเชตเช• เชฐเชœเซ‚ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เชœเซเชฏเชพเชฐเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชคเซ‡เชจเซ€ เช…เชจเซเชชเชฒเชฌเซเชงเชคเชพเชจเซ€ เชจเซ‹เช‚เชง เชฒเซ‡เชคเซ‹ เชจเชฅเซ€. เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เช…เชจเซ‡ เช•เช‚เชชเชจเซ€เชจเชพ เชชเชฐเชฟเชชเซเชฐเซ‡เช•เซเชทเซเชฏเชฎเชพเช‚, เช† เชถเซเชฐเซ‡เชทเซเช  เชธเช‚เชญเชตเชฟเชค เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เชฆเซƒเชถเซเชฏ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชจเชตเซ€ เชธเซเชตเชฟเชงเชพเช“ เชฐเชœเซ‚ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡ เช…เชจเซ‡ เชฌเช—เซเชธเชจเซ‡ เชตเชฟเช•เซเชทเซ‡เชช เชตเชฟเชจเชพ เช เซ€เช• เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡.

เช† เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชนเชพเช‚เชธเชฒ เช•เชฐเชตเซเช‚? เชคเซเชฏเชพเช‚ เช˜เชฃเซ€ เชฐเซ€เชคเซ‹ เช›เซ‡, เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชเช• เช…เชนเซ€เช‚ เช›เซ‡:

  • เชคเชฎเชพเชฐเซ€ เชธเซ‡เชตเชพเชจเชพ เชธเช‚เชธเซเช•เชฐเชฃ เชจเช‚เชฌเชฐ 1 เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹
  • เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เช•เชฐเซ‹
  • เชธเช‚เชธเซเช•เชฐเชฃ #2 เชจเซ€ เชธเชฎเชพเช‚เชคเชฐ เชคเชฎเชพเชฐเซ€ เชธเซ‡เชตเชพเชจเชพ เชธเช‚เชธเซเช•เชฐเชฃ #1 เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹
  • เชœเชฒเชฆเซ€ เชคเชฎเซ‡ เชœเซเช“ เช•เซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชจเช‚เชฌเชฐ 2 เชคเซ‡ เชœเซ‹เชˆเช เชคเซ‡ เชชเซเชฐเชฎเชพเชฃเซ‡ เช•เชพเชฐเซเชฏ เช•เชฐเซ‡ เช›เซ‡, เชธเช‚เชธเซเช•เชฐเชฃ เชจเช‚เชฌเชฐ 1 เชฆเซ‚เชฐ เช•เชฐเซ‹
  • เชฅเชˆ เช—เชฏเซเช‚!

เชธเชฐเชณ, เชคเซ‡ เชจเชฅเซ€? เช•เชฎเชจเชธเซ€เชฌเซ‡, เชคเซ‡ เชเชŸเชฒเซเช‚ เชธเชฐเชณ เชจเชฅเซ€, เช…เชจเซ‡ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชชเช›เซ€เชฅเซ€ เชตเชฟเช—เชคเชตเชพเชฐ เชœเซ‹เชˆเชถเซเช‚. เชนเชตเซ‡ เชšเชพเชฒเซ‹ เชฌเซ€เชœเซ€ เชเช•เชฆเชฎ เชธเชพเชฎเชพเชจเซเชฏ เชœเชฎเชพเชตเชŸ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชคเชชเชพเชธเซ€เช - เชตเชพเชฆเชณเซ€ เชฒเซ€เชฒเชพ เชœเชฎเชพเชตเชŸ.

เชถเซเช‚ เชคเชฎเซ‡ เช•เซเชฏเชพเชฐเซ‡เชฏ เชธเชพเช‚เชญเชณเซเชฏเซเช‚ เช›เซ‡ เชตเชพเชฆเชณเซ€ เชฒเซ€เชฒเชพ เชœเชฎเชพเชตเชŸ? เช•เซเชฒเชพเช‰เชก เชซเชพเช‰เชจเซเชกเซเชฐเซ€ เช†เชจเซ‡ เช…เชคเซเชฏเช‚เชค เชธเชฐเชณ เชฌเชจเชพเชตเซ‡ เช›เซ‡. เชœเชฐเชพ เชœเซเช“ เช† เชฒเซ‡เช–, เชœเซเชฏเชพเช‚ เช…เชฎเซ‡ เช†เชจเซเช‚ เชตเชงเซ เชตเชฟเช—เชคเชฎเชพเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เช เช›เซ€เช. เชธเช‚เช•เซเชทเชฟเชชเซเชคเชฎเชพเช‚ เชธเชพเชฐเชพเช‚เชถ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ‹ เชคเชฎเชจเซ‡ เชฏเชพเชฆ เช…เชชเชพเชตเซ€เช เช•เซ‡ เชตเชพเชฆเชณเซ€ เชฒเซ€เชฒเซ€ เชœเชฎเชพเชตเชŸ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ€:

  • เช–เชพเชคเชฐเซ€ เช•เชฐเซ‹ เช•เซ‡ เชคเชฎเชพเชฐเชพ เช‰เชคเซเชชเชพเชฆเชจ เช•เซ‹เชกเชจเซ€ เชฌเซ‡ เชจเช•เชฒเซ‹ ("เชตเชพเชฆเชณเซ€" เช…เชจเซ‡ "เชฒเซ€เชฒเซ‹") เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡;
  • เชคเชฎเชพเชฎ เชŸเซเชฐเชพเชซเชฟเช•เชจเซ‡ เชตเชพเชฆเชณเซ€ เชตเชพเชคเชพเชตเชฐเชฃ เชคเชฐเชซ เชฆเชฟเชถเชพเชฎเชพเชจ เช•เชฐเซ‹, เชเชŸเชฒเซ‡ เช•เซ‡. เชœเซ‡เชฅเซ€ เช‰เชคเซเชชเชพเชฆเชจ URL เชคเซเชฏเชพเช‚ เชจเชฟเชฐเซเชฆเซ‡เชถ เช•เชฐเซ‡ เช›เซ‡;
  • เช—เซเชฐเซ€เชจ เชเชจเซเชตเชพเชฏเชฐเซเชจเชฎเซ‡เชจเซเชŸเชฎเชพเช‚ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชคเชฎเชพเชฎ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช…เชจเซ‡ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเซ‹;
  • เชฏเซเช†เชฐเชเชฒเชจเซ‡ เชตเชพเชฆเชณเซ€เชฎเชพเช‚เชฅเซ€ เชฒเซ€เชฒเชพ เชตเชพเชคเชพเชตเชฐเชฃเชฎเชพเช‚ เชธเซเชตเชฟเชš เช•เชฐเซ‹

เชฌเซเชฒเซ เช—เซเชฐเซ€เชจ เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เช เชเช• เช…เชญเชฟเช—เชฎ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชชเซเชฐเซ‹เชกเช•เซเชถเชจ เชฌเซเชฐเซ‡เช•เชฟเช‚เช— เชตเชฟเชถเซ‡ เชšเชฟเช‚เชคเชพ เช•เชฐเซเชฏเชพ เชตเชฟเชจเชพ เชธเชฐเชณเชคเชพเชฅเซ€ เชจเชตเซ€ เชธเซเชตเชฟเชงเชพเช“ เชฐเชœเซ‚ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เช† เช เชนเช•เซ€เช•เชคเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เช›เซ‡ เช•เซ‡ เชœเซ‹ เช•เช‚เชˆเช• เชฅเชพเชฏ เชคเซ‹ เชชเชฃ, เชคเชฎเซ‡ "เชธเซเชตเซ€เชšเชจเซ‡ เชซเซเชฒเชฟเช• เช•เชฐเซ€เชจเซ‡" เชธเชฐเชณเชคเชพเชฅเซ€ เชชเชพเช›เชฒเชพ เชตเชพเชคเชพเชตเชฐเชฃเชฎเชพเช‚ เชชเชพเช›เชพ เชซเชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เช‰เชชเชฐเซ‹เช•เซเชค เชคเชฎเชพเชฎ เชตเชพเช‚เชšเซเชฏเชพ เชชเช›เซ€, เชคเชฎเซ‡ เชชเซเชฐเชถเซเชจ เชชเซ‚เช›เซ€ เชถเช•เซ‹ เช›เซ‹: เชตเชพเชฆเชณเซ€ เชฒเซ€เชฒเชพ เชœเชฎเชพเชตเชŸ เชธเชพเชฅเซ‡ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎเชจเซ‹ เชถเซเช‚ เชธเช‚เชฌเช‚เชง เช›เซ‡?

เช เซ€เช• เช›เซ‡, เชคเซ‡เช“เชฎเชพเช‚ เช˜เชฃเซเช‚ เชธเชพเชฎเซเชฏ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชธเชฎเชพเชจ เชตเชพเชคเชพเชตเชฐเชฃเชจเซ€ เชฌเซ‡ เชจเช•เชฒเซ‹ เชœเชพเชณเชตเชตเชพ เชฎเชพเชŸเซ‡ เชคเซ‡เชฎเชจเซ‡ เชœเชพเชณเชตเชตเชพ เชฎเชพเชŸเซ‡ เชฌเชฎเชฃเชพ เชชเซเชฐเชฏเชคเซเชจเซ‹เชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเซ‡ เช›เซ‡. เช† เช•เชพเชฐเชฃเซ‡ เช•เซ‡เชŸเชฒเซ€เช• เชŸเซ€เชฎเซ‹ เชฆเชพเชตเซ‹ เช•เชฐเซ‡ เช›เซ‡ เชฎเชพเชฐเซเชŸเชฟเชจ เชซเชพเช‰เชฒเชฐ, เช† เช…เชญเชฟเช—เชฎเชจเซ€ เชตเชฟเชตเชฟเชงเชคเชพเชจเซ‡ เช…เชจเซเชธเชฐเซ‹:

เชฌเซ€เชœเซ‹ เชตเชฟเช•เชฒเซเชช เช เชœ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ‹ เช›เซ‡, เชตเซ‡เชฌ เช…เชจเซ‡ เชกเซ‹เชฎเซ‡เชจ เชธเซเชคเชฐเซ‹ เชฎเชพเชŸเซ‡ เชตเชพเชฆเชณเซ€-เชฒเซ€เชฒเชพ เชธเซเชตเซ€เชšเซ‹ เชฌเชจเชพเชตเซ€เชจเซ‡. เช† เช…เชญเชฟเช—เชฎเชฎเชพเช‚, เชกเซ‡เชŸเชพเชฌเซ‡เช เช˜เชฃเซ€เชตเชพเชฐ เชธเชฎเชธเซเชฏเชพ เชฌเชจเซ€ เชถเช•เซ‡ เช›เซ‡, เช–เชพเชธ เช•เชฐเซ€เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเชพเชฐเซ‡ เชธเซ‹เชซเซเชŸเชตเซ‡เชฐเชจเชพ เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เชธเชฎเชฐเซเชฅเชจ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡ เชคเซ‡เชจเซ€ เชธเซเช•เซ€เชฎเชพ เชฌเชฆเชฒเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ.

เช…เชจเซ‡ เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เช† เชฒเซ‡เช–เชฎเชพเช‚ เชฎเซเช–เซเชฏ เชธเชฎเชธเซเชฏเชพ เชชเชฐ เช†เชตเซ€เช เช›เซ€เช. เชกเซ‡เชŸเชพเชฌเซ‡เช. เชšเชพเชฒเซ‹ เช† เชตเชพเช•เซเชฏ เชชเชฐ เชฌเซ€เชœเซ€ เชจเชœเชฐ เช•เชฐเซ€เช.

เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เช•เชฐเซ‹.

เชนเชตเซ‡ เชคเชฎเชพเชฐเซ‡ เชคเชฎเชพเชฐเซ€ เชœเชพเชคเชจเซ‡ เชชเซเชฐเชถเซเชจ เชชเซ‚เช›เชตเซ‹ เชชเชกเชถเซ‡ - เชœเซ‹ เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เชธเซเชธเช‚เช—เชค เชจ เชนเซ‹เชฏ เชคเซ‹ เชถเซเช‚? เชถเซเช‚ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซเช‚ เชฎเชพเชฐเซเช‚ เชชเซเชฐเชฅเชฎ เชธเช‚เชธเซเช•เชฐเชฃ เชคเซ‚เชŸเซ€ เชœเชถเซ‡ เชจเชนเซ€เช‚? เชตเชพเชธเซเชคเชตเชฎเชพเช‚, เช†เชตเซเช‚ เชœ เชฅเชถเซ‡...

เชคเซ‡เชฅเซ€, เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ / เชฌเซเชฒเซ เช—เซเชฐเซ€เชจ เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸเชจเชพ เชตเชฟเชถเชพเชณ เชฒเชพเชญเซ‹ เชนเซ‹เชตเชพ เช›เชคเชพเช‚, เช•เช‚เชชเชจเซ€เช“ เชคเซ‡เชฎเชจเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซ‹ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชจเซ€เชšเซ‡เชจเซ€ เชธเซเชฐเช•เซเชทเชฟเชค เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เช…เชจเซเชธเชฐเชตเชพเชจเซเช‚ เชตเชฒเชฃ เชงเชฐเชพเชตเซ‡ เช›เซ‡:

  • เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃ เชธเชพเชฅเซ‡ เชชเซ‡เช•เซ‡เชœ เชคเซˆเชฏเชพเชฐ เช•เชฐเซ‹
  • เชšเชพเชฒเซ€ เชฐเชนเซ‡เชฒ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชฌเช‚เชง เช•เชฐเซ‹
  • เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹ เชšเชฒเชพเชตเซ‹
  • เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซเช‚ เชจเชตเซเช‚ เชตเชฐเซเชเชจ เชœเชฎเชพเชตเชตเซเช‚ เช…เชจเซ‡ เชฒเซ‹เชจเซเชš เช•เชฐเชตเซเช‚

เช† เชฒเซ‡เช–เชฎเชพเช‚, เช…เชฎเซ‡ เชตเชฟเช—เชค เช†เชชเซ€เชถเซเช‚ เช•เซ‡ เชคเชฎเซ‡ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸเชจเซ‹ เชฒเชพเชญ เชฒเซ‡เชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเชพ เชกเซ‡เชŸเชพเชฌเซ‡เช เช…เชจเซ‡ เช•เซ‹เชก เชธเชพเชฅเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฐเซเชฏ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเชฎเชธเซเชฏเชพเช“

เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชธเซเชŸเซ‡เชŸเชฒเซ‡เชธ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช›เซ‡ เชœเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเชคเซ€ เชจเชฅเซ€, เชคเซ‹ เชคเชฎเซ‡ เชคเชฐเชค เชœ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เชฎเซ‡เชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹. เช•เชฎเชจเชธเซ€เชฌเซ‡, เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เชธเซ‹เชซเซเชŸเชตเซ‡เชฐเชจเซ‡ เช•เซเชฏเชพเช‚เช• เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เช†เชฅเซ€ เชคเชฎเชพเชฐเซ‡ เชธเชฐเซเช•เชฟเชŸเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชซเซ‡เชฐเชซเชพเชฐ เช•เชฐเชคเชพ เชชเชนเซ‡เชฒเชพ เชฌเซ‡ เชตเชพเชฐ เชตเชฟเชšเชพเชฐเชตเซเช‚ เชœเซ‹เชˆเช. เชธเซเช•เซ€เชฎเชพ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชตเซ€ เชคเซ‡เชจเซ€ เชตเชฟเช—เชคเซ‹เชฎเชพเช‚ เชชเซเชฐเชตเซ‡เชถเชคเชพ เชชเชนเซ‡เชฒเชพ, เชœเซ‡เชฅเซ€ เชจเซ‹-เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เชถเช•เซเชฏ เชฌเชจเซ‡, เชšเชพเชฒเซ‹ เชชเชนเซ‡เชฒเชพ เชตเชฐเซเชเชจเชฟเช‚เช— เชธเซเช•เซ€เชฎเชพ เชชเชฐ เชงเซเชฏเชพเชจ เช•เซ‡เชจเซเชฆเซเชฐเชฟเชค เช•เชฐเซ€เช.

เชธเช‚เชธเซเช•เชฐเชฃ เชฏเซ‹เชœเชจเชพ

เช† เชฒเซ‡เช–เชฎเชพเช‚ เช†เชชเชฃเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚ เชซเซเชฒเชพเชฏเชตเซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชจเชฟเชฏเช‚เชคเซเชฐเชฃ เชธเชพเชงเชจ เชคเชฐเซ€เช•เซ‡ (เช†เชถเชฐเซ‡ เช…เชจเซเชตเชพเชฆ: เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เชตเชฟเชถเซ‡ เชตเชพเชค เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช). เชธเซเชตเชพเชญเชพเชตเชฟเช• เชฐเซ€เชคเซ‡, เช…เชฎเซ‡ เชธเซเชชเซเชฐเชฟเช‚เช— เชฌเซ‚เชŸ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชชเชฃ เชฒเช–เซ€เชถเซเช‚ เชœเซ‡ เชฌเชฟเชฒเซเชŸ-เช‡เชจ เชซเซเชฒเชพเชฏเชตเซ‡ เชธเชชเซ‹เชฐเซเชŸ เชงเชฐเชพเชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชฆเชฐเซเชญ เชธเซ‡เชŸ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชธเซเช•เซ€เชฎเชพ เชธเซเชฅเชณเชพเช‚เชคเชฐ เช•เชฐเชถเซ‡. เชซเซเชฒเชพเชฏเชตเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, เชคเชฎเซ‡ เชคเชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชซเซ‹เชฒเซเชกเชฐเชฎเชพเช‚ เชธเซเชฅเชณเชพเช‚เชคเชฐ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซเชธ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ (เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ classpath:db/migration). เช…เชนเซ€เช‚ เชคเชฎเซ‡ เช†เชตเซ€ เชธเซเชฅเชณเชพเช‚เชคเชฐ เชซเชพเช‡เชฒเซ‹เชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹

โ””โ”€โ”€ db
 โ””โ”€โ”€ migration
     โ”œโ”€โ”€ V1__init.sql
     โ”œโ”€โ”€ V2__Add_surname.sql
     โ”œโ”€โ”€ V3__Final_migration.sql
     โ””โ”€โ”€ V4__Remove_lastname.sql

เช† เช‰เชฆเชพเชนเชฐเชฃเชฎเชพเช‚ เช†เชชเชฃเซ‡ 4 เชธเซเชฅเชณเชพเช‚เชคเชฐ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹ เชœเซ‹เชˆเช เช›เซ€เช เชœเซ‡, เชœเซ‹ เช…เช—เชพเช‰ เชเช•เซเชเชฟเช•เซเชฏเซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชจ เชนเซ‹เชฏ, เชคเซ‹ เชœเซเชฏเชพเชฐเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชถเชฐเซ‚ เชฅเชถเซ‡ เชคเซเชฏเชพเชฐเซ‡ เชเช• เชชเช›เซ€ เชเช• เชšเชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชšเชพเชฒเซ‹ เชเช• เชซเชพเชˆเชฒเซ‹ เชœเซ‹เชˆเช (V1__init.sql) เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡.

CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

เชฌเชงเซเช‚ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชธเซเชต-เชธเซเชชเชทเซเชŸเซ€เช•เชฐเชฃ เช›เซ‡: เชคเชฎเซ‡ เชคเชฎเชพเชฐเชพ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชธเช‚เชถเซ‹เชงเชฟเชค เช•เชฐเชตเซเช‚ เชœเซ‹เชˆเช เชคเซ‡ เชตเซเชฏเชพเช–เซเชฏเชพเชฏเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ SQL เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹. เชธเซเชชเซเชฐเชฟเช‚เช— เชฌเซ‚เชŸ เช…เชจเซ‡ เชซเซเชฒเชพเชฏเชตเซ‡ เชตเชฟเชถเซ‡ เชตเชงเซ เชฎเชพเชนเชฟเชคเซ€ เชฎเชพเชŸเซ‡, เชคเชชเชพเชธเซ‹ เชตเชธเช‚เชค เชฌเซเชŸ เชกเซ‰เช•เซเชธ.

เชธเซเชชเซเชฐเชฟเช‚เช— เชฌเซ‚เชŸ เชธเชพเชฅเซ‡ เชธเซเชคเซเชฐเซ‹เชค เชจเชฟเชฏเช‚เชคเซเชฐเชฃ เชธเชพเชงเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡, เชคเชฎเชจเซ‡ 2 เชฎเซ‹เชŸเชพ เชฒเชพเชญเซ‹ เชฎเชณเซ‡ เช›เซ‡:

  • เชคเชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซ‡ เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹เชฅเซ€ เช…เชฒเช— เช•เชฐเซ‹ เช›เซ‹
  • เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชฐเซ‹เชฒเช†เช‰เชŸ เชธเชพเชฅเซ‡ เชฅเชพเชฏ เช›เซ‡, เชเชŸเชฒเซ‡ เช•เซ‡. เชคเชฎเชพเชฐเซ€ เชœเชฎเชพเชตเชŸ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชธเชฐเชณ เช›เซ‡

เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเชฎเชธเซเชฏเชพเช“เชจเซเช‚ เชจเชฟเชตเชพเชฐเชฃ

เชฒเซ‡เช–เชจเชพ เช†เช—เชฒเชพ เชตเชฟเชญเชพเช—เชฎเชพเช‚, เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฎเชพเชŸเซ‡เชจเชพ เชฌเซ‡ เช…เชญเชฟเช—เชฎเซ‹ เชชเชฐ เชงเซเชฏเชพเชจ เช•เซ‡เชจเซเชฆเซเชฐเชฟเชค เช•เชฐเซ€เชถเซเช‚.

  • เชชเช›เชพเชค เช…เชธเช‚เช—เชคเชคเชพ
  • เชชเช›เชพเชค เชธเซเชธเช‚เช—เชคเชคเชพ

เชชเซเชฐเชฅเชฎ เชšเซ‡เชคเชตเชฃเซ€ เชคเชฐเซ€เช•เซ‡ เช—เชฃเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เช•เซ‡ เชคเชฎเชพเชฐเซ‡ เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชคเซˆเชฏเชพเชฐเซ€ เชตเชฟเชจเชพ เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เช•เชฐเชตเซ€ เชœเซ‹เชˆเช เชจเชนเซ€เช‚... เชฌเซ€เชœเซ‹ เชเช• เช‰เช•เซ‡เชฒ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ เชคเชฎเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชตเชฟเชจเชพ เชœเชฎเชพเชตเชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชคเซ‡ เชœ เชธเชฎเชฏเซ‡ เชชเช›เชพเชค เชธเซเชธเช‚เช—เชคเชคเชพ เชœเชพเชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹.

เช…เชฎเชพเชฐเซ‹ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เช…เชฎเซ‡ เชœเซ‡เชจเชพ เชชเชฐ เช•เชพเชฎ เช•เชฐเซ€เชถเซเช‚ เชคเซ‡ เชเช• เชธเชฐเชณ เชธเซเชชเซเชฐเชฟเช‚เช— เชฌเซ‚เชŸ เชซเซเชฒเชพเชฏเชตเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชนเชถเซ‡ เชœเซ‡เชฎเชพเช‚ เช›เซ‡ Person ั first_name ะธ last_name เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ (เช†เชถเชฐเซ‡ เช…เชจเซเชตเชพเชฆ: Person เชเช• เชŸเซ‡เชฌเชฒ เช›เซ‡ เช…เชจเซ‡ เชเชซirst_name ะธ last_name - เช† เชคเซ‡เชฎเชพเช‚เชจเชพ เช•เซเชทเซ‡เชคเซเชฐเซ‹ เช›เซ‡). เช…เชฎเซ‡ เชจเชพเชฎ เชฌเชฆเชฒเชตเชพ เชฎเชพเช‚เช—เซ€เช เช›เซ€เช last_name ะฒ surname.

เชงเชพเชฐเชฃเชพ

เช…เชฎเซ‡ เชตเชฟเช—เชคเซ‹เชฎเชพเช‚ เชชเซเชฐเชตเซ‡เชถเชคเชพ เชชเชนเซ‡เชฒเชพ, เช…เชฎเชพเชฐเซ€ เช…เชฐเชœเซ€เช“ เชตเชฟเชถเซ‡ เช…เชฎเชพเชฐเซ‡ เช•เซ‡เชŸเชฒเซ€เช• เชงเชพเชฐเชฃเชพเช“ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เช…เชฎเซ‡ เชœเซ‡ เชฎเซเช–เซเชฏ เชชเชฐเชฟเชฃเชพเชฎ เชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ€เช เช›เซ€เช เชคเซ‡ เชเช•เชฆเชฎ เชธเชฐเชณ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชนเชถเซ‡.

เชจเซ‹เช‚เชง. เชตเซเชฏเชตเชธเชพเชฏ เชชเซเชฐเซ‹-เชŸเซ€เชช. เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“เชจเซ‡ เชธเชฐเชณ เชฌเชจเชพเชตเชตเชพเชฅเซ€ เชคเชฎเซ‡ เชธเชชเซ‹เชฐเซเชŸ เชชเชฐ เช˜เชฃเชพ เชชเซˆเชธเชพ เชฌเชšเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹ (เชคเชฎเซ‡ เชคเชฎเชพเชฐเซ€ เช•เช‚เชชเชจเซ€ เชฎเชพเชŸเซ‡ เชœเซ‡เชŸเชฒเชพ เชตเชงเซ เชฒเซ‹เช•เซ‹ เช•เชพเชฎ เช•เชฐเชถเซ‹, เชคเซ‡เชŸเชฒเชพ เชตเชงเซ เชชเซˆเชธเชพ เชคเชฎเซ‡ เชฌเชšเชพเชตเซ€ เชถเช•เชถเซ‹)!

เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€

เช† เชœเชฎเชพเชตเชŸ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชธเชฐเชณ เชฌเชจเชพเชตเซ‡ เช›เซ‡ (เช•เซ‡เชŸเชฒเชพเช• เชกเซ‡เชŸเชพเชฌเซ‡เช เชฐเซ‹เชฒเชฌเซ‡เช• เชฒเช—เชญเช— เช…เชถเช•เซเชฏ เช›เซ‡, เชœเซ‡เชฎ เช•เซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚ เชฐเซ‹เชฒเชฌเซ‡เช•). เช…เชฎเซ‡ เชซเช•เซเชค เชเชชเซเชฒเชฟเช•เซ‡เชถเช‚เชธเชจเซ‡ เชฐเซ‹เชฒ เชฌเซ‡เช• เช•เชฐเชตเชพเชจเซเช‚ เชชเชธเช‚เชฆ เช•เชฐเซ€เช เช›เซ€เช. เช† เชฐเซ€เชคเซ‡, เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช…เชฒเช— เช…เชฒเช— เชกเซ‡เชŸเชพเชฌเซ‡เช เชนเซ‹เชฏ เชคเซ‹ เชชเชฃ (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, SQL เช…เชจเซ‡ NoSQL), เชคเชฎเชพเชฐเซ€ เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชธเชฎเชพเชจ เชฆเซ‡เช–เชพเชถเซ‡.

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชเช• เชตเชฐเซเชเชจ เชชเชพเช›เซเช‚ เชฐเซ‹เชฒ เชฌเซ‡เช• เช•เชฐเชตเซเช‚ เชนเช‚เชฎเซ‡เชถเชพ เชถเช•เซเชฏ เชนเซ‹เชตเซเช‚ เชœเซ‹เชˆเช (เชตเชงเซ เชจเชนเซ€เช‚)

เชœเซเชฏเชพเชฐเซ‡ เชœเชฐเซ‚เชฐเซ€ เชนเซ‹เชฏ เชคเซเชฏเชพเชฐเซ‡ เชœ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเชตเซเช‚ เชœเซ‹เชˆเช. เชœเซ‹ เชตเชฐเซเชคเชฎเชพเชจ เชธเช‚เชธเซเช•เชฐเชฃเชฎเชพเช‚ เช•เซ‹เชˆ เชญเซ‚เชฒ เช›เซ‡ เชœเซ‡ เชธเชฐเชณเชคเชพเชฅเซ€ เชธเซเชงเชพเชฐเซ‡เชฒ เชจเชฅเซ€, เชคเซ‹ เช…เชฎเซ‡ เชจเชตเซ€เชจเชคเชฎ เช•เชพเชฐเซเชฏเช•เชพเชฐเซ€ เชธเช‚เชธเซเช•เชฐเชฃ เชชเชฐ เชชเชพเช›เชพ เชซเชฐเชตเชพ เชธเช•เซเชทเชฎ เชนเซ‹เชตเชพ เชœเซ‹เชˆเช. เช…เชฎเซ‡ เชงเชพเชฐเซ€เช เช›เซ€เช เช•เซ‡ เช† เชจเชตเซ€เชจเชคเชฎ เช•เชพเชฐเซเชฏเช•เชพเชฐเซ€ เชธเช‚เชธเซเช•เชฐเชฃ เช…เช—เชพเช‰เชจเซเช‚ เช›เซ‡. เชเช• เช•เชฐเชคเชพเช‚ เชตเชงเซ เชฐเซ‹เชฒเช†เช‰เชŸ เชฎเชพเชŸเซ‡ เช•เซ‹เชก เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชธเช‚เช—เชคเชคเชพ เชœเชพเชณเชตเชตเซ€ เช…เชคเซเชฏเช‚เชค เชฎเซเชถเซเช•เซ‡เชฒ เช…เชจเซ‡ เช–เชฐเซเชšเชพเชณ เชนเชถเซ‡.

เชจเซ‹เช‚เชง. เชตเชงเซ เชตเชพเช‚เชšเชจเช•เซเชทเชฎเชคเชพ เชฎเชพเชŸเซ‡, เช† เชฒเซ‡เช–เชฎเชพเช‚ เช…เชฎเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชฎเซเช–เซเชฏ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เชฌเชฆเชฒเซ€เชถเซเช‚.

เชชเช—เชฒเซเช‚ 1: เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชธเซเชฅเชฟเชคเชฟ

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ: 1.0.0
DB เชธเช‚เชธเซเช•เชฐเชฃ: v1

เชŸเชฟเชชเซเชชเชฃเซ€

เช† เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชธเซเชฅเชฟเชคเชฟ เชนเชถเซ‡.

เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹

DB เชธเชฎเชพเชตเซ‡ เช›เซ‡ last_name.

CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเซเชฏเช•เซเชคเชฟเชจเชพ เชกเซ‡เชŸเชพเชจเซ‡ เชคเซ‡เชฎเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเซ‡ เช›เซ‡ last_name:

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastname) {
        this.lastName = lastname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
                + "]";
    }
}

เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เช…เชธเช‚เช—เชค เช•เซ‰เชฒเชฎเชจเซเช‚ เชจเชพเชฎ เชฌเชฆเชฒเชตเซเช‚

เชšเชพเชฒเซ‹ เช•เซ‰เชฒเชฎเชจเซเช‚ เชจเชพเชฎ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชตเซเช‚ เชคเซ‡เชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เชœเซ‹เชˆเช:

เชงเซเชฏเชพเชจ. เชจเซ€เชšเซ‡เชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เช‡เชฐเชพเชฆเชพเชชเซ‚เชฐเซเชตเช• เชตเชธเซเชคเซเช“เชจเซ‡ เชคเซ‹เชกเซ€ เชจเชพเช–เชถเซ‡. เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชธเช‚เช—เชคเชคเชพเชจเซ€ เชธเชฎเชธเซเชฏเชพเชจเซ‡ เชฆเชฐเซเชถเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช† เชฌเชคเชพเชตเซ€เช เช›เซ€เช.

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ: 2.0.0.BAD

DB เชธเช‚เชธเซเช•เชฐเชฃ: v2bad

เชŸเชฟเชชเซเชชเชฃเซ€

เชตเชฐเซเชคเชฎเชพเชจ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช…เชฎเชจเซ‡ เชเช• เชœ เชธเชฎเชฏเซ‡ เชฌเซ‡ เช‰เชฆเชพเชนเชฐเชฃเซ‹ (เชœเซ‚เชจเชพ เช…เชจเซ‡ เชจเชตเชพ) เชšเชฒเชพเชตเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชคเชพ เชจเชฅเซ€. เช†เชฎ, เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เชนเชพเช‚เชธเชฒ เช•เชฐเชตเซ€ เชฎเซเชถเซเช•เซ‡เชฒ เชนเชถเซ‡ (เชœเซ‹ เชงเชพเชฐเชฃเชพเช“เชจเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡, เชคเซ‹ เชคเซ‡ เช–เชฐเซ‡เช–เชฐ เช…เชถเช•เซเชฏ เช›เซ‡).

A/B เชชเชฐเซ€เช•เซเชทเชฃ

เชตเชฐเซเชคเชฎเชพเชจ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เช เช›เซ‡ เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ เช›เซ‡ 1.0.0, เช‰เชคเซเชชเชพเชฆเชจ เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เชคเซˆเชจเชพเชค v1. เช…เชฎเชพเชฐเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ, เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‹ เชฌเซ€เชœเซ‹ เชฆเชพเช–เชฒเซ‹ เชœเชฎเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ 2.0.0.BAD, เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‹ v2bad.

เชชเช—เชฒเชพเช‚:

  1. เชธเช‚เชธเซเช•เชฐเชฃ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‹ เชจเชตเซ‹ เชฆเชพเช–เชฒเซ‹ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เช›เซ‡ 2.0.0.BADเชœเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡ v2bad
  2. เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ v2bad เช• columnเชฒเชฎ last_name เชนเชตเซ‡ เช…เชธเซเชคเชฟเชคเซเชตเชฎเชพเช‚ เชจเชฅเซ€ - เชคเซ‡ เชฌเชฆเชฒเชพเชˆ เช—เชฏเซเช‚ เชนเชคเซเช‚ surname
  3. เชกเซ‡เชŸเชพเชฌเซ‡เช เช…เชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช…เชชเชกเซ‡เชŸ เชธเชซเชณ เชฅเชฏเซเช‚ เช…เชจเซ‡ เช•เซ‡เชŸเชฒเชพเช• เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชšเชพเชฒเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡ 1.0.0, เช…เชจเซเชฏ - เชฎเชพเช‚ 2.0.0.BAD. เชฌเชงเซเช‚ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒ เช›เซ‡ v2bad
  4. เชธเช‚เชธเซเช•เชฐเชฃเชจเชพ เชคเชฎเชพเชฎ เช‰เชฆเชพเชนเชฐเชฃเซ‹ 1.0.0 เชญเซ‚เชฒเซ‹ เชซเซ‡เช‚เช•เชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเชถเซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡เช“ เช•เซ‰เชฒเชฎเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชฆเชพเช–เชฒ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเชถเซ‡ last_nameเชœเซ‡เช“ เชนเชตเซ‡ เช…เชธเซเชคเชฟเชคเซเชตเชฎเชพเช‚ เชจเชฅเซ€
  5. เชธเช‚เชธเซเช•เชฐเชฃเชจเชพ เชคเชฎเชพเชฎ เช‰เชฆเชพเชนเชฐเชฃเซ‹ 2.0.0.BAD เชธเชฎเชธเซเชฏเชพ เชตเชฟเชจเชพ เช•เชพเชฎ เช•เชฐเชถเซ‡

เชœเซ‡เชฎ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เชœเซ‹ เช†เชชเชฃเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เช…เชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชฎเชพเช‚ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเซ€เช, เชคเซ‹ A/B เชชเชฐเซ€เช•เซเชทเชฃ เช…เชถเช•เซเชฏ เช›เซ‡.

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฐเซ‹เชฒเชฌเซ‡เช•

เชšเชพเชฒเซ‹ เชงเชพเชฐเซ€เช เช•เซ‡ A/B เชœเชฎเชพเชตเชŸ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซเชฏเชพ เชชเช›เซ€ (เช†เชถเชฐเซ‡ เชชเซเชฐเชคเชฟ.: เชฒเซ‡เช–เช•เชจเซ‹ เช…เชฐเซเชฅ เช•เชฆเชพเชš เช…เชนเซ€เช‚ A/B เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชจเซ‹ เช›เซ‡) เช…เชฎเซ‡ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เช•เซ‡ เช…เชฎเชพเชฐเซ‡ เชเชชเซเชฒเซ€เช•เซ‡เชถเชจเชจเซ‡ เชตเชฐเซเชเชจ เชชเชฐ เชชเชพเช›เซเช‚ เชซเซ‡เชฐเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ 1.0.0. เชšเชพเชฒเซ‹ เช•เชนเซ€เช เช•เซ‡ เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเชตเชพ เชฎเชพเช‚เช—เชคเชพ เชจเชฅเซ€.

เชชเช—เชฒเชพเช‚:

  1. เช…เชฎเซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฆเชพเช–เชฒเชพเชจเซ‡ เชฌเช‚เชง เช•เชฐเซ€เช เช›เซ€เช 2.0.0.BAD
  2. เชกเซ‡เชŸเชพเชฌเซ‡เช เชนเชœเซ เชชเชฃ เช›เซ‡ v2bad
  3. เช†เชตเซƒเชคเซเชคเชฟ เชฅเซ€ 1.0.0 เชคเซ‡ เชถเซเช‚ เช›เซ‡ เชคเซ‡ เชธเชฎเชœเชพเชคเซเช‚ เชจเชฅเซ€ surname, เช†เชชเชฃเซ‡ เชญเซ‚เชฒเซ‹ เชœเซ‹เชถเซเช‚
  4. เชจเชฐเช• เช›เซ‚เชŸเซ€ เช—เชฏเซ‹ เช›เซ‡, เช…เชฎเซ‡ เชนเชตเซ‡ เชชเชพเช›เชพ เชœเชˆ เชถเช•เชคเชพ เชจเชฅเซ€

เชœเซ‡เชฎ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เชœเซ‹ เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เช…เชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชฎเชพเช‚ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเซ€เช เช›เซ€เช, เชคเซ‹ เช…เชฎเซ‡ เชชเชพเช›เชฒเชพ เชธเช‚เชธเซเช•เชฐเชฃ เชชเชฐ เชชเชพเช›เชพ เชซเชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€.

เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชเช•เซเชเซ‡เช•เซเชฏเซเชถเชจ เชฒเซ‹เช—เซเชธ

Backward incompatible scenario:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0.BAD
05) Wait for the app (2.0.0.BAD) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0 <-- this should fail
07) Generate a person by calling POST localhost:9992/person to version 2.0.0.BAD <-- this should pass

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}

Starting app in version 2.0.0.BAD
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

curl: (22) The requested URL returned error: 500 Internal Server Error

Generate a person in version 2.0.0.BAD
Sending a post to 127.0.0.1:9995/person. This is the response:

{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}

เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชธเซเชฅเชณเชพเช‚เชคเชฐ เชธเซเช•เซเชฐเชฟเชชเซเชŸ เช•เซ‡ เชœเซ‡ เชจเชพเชฎ เชฌเชฆเชฒเชพเชฏ เช›เซ‡ last_name ะฒ surname

เชธเซเชคเซเชฐเซ‹เชค เชซเซเชฒเชพเชฏเชตเซ‡ เชธเซเช•เซเชฐเชฟเชชเซเชŸ:

CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

เชจเชพเชฎ เชฌเชฆเชฒเชคเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸ last_name.

-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;

เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹

เช…เชฎเซ‡ เช•เซเชทเซ‡เชคเซเชฐเชจเซเช‚ เชจเชพเชฎ เชฌเชฆเชฒเซเชฏเซเช‚ เช›เซ‡ lastName เชชเชฐ surname.

เชชเชพเช›เชณเชจเซ€-เชธเซเชธเช‚เช—เชค เชฐเซ€เชคเซ‡ เช•เซ‰เชฒเชฎเชจเซเช‚ เชจเชพเชฎ เชฌเชฆเชฒเชตเซเช‚

เช† เชธเซŒเชฅเซ€ เชธเชพเชฎเชพเชจเซเชฏ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เช›เซ‡ เชœเซ‡เชจเซ‹ เช†เชชเชฃเซ‡ เชธเชพเชฎเชจเซ‹ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. เช†เชชเชฃเซ‡ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เช…เชฎเซ‡ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชธเชพเชฌเชฟเชค เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เช•เซ‡ เชถเซ‚เชจเซเชฏ-เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เชฎเชพเชŸเซ‡, เช†เชชเชฃเซ‡ เชตเชงเชพเชฐเชพเชจเชพ เชชเช—เชฒเชพเช‚ เชตเชฟเชจเชพ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฃเชจเซ‡ เชซเช•เซเชค เชฒเชพเช—เซ เชจ เช•เชฐเชตเซเช‚ เชœเซ‹เชˆเช. เชฒเซ‡เช–เชจเชพ เช† เชตเชฟเชญเชพเช—เชฎเชพเช‚, เช…เชฎเซ‡ เชชเช›เชพเชค เชธเซเชธเช‚เช—เชคเชคเชพ เชœเชพเชณเชตเซ€ เชฐเชพเช–เซ€เชจเซ‡ เช‡เชšเซเช›เชฟเชค เชชเชฐเชฟเชฃเชพเชฎ เชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เชธเชพเชฅเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ 3 เชœเชฎเชพเชตเชŸ เช•เชฐเซ€เชถเซเช‚.

เชจเซ‹เช‚เชง. เชฏเชพเชฆ เช•เชฐเซ‹ เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชตเชฐเซเชเชจ เชกเซ‡เชŸเชพเชฌเซ‡เช เช›เซ‡ v1. เชคเซ‡เชฎเชพเช‚ เช•เซ‰เชฒเชฎ เช›เซ‡ first_name ะธ last_name. เช†เชชเชฃเซ‡ เชฌเชฆเชฒเชตเซเช‚ เชชเชกเชถเซ‡ last_name เชชเชฐ surname. เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชเชช เชตเชฐเซเชเชจ เชชเชฃ เช›เซ‡ 1.0.0, เชœเซ‡เชจเซ‹ เชนเชœเซ เช‰เชชเชฏเซ‹เช— เชฅเชฏเซ‹ เชจเชฅเซ€ surname.

เชชเช—เชฒเซเช‚ 2: เช…เชŸเช• เช‰เชฎเซ‡เชฐเซ‹

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ: 2.0.0
DB เชธเช‚เชธเซเช•เชฐเชฃ: v2

เชŸเชฟเชชเซเชชเชฃเซ€

เชจเชตเซ€ เช•เซ‰เชฒเชฎ เช‰เชฎเซ‡เชฐเซ€เชจเซ‡ เช…เชจเซ‡ เชคเซ‡เชจเชพ เชธเชฎเชพเชตเชฟเชทเซเชŸเซ‹เชจเซ€ เชจเช•เชฒ เช•เชฐเซ€เชจเซ‡, เช…เชฎเซ‡ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เชธเซเชธเช‚เช—เชค เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฌเชจเชพเชตเซ€เช เช›เซ€เช. เชคเซ‡ เชœ เชธเชฎเชฏเซ‡, เชœเซ‹ เช†เชชเชฃเซ‡ JAR เชจเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเซ€เช เช…เชฅเชตเชพ เชœเซ‚เชจเซ€ JAR เชšเชพเชฒเซ€ เชฐเชนเซ€ เชนเซ‹เชฏ, เชคเซ‹ เชคเซ‡ เช…เชฎเชฒ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชคเซ‚เชŸเซ€ เชœเชถเซ‡ เชจเชนเซ€เช‚.

เช…เชฎเซ‡ เชเช• เชจเชตเซเช‚ เชธเช‚เชธเซเช•เชฐเชฃ เชฐเชœเซ‚ เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชชเช—เชฒเชพเช‚:

  1. เชจเชตเซ€ เช•เซ‰เชฒเชฎ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชณเชพเช‚เชคเชฐ เช•เชฐเซ‹ surname. เชนเชตเซ‡ เชคเชฎเชพเชฐเซเช‚ DB เชธเช‚เชธเซเช•เชฐเชฃ v2
  2. เชจเชพ เชกเซ‡เชŸเชพเชจเซ€ เชจเช•เชฒ เช•เชฐเซ‹ last_name ะฒ surname. เชงเซเชฏเชพเชจ เช†เชชเซ‹เช•เซ‡ เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช†เชŸเชฒเซ‹ เช˜เชฃเซ‹ เชกเซ‡เชŸเชพ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเชพเชฐเซ‡ เชฌเซ‡เชš เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฃเชจเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเซเช‚ เชœเซ‹เชˆเช!
  3. เช•เซ‹เชก เชฒเช–เซ‹ เชœเซเชฏเชพเช‚ เชคเซ‡เช“ เชตเชชเชฐเชพเชฏ เช›เซ‡ เชฌเช‚เชจเซ‡ ะธ ะฝะพะฒั‹ะนเช…เชจเซ‡ เชตเซƒเชฆเซเชง เช•เซ‰เชฒเชฎ เชนเชตเซ‡ เชคเชฎเชพเชฐเซเช‚ เชเชช เชตเชฐเซเชเชจ 2.0.0
  4. เช•เซ‰เชฒเชฎเชฎเชพเช‚เชฅเซ€ เชฎเซ‚เชฒเซเชฏ เชตเชพเช‚เชšเซ‹ surname, เชœเซ‹ เชคเซ‡ เชจเชฅเซ€ null, เช…เชฅเชตเชพ l เชฅเซ€ast_nameเชœเซ‹ surname เช‰เชฒเซเชฒเซ‡เช– เชจเชฅเซ€. เชคเชฎเซ‡ เช•เชพเชขเซ€ เชถเช•เซ‹ เช›เซ‹ getLastName() เช•เซ‹เชกเชฎเชพเช‚เชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เช†เช‰เชŸเชชเซเชŸ เช•เชฐเชถเซ‡ null เชœเซเชฏเชพเชฐเซ‡ เชฅเซ€ เชคเชฎเชพเชฐเซ€ เช…เชฐเชœเซ€ เชชเชพเช›เซ€ เช–เซ‡เช‚เชšเซ‹ 3.0.0 เชฎเชพเชŸเซ‡ 2.0.0.

เชœเซ‹ เชคเชฎเซ‡ เชธเซเชชเซเชฐเชฟเช‚เช— เชฌเซ‚เชŸ เชซเซเชฒเชพเชฏเชตเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ‹, เชคเซ‹ เช† เชฌเซ‡ เชชเช—เชฒเชพเช‚ เชตเชฐเซเชเชจ เชธเซเชŸเชพเชฐเซเชŸเช…เชช เชฆเชฐเชฎเชฟเชฏเชพเชจ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ 2.0.0 เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซเชธ เชœเซ‹ เชคเชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชตเชฐเซเชเชจเชฟเช‚เช— เชŸเซ‚เชฒ เชฎเซ‡เชจเซเชฏเซเช…เชฒเซ€ เชšเชฒเชพเชตเซ‹ เช›เซ‹, เชคเซ‹ เชคเชฎเชพเชฐเซ‡ เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฌเซ‡ เช…เชฒเช—-เช…เชฒเช— เชตเชธเซเชคเซเช“ เช•เชฐเชตเซ€ เชชเชกเชถเซ‡ (เชชเชนเซ‡เชฒเชพ เชกเซ€เชฌเซ€ เชตเชฐเซเชเชจเชจเซ‡ เชฎเซ‡เชจเซเชฏเซเช…เชฒเซ€ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‹ เช…เชจเซ‡ เชชเช›เซ€ เชจเชตเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹).

เชคเซ‡ เชฎเชนเชคเซเชตเชจเซเช‚ เช›เซ‡. เชฏเชพเชฆ เชฐเชพเช–เซ‹ เช•เซ‡ เชจเชตเซ€ เชฌเชจเชพเชตเซ‡เชฒเซ€ เช•เซ‰เชฒเชฎ เชจ เชœเซ‹เชˆเช เชนเซ‹เชˆ เชจเชฅเซ€. เชœเซ‹ เชคเชฎเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเซ‹ เช›เซ‹, เชคเซ‹ เชœเซ‚เชจเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชจเชตเซ€ เช•เซ‰เชฒเชฎ เชตเชฟเชถเซ‡ เชœเชพเชฃเชคเซ€ เชจเชฅเซ€ เช…เชจเซ‡ เชคเซ‡ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชคเซ‡เชจเซ‡ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชถเซ‡ เชจเชนเซ€เช‚ Insert. เชชเชฐเช‚เชคเซ เชœเซ‹ เชคเชฎเซ‡ เช† เช…เชตเชฐเซ‹เชง เช‰เชฎเซ‡เชฐเชถเซ‹ เช…เชจเซ‡ เชคเชฎเชพเชฐเซเช‚ เชกเซ€เชฌเซ€ เชนเชถเซ‡ v2, เช†เชจเซ‡ เชจเชตเซ€ เช•เซ‰เชฒเชฎเชจเซ€ เช•เชฟเช‚เชฎเชค เชธเซ‡เชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเชถเซ‡. เชœเซ‡ เชชเซเชฐเชคเชฟเชฌเช‚เชงเซ‹เชจเชพ เช‰เชฒเซเชฒเช‚เช˜เชจ เชคเชฐเชซ เชฆเซ‹เชฐเซ€ เชœเชถเซ‡.

เชคเซ‡ เชฎเชนเชคเซเชตเชจเซเช‚ เช›เซ‡. เชคเชฎเชพเชฐเซ‡ เชชเชฆเซเชงเชคเชฟ เชฆเซ‚เชฐ เช•เชฐเชตเซ€ เชœเซ‹เชˆเช getLastName(), เช•เชพเชฐเชฃ เช•เซ‡ เชธเช‚เชธเซเช•เชฐเชฃเชฎเชพเช‚ 3.0.0 เช•เซ‹เชกเชฎเชพเช‚ เช•เซ‰เชฒเชฎเชจเซ‹ เช•เซ‹เชˆ เช–เซเชฏเชพเชฒ เชจเชฅเซ€ last_name. เช†เชจเซ‹ เช…เชฐเซเชฅ เช เช›เซ‡ เช•เซ‡ เชคเซเชฏเชพเช‚ เชจเชฒ เชธเซ‡เชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชคเชฎเซ‡ เชชเชฆเซเชงเชคเชฟ เช›เซ‹เชกเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชฎเชพเชŸเซ‡ เชšเซ‡เช• เช‰เชฎเซ‡เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ null, เชชเชฐเช‚เชคเซ เชตเชงเซ เชธเชพเชฐเซ‹ เช‰เช•เซ‡เชฒ เช เช›เซ‡ เช•เซ‡ เชคเชฐเซเช•เชฎเชพเช‚ เชคเซ‡เชจเซ€ เช–เชพเชคเชฐเซ€ เช•เชฐเชตเซ€ getSurname() เชคเชฎเซ‡ เชฏเซ‹เช—เซเชฏ เชฌเชฟเชจ-เชถเซ‚เชจเซเชฏ เชฎเซ‚เชฒเซเชฏ เชชเชธเช‚เชฆ เช•เชฐเซเชฏเซเช‚ เช›เซ‡.

A/B เชชเชฐเซ€เช•เซเชทเชฃ

เชตเชฐเซเชคเชฎเชพเชจ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เช เช›เซ‡ เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ เช›เซ‡ 1.0.0, เช‰เชคเซเชชเชพเชฆเชจ เชชเชฐ เชคเซˆเชจเชพเชค, เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ v1. เช…เชฎเชพเชฐเซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‹ เชฌเซ€เชœเซ‹ เชฆเชพเช–เชฒเซ‹ เชœเชฎเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ 2.0.0เชœเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเชถเซ‡ v2.

เชชเช—เชฒเชพเช‚:

  1. เชธเช‚เชธเซเช•เชฐเชฃ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‹ เชจเชตเซ‹ เชฆเชพเช–เชฒเซ‹ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เช›เซ‡ 2.0.0เชœเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡ v2
  2. เช† เชฆเชฐเชฎเชฟเชฏเชพเชจ เช•เซ‡เชŸเชฒเซ€เช• เชตเชฟเชจเช‚เชคเซ€เช“ เช†เชตเซƒเชคเซเชคเชฟ เชฆเชพเช–เชฒเชพเช“ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€ 1.0.0
  3. เช…เชชเชกเซ‡เชŸ เชธเชซเชณ เชฅเชฏเซเช‚ เช…เชจเซ‡ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชตเชฐเซเชเชจ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชฌเชนเซเชตเชฟเชง เชšเชพเชฒเซ€ เชฐเชนเซ‡เชฒเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹ เช›เซ‡ 1.0.0 เช…เชจเซ‡ เช…เชจเซเชฏ เช†เชตเซƒเชคเซเชคเชฟเช“ 2.0.0. เชฆเชฐเซ‡เช• เชตเซเชฏเช•เซเชคเชฟ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเชพเชฅเซ‡ เชตเชพเชคเชšเซ€เชค เช•เชฐเซ‡ เช›เซ‡ v2
  4. เช†เชตเซƒเชคเซเชคเชฟ 1.0.0 เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เช…เชŸเช• เช•เซ‰เชฒเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซเช‚ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชธเช‚เชธเซเช•เชฐเชฃ 2.0.0 เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡. เชคเซ‡เช“ เชเช•เชฌเซ€เชœเชพ เชธเชพเชฅเซ‡ เชฆเช–เชฒ เช•เชฐเชคเชพ เชจเชฅเซ€, เช…เชจเซ‡ เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชญเซ‚เชฒเซ‹ เชจ เชนเซ‹เชตเซ€ เชœเซ‹เชˆเช.
  5. เช†เชตเซƒเชคเซเชคเชฟ 2.0.0 เชชเช›เชพเชค เชธเซเชธเช‚เช—เชคเชคเชพ เชธเซเชจเชฟเชถเซเชšเชฟเชค เช•เชฐเซ€เชจเซ‡ เชœเซ‚เชจเชพ เช…เชจเซ‡ เชจเชตเชพ เชฌเช‚เชจเซ‡ เช•เซ‰เชฒเชฎเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‡ เช›เซ‡

เชคเซ‡ เชฎเชนเชคเซเชตเชจเซเช‚ เช›เซ‡. เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชœเซ‚เชจเซ€/เชจเชตเซ€ เช•เซ‰เชฒเชฎเชจเชพ เชฎเซ‚เชฒเซเชฏเซ‹เชจเชพ เช†เชงเชพเชฐเซ‡ เช†เช‡เชŸเชฎเซเชธเชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเชคเซ€ เช•เซ‹เชˆเชชเชฃ เช•เซเชตเซ‡เชฐเซ€ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเชพเชฐเซ‡ เชฏเชพเชฆ เชฐเชพเช–เชตเซเช‚ เชœเซ‹เชˆเช เช•เซ‡ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชนเชตเซ‡ เชกเซเชชเซเชฒเชฟเช•เซ‡เชŸ เชฎเซ‚เชฒเซเชฏเซ‹ เช›เซ‡ (เชฎเซ‹เชŸเชพ เชญเชพเช—เซ‡ เชคเซ‡เช“ เชนเชœเซ€ เชชเชฃ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เชฅเชˆ เชฐเชนเซเชฏเชพเช‚ เช›เซ‡). เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชœเซ‹ เชคเชฎเซ‡ เชเชตเชพ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“เชจเซ€ เชธเช‚เช–เซเชฏเชพเชจเซ‡ เช—เชฃเชตเชพ เชฎเชพเช‚เช—เชคเชพ เชนเซ‹เชต เช•เซ‡ เชœเซ‡เชฎเชจเซเช‚ เช›เซ‡เชฒเซเชฒเซเช‚ เชจเชพเชฎ (เช•เซ‰เชฒเชฎ เช—เชฎเซ‡ เชคเซ‡ เช•เชนเซ‡เชตเชพเชฏ) เช…เช•เซเชทเชฐเชฅเซ€ เชถเชฐเซ‚ เชฅเชฏเซเช‚ เชนเซ‹เชฏ A, เชชเช›เซ€ เชกเซ‡เชŸเชพ เชธเซเชฅเชณเชพเช‚เชคเชฐ เชชเซ‚เชฐเซเชฃ เชฅเชพเชฏ เชคเซเชฏเชพเช‚ เชธเซเชงเซ€ (old โ†’ new เช•เซ‰เชฒเชฎ) เชœเซ‹ เชคเชฎเซ‡ เชจเชตเซ€ เช•เซ‰เชฒเชฎ เชฎเชพเชŸเซ‡ เช•เซเชตเซ‡เชฐเซ€ เช•เชฐเซ‹ เช›เซ‹ เชคเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช…เชธเช‚เช—เชค เชกเซ‡เชŸเชพ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡.

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฐเซ‹เชฒเชฌเซ‡เช•

เชนเชตเซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชเชช เชตเชฐเซเชเชจ เช›เซ‡ 2.0.0 เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชฎเชพเช‚ v2.

เชชเช—เชฒเชพเช‚:

  1. เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชชเชฐ เชชเชพเช›เชพ เชซเซ‡เชฐเชตเซ‹ 1.0.0.
  2. เช†เชตเซƒเชคเซเชคเชฟ 1.0.0 เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เช•เซ‰เชฒเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซเช‚ เชจเชฅเซ€ surname, เชคเซ‡เชฅเซ€ เชฐเซ‹เชฒเชฌเซ‡เช• เชธเชซเชณ เชนเซ‹เชตเซเช‚ เชœเซ‹เชˆเช

DB เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชกเซ‡เชŸเชพเชฌเซ‡เช เชจเชพเชฎเชจเซ€ เช•เซ‰เชฒเชฎ เชงเชฐเชพเชตเซ‡ เช›เซ‡ last_name.

เชซเซเชฒเชพเชฏเชตเซ‡ เชธเซเชคเซเชฐเซ‹เชค เชธเซเช•เซเชฐเชฟเชชเซเชŸ:

CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

เชธเซเช•เซเชฐเชฟเชชเซเชŸ เช‰เชฎเซ‡เชฐเซ‹ surname.

เชงเซเชฏเชพเชจ. เชฏเชพเชฆ เชฐเชพเช–เซ‹ เช•เซ‡ เชคเชฎเซ‡ เชœเซ‡ เช•เซ‰เชฒเชฎ เช‰เชฎเซ‡เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ‹ เชคเซ‡เชฎเชพเช‚ เชคเชฎเซ‡ เช•เซ‹เชˆเชชเชฃ NOT NULL เช…เชตเชฐเซ‹เชงเซ‹ เช‰เชฎเซ‡เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€. เชœเซ‹ เชคเชฎเซ‡ JAR เชจเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเซ‹ เช›เซ‹, เชคเซ‹ เชœเซ‚เชจเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒเซ€ เช•เซ‰เชฒเชฎ เชตเชฟเชถเซ‡ เช•เซ‹เชˆ เช–เซเชฏเชพเชฒ เชนเชถเซ‡ เชจเชนเซ€เช‚ เช…เชจเซ‡ เชคเซ‡ เช†เชชเชฎเซ‡เชณเซ‡ NULL เชชเชฐ เชธเซ‡เชŸ เชฅเชˆ เชœเชถเซ‡. เชœเซ‹ เช†เชตเซ€ เชฎเชฐเซเชฏเชพเชฆเชพ เชนเซ‹เชฏ, เชคเซ‹ เชœเซ‚เชจเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช–เชพเชฒเซ€ เชคเซ‚เชŸเซ€ เชœเชถเซ‡.

-- NOTE: This field can't have the NOT NULL constraint cause if you rollback, the old version won't know about this field
-- and will always set it to NULL
ALTER TABLE PERSON ADD surname varchar(255);

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
UPDATE PERSON SET PERSON.surname = PERSON.last_name

เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹

เช…เชฎเซ‡ เชกเซ‡เชŸเชพ เชคเชฐเซ€เช•เซ‡ เชธเช‚เช—เซเชฐเชน เช•เชฐเซ€เช เช›เซ€เช last_name, เช…เชจเซ‡ เชฎเชพเช‚ surname. เชคเซ‡ เชœ เชธเชฎเชฏเซ‡ เช…เชฎเซ‡ เชฅเซ€ เชตเชพเช‚เชšเซ€เช เช›เซ€เช last_name, เช•เชพเชฐเชฃ เช•เซ‡ เช† เช•เซ‰เชฒเชฎ เชธเซŒเชฅเซ€ เชธเซเชธเช‚เช—เชค เช›เซ‡. เชœเชฎเชพเชตเชŸ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฆเชฐเชฎเชฟเชฏเชพเชจ, เช•เซ‡เชŸเชฒเซ€เช• เชตเชฟเชจเช‚เชคเซ€เช“ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชฆเชพเช–เชฒเชพ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡ เชœเซ‡ เชนเชœเซ เชธเซเชงเซ€ เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชจเชฅเซ€.

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;
    private String surname;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * Reading from the new column if it's set. If not the from the old one.
     *
     * When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
     * the surname column is not up to date (during the migration process lastName could have been updated).
     * In this case one can run yet another migration script after all applications have been deployed in the
     * new version to ensure that the surname field is updated.
     *
     * However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
     * have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
     * would be reading from lastName, then we would have very old data (since not a single datum was inserted
     * to lastName in version 3.0.0).
     */
    public String getSurname() {
        return this.surname != null ? this.surname : this.lastName;
    }

    /**
     * Storing both FIRST_NAME and SURNAME entries
     */
    public void setSurname(String surname) {
        this.lastName = surname;
        this.surname = surname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
                + "]";
    }
}

เชชเช—เชฒเซเช‚ 3: เช•เซ‹เชกเชฎเชพเช‚เชฅเซ€ เช›เซ‡เชฒเซเชฒเซเช‚_เชจเชพเชฎ เชฆเซ‚เชฐ เช•เชฐเชตเซเช‚

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ: 3.0.0

DB เชธเช‚เชธเซเช•เชฐเชฃ:v3

เชŸเชฟเชชเซเชชเชฃเซ€

เชจเซ‰เซ…เชง เชชเซเชฐเชคเชฟ.: เชฆเซ‡เช–เซ€เชคเซ€ เชฐเซ€เชคเซ‡, เชฎเซ‚เชณ เชฒเซ‡เช–เชฎเชพเช‚ เชฒเซ‡เช–เช•เซ‡ เชญเซ‚เชฒเชฅเซ€ เชชเช—เชฒเซเช‚ 2 เชฎเชพเช‚เชฅเซ€ เช† เชฌเซเชฒเซ‹เช•เชจเชพ เชŸเซ‡เช•เซเชธเซเชŸเชจเซ€ เชจเช•เชฒ เช•เชฐเซ€ เช›เซ‡. เช† เชชเช—เชฒเชพ เชชเชฐ, เช•เซ‰เชฒเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพเชจเซ‡ เชฆเซ‚เชฐ เช•เชฐเชตเชพเชจเชพ เชนเซ‡เชคเซเชฅเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช•เซ‹เชกเชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพ เชœเซ‹เชˆเช. last_name.

เชจเชตเซ€ เช•เซ‰เชฒเชฎ เช‰เชฎเซ‡เชฐเซ€เชจเซ‡ เช…เชจเซ‡ เชคเซ‡เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€เชจเซ€ เชจเช•เชฒ เช•เชฐเซ€เชจเซ‡, เช…เชฎเซ‡ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เชธเซเชธเช‚เช—เชค เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฌเชจเชพเชตเซเชฏเชพ เช›เซ‡. เช‰เชชเชฐเชพเช‚เชค, เชœเซ‹ เช†เชชเชฃเซ‡ JAR เชจเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เช•เชฐเซ€เช เช…เชฅเชตเชพ เชœเซ‚เชจเซ€ JAR เชšเชพเชฒเซ€ เชฐเชนเซ€ เชนเซ‹เชฏ, เชคเซ‹ เชคเซ‡ เช…เชฎเชฒ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชคเซ‚เชŸเซ€ เชœเชถเซ‡ เชจเชนเซ€เช‚.

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฐเซ‹เชฒเชฌเซ‡เช•

เชนเชพเชฒเชฎเชพเช‚ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชเชช เชตเชฐเซเชเชจ เช›เซ‡ 3.0.0 เช…เชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช v3. เชธเช‚เชธเซเช•เชฐเชฃ 3.0.0 เชฎเชพเชŸเซ‡ เชกเซ‡เชŸเชพ เชธเชพเชšเชตเชคเซ‹ เชจเชฅเซ€ last_name. เช†เชจเซ‹ เช…เชฐเซเชฅ เช เช›เซ‡ เช•เซ‡ เชฎเชพเช‚ surname เชธเซŒเชฅเซ€ เช…เชฆเซเชฏเชคเชจ เชฎเชพเชนเชฟเชคเซ€ เชธเช‚เช—เซเชฐเชนเชฟเชค เช›เซ‡.

เชชเช—เชฒเชพเช‚:

  1. เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชธเช‚เชธเซเช•เชฐเชฃ เชชเชฐ เชชเชพเช›เชพ เชซเซ‡เชฐเชตเซ‹ 2.0.0.
  2. เช†เชตเซƒเชคเซเชคเชฟ 2.0.0 เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ last_name ะธ surname.
  3. เช†เชตเซƒเชคเซเชคเชฟ 2.0.0 เชฒเซ‡เชถเซ‡ surname, เชœเซ‹ เชคเซ‡ เชถเซ‚เชจเซเชฏ เชจเชฅเซ€, เช…เชจเซเชฏเชฅเชพ -last_name

เชกเซ‡เชŸเชพเชฌเซ‡เช เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เช•เซ‹เชˆ เชฎเชพเชณเช–เชพเช•เซ€เชฏ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชจเชฅเซ€. เชœเซ‚เชจเชพ เชกเซ‡เชŸเชพเชจเซเช‚ เช…เช‚เชคเชฟเชฎ เชธเซเชฅเชณเชพเช‚เชคเชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเซ€เชšเซ‡เชจเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชšเชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡:

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
-- ALSO WE'RE NOT CHECKING IF WE'RE NOT OVERRIDING EXISTING ENTRIES. WE WOULD HAVE TO COMPARE
-- ENTRY VERSIONS TO ENSURE THAT IF THERE IS ALREADY AN ENTRY WITH A HIGHER VERSION NUMBER
-- WE WILL NOT OVERRIDE IT.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;

-- DROPPING THE NOT NULL CONSTRAINT; OTHERWISE YOU WILL TRY TO INSERT NULL VALUE OF THE LAST_NAME
-- WITH A NOT_NULL CONSTRAINT.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;

เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชจเซ‰เซ…เชง เชชเซเชฐเชคเชฟ.: เช† เชฌเซเชฒเซ‹เช•เชจเซเช‚ เชตเชฐเซเชฃเชจ เชชเชฃ เชญเซ‚เชฒเชฅเซ€ เชฒเซ‡เช–เช• เชฆเซเชตเชพเชฐเชพ เชชเช—เชฒเซเช‚ 2 เชฎเชพเช‚เชฅเซ€ เชจเช•เชฒ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเชคเซเช‚. เชฒเซ‡เช–เชจเชพ เชคเชฐเซเช• เช…เชจเซเชธเชพเชฐ, เช† เชชเช—เชฒเชพเชฎเชพเช‚ เช•เซ‹เชกเชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเชจเซ‹ เชนเซ‡เชคเซ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชคเชคเซเชตเซ‹เชจเซ‡ เชฆเซ‚เชฐ เช•เชฐเชตเชพเชจเซ‹ เชนเซ‹เชตเซ‹ เชœเซ‹เชˆเช เชœเซ‡ เช•เซ‰เชฒเชฎ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡. last_name.

เช…เชฎเซ‡ เชกเซ‡เชŸเชพ เชคเชฐเซ€เช•เซ‡ เชธเช‚เช—เซเชฐเชน เช•เชฐเซ€เช เช›เซ€เช last_name, เช…เชจเซ‡ เชฎเชพเช‚ surname. เชตเชงเซเชฎเชพเช‚, เช…เชฎเซ‡ เช•เซ‰เชฒเชฎเชฎเชพเช‚เชฅเซ€ เชตเชพเช‚เชšเซ€เช เช›เซ€เช last_name, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชธเซŒเชฅเซ€ เชธเซเชธเช‚เช—เชค เช›เซ‡. เชœเชฎเชพเชตเชŸ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฆเชฐเชฎเชฟเชฏเชพเชจ, เช•เซ‡เชŸเชฒเซ€เช• เชตเชฟเชจเช‚เชคเซ€เช“ เชเชตเชพ เช‰เชฆเชพเชนเชฐเชฃ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชถเช•เซ‡ เช›เซ‡ เช•เซ‡ เชœเซ‡ เชนเชœเซ เชธเซเชงเซ€ เช…เชชเช—เซเชฐเซ‡เชก เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชจเชฅเซ€.

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String surname;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSurname() {
        return this.surname;
    }

    public void setSurname(String lastname) {
        this.surname = lastname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", surname=" + this.surname
                + "]";
    }
}

เชชเช—เชฒเซเช‚ 4: เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚เชฅเซ€ เช›เซ‡เชฒเซเชฒเซเช‚_เชจเชพเชฎ เชฆเซ‚เชฐ เช•เชฐเชตเซเช‚

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃ: 4.0.0

DB เชธเช‚เชธเซเช•เชฐเชฃ: v4

เชŸเชฟเชชเซเชชเชฃเซ€

เชนเช•เซ€เช•เชค เช เช›เซ‡ เช•เซ‡ เช†เชตเซƒเชคเซเชคเชฟ เช•เซ‹เชก เช•เชพเชฐเชฃเซ‡ 3.0.0 เช•เซ‰เชฒเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเชฏเซ‹ เชจเชฅเซ€ last_name, เชœเซ‹ เช†เชชเชฃเซ‡ เชชเชพเช›เชพ เชฐเซ‹เชฒ เช•เชฐเซ€เช เชคเซ‹ เช…เชฎเชฒ เชฆเชฐเชฎเชฟเชฏเชพเชจ เช•เช‚เชˆเชชเชฃ เช–เชฐเชพเชฌ เชฅเชถเซ‡ เชจเชนเซ€เช‚ 3.0.0 เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚เชฅเซ€ เช•เซ‰เชฒเชฎ เชฆเซ‚เชฐ เช•เชฐเซเชฏเชพ เชชเช›เซ€.

เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชเช•เซเชเซ‡เช•เซเชฏเซเชถเชจ เชฒเซ‹เช—เซเชธ

We will do it in the following way:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0
05) Wait for the app (2.0.0) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0
07) Generate a person by calling POST localhost:9992/person to version 2.0.0
08) Kill app (1.0.0)
09) Run 3.0.0
10) Wait for the app (3.0.0) to boot
11) Generate a person by calling POST localhost:9992/person to version 2.0.0
12) Generate a person by calling POST localhost:9993/person to version 3.0.0
13) Kill app (3.0.0)
14) Run 4.0.0
15) Wait for the app (4.0.0) to boot
16) Generate a person by calling POST localhost:9993/person to version 3.0.0
17) Generate a person by calling POST localhost:9994/person to version 4.0.0

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}

Starting app in version 2.0.0

Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:

{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}

Killing app 1.0.0

Starting app in version 3.0.0

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}

Killing app 2.0.0

Starting app in version 4.0.0

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:

{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}

Generate a person in version 4.0.0
Sending a post to 127.0.0.1:9994/person. This is the response:

{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}

DB เชซเซ‡เชฐเชซเชพเชฐเซ‹

เชชเซเชฐเชฎเชพเชฃเชฎเชพเช‚ v3 เช…เชฎเซ‡ เชซเช•เซเชค เช•เซ‰เชฒเชฎ เชฆเซ‚เชฐ เช•เชฐเซ€เช เช›เซ€เช last_name เช…เชจเซ‡ เช–เซ‚เชŸเชคเชพ เชชเซเชฐเชคเชฟเชฌเช‚เชงเซ‹ เช‰เชฎเซ‡เชฐเซ‹.

-- REMOVE THE COLUMN
ALTER TABLE PERSON DROP last_name;

-- ADD CONSTRAINTS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;

เช•เซ‹เชก เชซเซ‡เชฐเชซเชพเชฐเซ‹

เช•เซ‹เชกเชฎเชพเช‚ เช•เซ‹เชˆ เชซเซ‡เชฐเชซเชพเชฐ เชจเชฅเซ€.

เชจเชฟเชทเซเช•เชฐเซเชท

เช…เชฎเซ‡ เชธเชซเชณเชคเชพเชชเซ‚เชฐเซเชตเช• เชชเชพเช›เชณเชจเซ€-เช…เชธเช‚เช—เชค เช•เซ‰เชฒเชฎเชจเชพ เชจเชพเชฎเชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเชจเซ‡ เช˜เชฃเชพ เชชเชพเช›เชณเชจเซ€-เชธเซเชธเช‚เช—เชค เชœเชฎเชพเชตเชŸ เช•เชฐเซ€เชจเซ‡ เชฒเชพเช—เซ เช•เชฐเซเชฏเซ‹. เชจเซ€เชšเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เชธเชพเชฐเชพเช‚เชถ เช›เซ‡:

  1. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชœเชฎเชพเชตเชŸ 1.0.0 ั v1 เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเช•เซ€เชฎเชพ (เช•เซ‰เชฒเชฎเชจเซเช‚ เชจเชพเชฎ = last_name)
  2. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชœเชฎเชพเชตเชŸ 2.0.0, เชœเซ‡ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‡ เช›เซ‡ last_name ะธ surname. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชฎเชพเช‚เชฅเซ€ เชตเชพเช‚เชšเซ‡ เช›เซ‡ last_name. เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเช‚เชธเซเช•เชฐเชฃเชฎเชพเช‚ เช›เซ‡ v2เชœเซ‡เชตเซ€ เช•เซ‰เชฒเชฎ เชงเชฐเชพเชตเซ‡ เช›เซ‡ last_name, เช…เชจเซ‡ surname. surname l เชจเซ€ เชจเช•เชฒ เช›เซ‡ast_name. (เชจเซ‹เช‚เชง: เช† เช•เซ‰เชฒเชฎเชฎเชพเช‚ เชจเชฒ เช…เชตเชฐเซ‹เชง เชจ เชนเซ‹เชตเซ‹ เชœเซ‹เชˆเช)
  3. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชœเชฎเชพเชตเชŸ 3.0.0, เชœเซ‡ เชซเช•เซเชค เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‡ เช›เซ‡ surname เช…เชจเซ‡ เช…เชŸเช• เชชเชฐเชฅเซ€ เชตเชพเช‚เชšเซ‡ เช›เซ‡. เชกเซ‡เชŸเชพเชฌเซ‡เช เชฎเชพเชŸเซ‡, เช›เซ‡เชฒเซเชฒเซเช‚ เชธเซเชฅเชณเชพเช‚เชคเชฐ เชฅเชˆ เชฐเชนเซเชฏเซเช‚ เช›เซ‡ last_name ะฒ surname. เชเช• เชฎเชฐเซเชฏเชพเชฆเชพ เชชเชฃ เชจเชฅเซ€ เชฎเชพเช‚เชฅเซ€ เชฆเซ‚เชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ last_name. เชกเซ‡เชŸเชพเชฌเซ‡เช เชนเชตเซ‡ เชธเช‚เชธเซเช•เชฐเชฃเชฎเชพเช‚ เช›เซ‡ v3
  4. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชœเชฎเชพเชตเชŸ 4.0.0 - เช•เซ‹เชกเชฎเชพเช‚ เช•เซ‹เชˆ เชซเซ‡เชฐเชซเชพเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชจเชฅเซ€. เชกเซ‡เชŸเชพเชฌเซ‡เช เชœเชฎเชพเชตเชŸ v4, เชœเซ‡ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡ last_name. เช…เชนเซ€เช‚ เชคเชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เช–เซ‚เชŸเชคเชพ เช…เชตเชฐเซ‹เชงเซ‹ เช‰เชฎเซ‡เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เช† เช…เชญเชฟเช—เชฎเชจเซ‡ เช…เชจเซเชธเชฐเซ€เชจเซ‡, เชคเชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช/เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชธเซเชธเช‚เช—เชคเชคเชพเชจเซ‡ เชคเซ‹เชกเซเชฏเชพ เชตเชฟเชจเชพ เชนเช‚เชฎเซ‡เชถเชพ เชเช• เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เชฐเซ‹เชฒ เชฌเซ‡เช• เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เช•เซ‹เชก

เช† เชฒเซ‡เช–เชฎเชพเช‚ เชตเชชเชฐเชพเชฏเซ‡เชฒ เชคเชฎเชพเชฎ เช•เซ‹เชก เช…เชนเซ€เช‚ เช‰เชชเชฒเชฌเซเชง เช›เซ‡ Github. เชจเซ€เชšเซ‡ เชตเชงเชพเชฐเชพเชจเซเช‚ เชตเชฐเซเชฃเชจ เช›เซ‡.

เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ

เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เช•เซเชฒเซ‹เชจ เช•เชฐเซเชฏเชพ เชชเช›เซ€, เชคเชฎเซ‡ เชจเซ€เชšเซ‡เชจเซเช‚ เชซเซ‹เชฒเซเชกเชฐ เชฎเชพเชณเช–เซเช‚ เชœเซ‹เชถเซ‹.

โ”œโ”€โ”€ boot-flyway-v1              - 1.0.0 version of the app with v1 of the schema
โ”œโ”€โ”€ boot-flyway-v2              - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
โ”œโ”€โ”€ boot-flyway-v2-bad          - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
โ”œโ”€โ”€ boot-flyway-v3              - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
โ””โ”€โ”€ boot-flyway-v4              - 4.0.0 version of the app with v4 of the schema (app can be rolled back)

เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹

เชคเชฎเซ‡ เชจเซ€เชšเซ‡เชจเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹เชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹ เชšเชฒเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹, เชœเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เชชเช›เชพเชค-เชธเซเชธเช‚เช—เชค เช…เชจเซ‡ เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฆเชฐเซเชถเชพเชตเชถเซ‡.

เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เชธเซเชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชพเชฅเซ‡เชจเซ‹ เช•เซ‡เชธ, เชšเชฒเชพเชตเซ‹:

./scripts/scenario_backward_compatible.sh

เช…เชจเซ‡ เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชชเชพเช›เชณเชจเซ€ เชคเชฐเชซ เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชพเชฅเซ‡เชจเซ‹ เช•เซ‡เชธ, เชšเชฒเชพเชตเซ‹:

./scripts/scenario_backward_incompatible.sh

เชตเชธเช‚เชค เชฌเซเชŸ เชจเชฎเซ‚เชจเชพ เชซเซเชฒเชพเชฏเชตเซ‡

เชฌเชงเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชฎเชพเช‚เชฅเซ€ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เช›เซ‡ Spring Boot Sample Flyway.

เชคเชฎเซ‡ เชเช• เชจเชœเชฐ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ http://localhost:8080/flyway, เชคเซเชฏเชพเช‚ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹เชจเซ€ เชฏเชพเชฆเซ€ เช›เซ‡.

เช† เช‰เชฆเชพเชนเชฐเชฃเชฎเชพเช‚ H2 เช•เชจเซเชธเซ‹เชฒเชจเซ‹ เชชเชฃ เชธเชฎเชพเชตเซ‡เชถ เชฅเชพเชฏ เช›เซ‡ http://localhost:8080/h2-console) เชœเซ‡เชฅเซ€ เชคเชฎเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเซเชฅเชฟเชคเชฟ เชœเซ‹เชˆ เชถเช•เซ‹ (เชกเชฟเชซเซ‹เชฒเซเชŸ jdbc URL เช›เซ‡ jdbc:h2:mem:testdb).

เชตเชงเซเชฎเชพเช‚

เช…เชฎเชพเชฐเชพ เชฌเซเชฒเซ‹เช— เชชเชฐ เช…เชจเซเชฏ เชฒเซ‡เช–เซ‹ เชชเชฃ เชตเชพเช‚เชšเซ‹:

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹