JavaRush /ื‘ืœื•ื’ Java /Random-HE /ืžื’ืฃ ืื‘ื™ื‘ ื›ื™ื‘ื•ืฉ
Surplus
ืจึธืžึธื”
ะœะพัะบะฒะฐ

ืžื’ืฃ ืื‘ื™ื‘ ื›ื™ื‘ื•ืฉ

ืคื•ืจืกื ื‘ืงื‘ื•ืฆื”
ื™ื•ื ื˜ื•ื‘, ืงื•ืจื ื™ืงืจ! ื•ื ืขื™ื ืœื”ื›ื™ืจ, ื’ื ืื ื”ืฉื ื”ืคื•ืžืคื•ื–ื™ ื”ื™ื” ื”ืกื™ื‘ื” ื”ืขื™ืงืจื™ืช ืœื‘ื—ื•ืŸ ืืช ื”ื ื•ืฉื ื”ืฆื ื•ืข ืขืœ ื”ื”ื™ื›ืจื•ืช ื”ืจืืฉื•ื ื” ืขื ืคื™ืชื•ื— Spring Boot. ื‘ืจืฆื•ื ื™ ืœื—ืœื•ืง ืืช ื”ื ื™ืกื™ื•ืŸ ืฉืœื™ ื‘ื‘ื™ืฆื•ืข ืžืฉื™ืžืช ื”ื”ื™ื›ืจื•ืช ืœื”ืชืžื—ื•ืช ื‘ืคื•ืจื˜ืœ JavaRush, ืชื•ืš ื”ืฆื’ืช ืกืงื™ืจื” ืžื”ืฆื“ ืฉืœ ืกื˜ื•ื“ื ื˜ ืจื’ื™ืœ ื‘ืื•ื ื™ื‘ืจืกื™ื˜ื” ื˜ื›ื ื™ืช ืœื—ืœื•ื˜ื™ืŸ ืฉืจื•ืฆื” ืœื‘ื—ื•ืŸ ืืช ื—ื•ื–ืง ื”ื™ื“ืข ื”ืžืฆื˜ื‘ืจ ืฉืœื•. Conquest Spring Boot - 1ืื ื™ ื‘ืฉื•ื ืื•ืคืŸ ืœื ืžืชื›ื—ืฉ ืœื ื•ื›ื—ื•ืช ืืคืฉืจื™ืช ืฉืœ ื’ืกื•ืช ืจื•ื— ื‘ืงื•ื“ ืื• ื‘ืฉื™ื˜ืช ื”ื—ืฉื™ื‘ื” ื”ืžืฆื•ืจืคืช, ื•ืื ื™ ืžื‘ืจืš ืขืœ ื‘ื™ืงื•ืจืช ื‘ื•ื ื”, ื›ื™ ื‘ื–ื›ื•ืช "ืžื”ืžื•ืจื•ืช ื•ื—ื‘ื•ืจื•ืช" ืืคืฉืจ ืœื”ืชืคืชื— ืœื›ื™ื•ื•ืŸ ืžืงืฆื•ืขื™. ื™ืชืจ ืขืœ ื›ืŸ, ืื ื™ ื‘ื›ืœืœ ืœื ืžืชื™ื™ืžืจ ืœื”ื™ื•ืช "ืชืจื•ืคืช ืคืœื" ื‘ืคืชืจื•ืŸ ื”ืชื ืื™ื ื”ื ืชื•ื ื™ื ื•ืžืฉืžื™ื˜ ื‘ื›ื•ื•ื ื” ืงื˜ืขื™ื ื‘ื•ื“ื“ื™ื ืฉืœ ื”ืชื•ื›ื ื™ืช, ืžื” ืฉืžื•ืชื™ืจ ืืช ื—ืฉื™ื‘ื•ืช ื”ืžืคืชื— ืฉืœ ื›ื ื™ืกื” ืœื ื•ืฉื ืžื•ืจื›ื‘ ื™ื—ืกื™ืช ืœืœื ื”ืฉืœื›ื•ืช ืงื˜ื ื˜ื ื•ืช ืขืœ ืžืขืจื›ืช ื”ืขืฆื‘ื™ื. ื–ื” ื ื›ื•ืŸ, ื–ื” ืคื–ื™ื– ืœื”ื›ื—ื™ืฉ ืืช ื”ืžื•ื‘ืŸ ืžืืœื™ื•: ื–ื” ื”ื™ื” ืœื™ ืงืฉื” ื•ืฉื•ื ื“ื‘ืจ ืœื ื”ื™ื” ื‘ืจื•ืจ ืขื“ ืจื’ืข ืžืกื•ื™ื. ื•ืื ืืชื” ื—ื•ื•ื” ืจื’ืฉื•ืช ื“ื•ืžื™ื ืžื”ืคื’ื™ืฉื” ื”ืจืืฉื•ื ื” ืขื ื”ืžืฉื™ืžื”, ืื– "ื‘ืจื•ืš ื”ื‘ื!" ื‘ื•ืื• ื ื›ืชื•ื‘ ื™ื™ืฉื•ื ืื™ื ื˜ืจื ื˜ ื‘-Spring Boot ื‘ืืžืฆืขื•ืช ืื ืœื•ื’ื™ื” ืคืฉื•ื˜ื” ืฉืœ โ€‹โ€‹ืžื‘ื—ืŸ ื›ื ื™ืกื” ืœื”ืชืžื—ื•ืช ื‘ืืžืฆืขื•ืช ืžื ื•ืข ืชื‘ื ื™ืช Thymeleafื•ืฉืื™ืœืชื•ืช queryืœืฉืจืช MySQL ืžืงื•ืžื™ ื›ื“ื™ ืœืกื ืŸ ืืช ืžืขืจืš ื”ืžื™ื“ืข ื”ื ื›ื ืก. ืื– ื‘ื•ืื• ื ืชื—ื™ืœ!

ืžื’ืฃ ืื‘ื™ื‘. ืื™ื–ื• ื—ื™ื” ื–ื• ื•ื›ื™ืฆื“ ืœื‘ืฉืœ ืื•ืชื”?

ื‘ืงืฆืจื” ื•ื‘ืชืžืฆื™ืชื™ื•ืช, ื–ื”ื• ื›ืœื™ ืžืฆื•ื™ืŸ ืžื‘ื™ืช Pivotel ืœื—ื™ืกื›ื•ืŸ ื‘ื–ืžืŸ ื™ืงืจ ื‘ืชื”ืœื™ืš ื™ืฆื™ืจืช ื”ืืคืœื™ืงืฆื™ื”, ื‘ื™ื˜ื•ืœ ื”ืฆื•ืจืš ื‘ื—ื™ื‘ื•ืจ ื™ืฉื™ืจ ืฉืœ ืกืคืจื™ื•ืช ืฆื“ ืฉืœื™ืฉื™, ื›ืชื™ื‘ืช ื‘ื“ ืžื™ืคื•ื™ ื•ืกืจื‘ืœื˜ื™ื ืžืจืฉื™ืžื™ื. ื“ื™ ืœื”ืฉืชืžืฉ ื‘ื‘ื•ื ื” Spring Initializr , ื”ืžืฉื•ืœื‘ ื‘- IntelliJ IDEA Ultimate Edition (ืงื•ื‘ืฅ - ื—ื“ืฉ - ืคืจื•ื™ืงื˜... - Spring Initializr) ืื• ืžืžื•ืงื ื‘ืฉื™ืจื•ืช ื”ืื™ื ื˜ืจื ื˜ start.spring.io , ืชื•ืš ืฆื™ื•ืŸ ื—ื‘ื™ืœื•ืช ืœื›ืœื•ืœ ืžืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ื”ืฆืขื•ืช.
Conquest Spring Boot - 2
ื‘ื”ืชืื ืœืžืคืจื˜ื™ื ื”ื˜ื›ื ื™ื™ื ืฉื”ื•ืขืœื•, ื ืฉืชืžืฉ ื‘ืกื˜ ื”ืื“ื•ืŸ, ื”ืกื˜ื ื“ืจื˜ื™ ืœื™ืฆื™ืจืช ื™ื™ืฉื•ื ืื™ื ื˜ืจื ื˜ ืคืฉื•ื˜ ื‘ืืžืฆืขื•ืช ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL :
  • WEB ื”ื•ื ื”ืจื›ื™ื‘ ื”ืขื™ืงืจื™ ืœืคื™ืชื•ื— ืืคืœื™ืงืฆื™ื™ืช ืื™ื ื˜ืจื ื˜, ื›ื•ืœืœ ืฉืจืช Apache Tomcat ืžืงื•ืžื™ ื‘ื›ืชื•ื‘ืช ื”ืกื˜ื ื“ืจื˜ื™ืช localhost:8080 ื•ืžืกื’ืจืช Spring MVC ื”ืื•ื ื™ื‘ืจืกืœื™ืช.

  • DevTools - ืžืฉืžืฉื™ื ืœื”ืคืขืœื” ืžื—ื“ืฉ ืžื”ื™ืจื” ืฉืœ ื™ื™ืฉื•ื ื‘-JVM ื—ื ื›ืืฉืจ ืžืชื’ืœื™ื ืฉื™ื ื•ื™ื™ื ื‘ืงื•ื“ ืื• ื‘ืชื‘ื ื™ื•ืช ื”ืงื•ืžืคื™ืœืฆื™ื”; ื™ืชืจ ืขืœ ื›ืŸ, ื–ื” ืžืฉื—ืจืจ ืืช Thymeleaf ืžื ื™ืงื•ื™ ืžื˜ืžื•ืŸ ืื ื”ืžื ื•ืข ืฉื ื‘ื—ืจ ื›ืœื•ืœ ื‘ืคืจื•ื™ืงื˜.

  • JPA ื”ื™ื ื˜ื›ื ื•ืœื•ื’ื™ื” ื”ื ื“ืจืฉืช ืœืขื‘ื•ื“ื” ืขื ืžืกื“ื™ ื ืชื•ื ื™ื ื•ืžืกืคืงืช ืžื™ืคื•ื™ ืื•ื‘ื™ื™ืงื˜ื™ื‘ื™ ืฉืœ ืื•ื‘ื™ื™ืงื˜ื™ Java, ืžืกืคืงืช API ( Hibernate ื‘ืžืงืจื” ืฉืœื ื•) ืœื ื™ื”ื•ืœ, ืฉืžื™ืจื” ื•ืื—ื–ื•ืจ ืฉืœ ื™ืฉื•ื™ื•ืช.

  • Thymeleaf (ืฉืคื, AngularJS, Vaadin ื•ืขื•ื“) - ืžื ื•ืข ืชื‘ื ื™ืช ืœื”ื“ืžื™ื™ืช ืืคืœื™ืงืฆื™ื•ืช; ื‘ื–ื›ื•ืช ื”ื”ื™ื›ืจื•ืช ื”ื™ื—ืกื™ืช ืฉืœื™ ืขื ืขืงืจื•ื ื•ืช ื”-html, ื‘ื—ืจืชื™ ื‘-Thymeleaf, ืฉื“ื—ืฃ ืืช ื”ืฉืคื” ืœืื‘ืŸ ื”ืคื™ื ื” ืฉืœ ื”ืขื•ืœื.

  • MySQL - ืžื—ื‘ืจ ืžื ื”ืœื™ ื”ืชืงื ื™ื ืฉืœ Java Database Connectivity ืœื‘ื™ืฆื•ืข ืฉืื™ืœืชื•ืช SQL ืžื•ืœ ืžืกื“ ื”ื ืชื•ื ื™ื.
ืœืื—ืจ ื”ื‘ื—ื™ืจื” ื”ืกื•ืคื™ืช ืฉืœ ื”ืจื›ื™ื‘ื™ื ื•ื”ื™ืฆื™ืจื”, ืื ื• ืžืงื‘ืœื™ื ืืจื›ื™ื˜ืงื˜ื•ืจืช ืืคืœื™ืงืฆื™ื•ืช ืื™ื ื˜ืจื ื˜ ืจื’ื™ืœื” ืขื ืกืคืจื™ื•ืช ืžื•ื›ื ื•ืช ืœืžื™ืœื•ื™ ื ื•ืกืฃ. ืคืจื’ืžื ื˜ื™ื ืœืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ื—ืœืง ื”ื•ื•ื™ื–ื•ืืœื™, ื‘ื™ืŸ ืื ื–ื” ืกื’ื ื•ื ื•ืช ื’ืจืคื™ื™ื ืฉืœ CSS, ื“ืคื™ HTML ืกื˜ื ื“ืจื˜ื™ื™ื ืื• ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช JavaScript, ืฆืจื™ื›ื™ื ืœื”ื™ื•ืช ืžืžื•ืงืžื™ื ื‘"ืžืฉืื‘ื™ื", ื•ื‘ื”ืชืื ืœื›ืš, ืจื›ื™ื‘ ื”ืงืฆื” ื”ืื—ื•ืจื™ ืืžื•ืจ ืœื”ื™ื•ืช ืžืžื•ืงื ื‘-"Java". ื›ื“ืื™ ืœืฉื™ื ืœื‘ ื’ื ืœืงื•ื‘ืฅ pom.xml ื‘ื˜ื•ื•ื— ื”ืฉื•ืจืฉ, ื”ืžืื—ืกืŸ ืืช ืžื‘ื ื” ื”ืคืจื•ื™ืงื˜ ื•ื”ืชืœื•ืช ื‘ื™ืŸ ื”ืจื›ื™ื‘ื™ื. ืื ืืชื” ืจื•ืฆื” ืœื”ืจื—ื™ื‘ ืขื•ื“ ื™ื•ืชืจ ืืช ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืขื ื—ื‘ื™ืœื•ืช ื ื•ืกืคื•ืช ืื• ืœื”ืกื™ืจ ื“ื‘ืจื™ื ืžื™ื•ืชืจื™ื, ืขืœื™ืš ืœื‘ืฆืข ืžื ื™ืคื•ืœืฆื™ื•ืช ื‘ื™ืŸ ืชื’ื™ื•ืช <dependencies></dependencies>ืœืคื™ ืฉื™ื˜ื” ื“ื•ืžื”.
Conquest Spring Boot - 3

ืฆืขื“ื™ื ืจืืฉื•ื ื™ื ืœืขืชื™ื“ ื’ื“ื•ืœ

ืœืื—ืจ ืžื›ืŸ, ืขื•ืœื” ืฉืืœื” ื“ื™ ืžืขื ื™ื™ื ืช ื•ื“ื™ ื”ื’ื™ื•ื ื™ืช: "ืžื” ืœืขืฉื•ืช ืขื›ืฉื™ื•? ืื™ืš ื–ื” ื™ืขื‘ื•ื“? ื”ืชื•ื›ื ื™ืช ื‘ื ื•ื™ื” ืขืœ ื”ืขืงืจื•ื ื•ืช ืฉืœ Model-View-Controller: ื”ื™ื ืžืืจื’ื ืช ืืช ืงืจื™ืืช ื”ื™ืฉื•ื™ื•ืช ืžืžืกื“ ื”ื ืชื•ื ื™ื ื”ืžื—ื•ื‘ืจื™ื (Model) ื•ืžื•ืฆื’ืช ื‘ืžืžืฉืง ื”ืžืฉืชืžืฉ ืขื ืคืงื“ื™ื (View); ืชืงืฉื•ืจืช ื‘ื™ืŸ ืจื›ื™ื‘ื™ื ื•ื‘ื™ืฆื•ืข ืคืขื•ืœื•ืช ืขืœ ืคื™ ื‘ืงืฉื•ืช ืžื•ืขื‘ืจื•ืช ืžืชื‘ืฆืขืช ื‘ื–ื›ื•ืช ื”ื‘ืงืจ. ื™ืฆื™ืจืช ืžืจื›ื™ื‘ื™ ืžืคืชื— ื”ื™ื ื”ืžืฉืžืฉืช ื›ื ืงื•ื“ืช ื”ืชื™ื™ื—ืกื•ืช ืœื”ืžืฉืš ื”ืคื™ืชื•ื—. ืขืœ ืžื ืช ืœืžื ื•ืข ืžื“ืจื•ืŸ ื—ืœืงืœืง ื•ืœืฉืžื•ืจ ืขืœ ื›ื‘ื•ื“ ื—ื‘ืจื™ืš ืœืชื—ื•ื ื”ืขื‘ื•ื“ื”, ื™ืฉ ืœืžืงื ืืช ื”ืจื›ื™ื‘ื™ื ื‘ืกืคืจื™ื•ืช ื”ืžืชืื™ืžื•ืช (ืœืžืฉืœ, ืœืžืงื ืืช ืงื•ื‘ืฅ ื”-Controller ื‘ืชื™ืงื™ื™ืช ื”ื‘ืงืจื™ื ื‘ืกื ื™ืฃ "java") ื•ืœืฉืžื•ืจ ื‘ืงืคื™ื“ื” ืกื“ืจ ื‘ืžืงื•ื ื”ืขื‘ื•ื“ื”.

ืžื”ื•ืช ื”ื™ื ื—ืœืง ืงื˜ืŸ ื‘ืžื ื’ื ื•ืŸ ื’ื“ื•ืœ

ืื• ื‘ืžื™ืœื™ื ืื—ืจื•ืช, ื”ืžื•ื“ืœ ืฉืœื ื• ืœืคื™ ื”ืชื ืื™ื ืฉื ืงื‘ืขื• ื‘ื‘ืขื™ื”. ืื ื™ื•ืฆืื™ื ืžื ื•ืฉื ื”ื“ื™ื•ืŸ ื•ื—ื•ื–ืจื™ื ืœืคืจื•ื™ืงื˜ ื”ืžื‘ื•ื, ืื ื• ื™ื›ื•ืœื™ื ืœืงื‘ื•ืข ื‘ื‘ื™ื˜ื—ื•ืŸ ืฉื™ืฉ ื”ื‘ื“ืœื™ื ืžื™ื ื™ืžืœื™ื™ื ื‘ื™ืŸ ื”ืžืฉื™ืžื•ืช ื•ืœื”ื™ืฆืžื“ ืœืงื•ื ืกืคื˜ ื”ืžืžื•ืฆืข ื‘ืกืงื™ืจื” ื ื•ืกืคืช. ื ื ื™ื—, ื”ืขืจื•ืช ื‘ืžื—ื‘ืจืช, ื›ื•ืœืœ:
  • ืžืกืคืจ ื–ื™ื”ื•ื™ ืœืงื‘ื™ืขืช ืžื™ืงื•ื ื‘ื–ืจื™ืžื” ื”ื›ืœืœื™ืช;
  • ื”ื•ื“ืขืช ื˜ืงืกื˜ ืฉืœ ืžืกืคืจ ืžืกื•ื™ื ืฉืœ ืชื•ื•ื™ื;
  • ื”ืชืืจื™ืš ืฉื‘ื• ื”ืžืฉืชืžืฉ ื”ื•ืกื™ืฃ ืื•ืชื• ืœืจืฉื™ืžื” ื”ื›ืœืœื™ืช;
  • ืžืฉืชื ื” ื‘ื•ืœื™ืื ื™ ืœืงื‘ื™ืขืช "ื‘ื•ืฆืข ืื• ืœื ื ืขืฉื”" ("ืงืจื ืื• ืœื ืงืจื").
ืœื›ืŸ, ื‘ื•ืื• ื ื™ืฆื•ืจ ืžื—ืœืงื” Note ื‘ืกืคืจื™ื™ื” ื‘ืฉื "entity" ื•ื ื•ืกื™ืฃ ืืช ื”ืฉื“ื•ืช ื”ืžืชืื™ืžื™ื:
@Entity
public class Note {

   @Id
   @GeneratedValue
   private int id;
   private String message;
   private Date date;
   private boolean done;

   public Note() {
   }

   public Note(String message) {
       this.message = message;
       this.date = new Date();
       this.done = false;
   }
}
ืกื˜ื™ื™ื” ื ื•ืกืคืช ืžื ื•ืฉื ื”ื“ื™ื•ืŸ ืœื”ื‘ื ื” ืจื‘ื” ื™ื•ืชืจ ืฉืœ ื”ืžืชืจื—ืฉ ืžืชื•ืš ืขืžื“ื” ืชื™ืื•ืจื˜ื™ืช. ื”ืงืฉืจ ื‘ื™ืŸ ืจื›ื™ื‘ื™ื ื‘ืื‘ื™ื‘ ืžื•ื’ื“ืจ ืขืœ ื™ื“ื™ ื”ืขืจื•ืช - ืžืฆื‘ื™ืขื™ื ืžื™ื•ื—ื“ื™ื ืžื•ืœ ืื•ื‘ื™ื™ืงื˜ื™ื, ืฉื›ืœ ืื—ื“ ืžื”ื ืžืžืœื ืชืคืงื™ื“ ืžืกื•ื™ื ื‘ืžื ื’ื ื•ืŸ ื•ืžืชื—ื™ืœ ื‘ืกืžืœ "@". ื”ื”ืขืจื” @Entity ืžืฆื™ื™ื ืช ืœ-Spring Boot ืฉื ืชื•ื ื™ ื”ืžื—ืœืงื” ื”ื‘ืื™ื ืฉื™ื™ื›ื™ื ืœ-"Entity", ื•-@Id ื•-@GeneratedValue ืžืฆื™ื™ื ื™ื ืืช ื”ืฉื“ื” ื”ื ื‘ื—ืจ ื›ืžื–ื”ื” ืขื ื™ืฆื™ืจื” ืื•ื˜ื•ืžื˜ื™ืช ืฉืœ ืื™ื˜ืจื˜ื•ืจ ื‘ืขืช ืขื™ื‘ื•ื“ ืžืขืจืš ืžื™ื“ืข. ืื ื™ ืžืฉืžื™ื˜ ื‘ื›ื•ื•ื ื” ืืช ื”ื•ืกืคืช Getter ื•-Setter ืกื˜ื ื“ืจื˜ื™ื™ื ื›ื“ื™ ืœื”ื’ื‘ื™ืจ ืืช ื”ืงื•ืžืคืงื˜ื™ื•ืช ืฉืœ ื”ืคื•ืจืžื˜ ื”ื•ื•ื™ื–ื•ืืœื™. ืœืื—ืจ ืžื›ืŸ, ืชื•ืš ื”ืชื—ืฉื‘ื•ืช ื‘ืฉื™ืžื•ืฉ ื‘ืžืกื“ ื ืชื•ื ื™ื ืœืื—ืกื•ืŸ ืจืฉื•ืžื•ืช, ืื ื• ืขื•ื‘ืจื™ื ืœืฉืœื‘ ื”ื‘ื ื‘ืคื™ืชื•ื— ืืคืœื™ืงืฆื™ื•ืช: ื ื™ืฆื•ืจ ืืช ืžืžืฉืง NoteRepository ื‘ืกืคืจื™ื™ืช "repository", ืืœืžื ื˜ ืžืงืฉืจ ื‘ืฉืจืฉืจืช ื”ื—ืœื™ืคื™ืŸ, ื•ื ื ื™ื— ืืช ื”ืžื™ืจื‘ ืžืื’ืจ ืžืชืื™ื ืœืขื‘ื•ื“ื” ื ื•ืกืคืช, ื”ืžืฆื™ื™ืŸ ืืช ื”ื™ืฉื•ืช ื”ืžืื•ื—ืกื ืช ื•ืืช ืื™ื˜ืจื˜ื•ืจ ื”ืžืกืคืจื™ื ื”ืฉืœืžื™ื ืฉื™ืฉ ืœื’ืฉืช ืืœื™ื”ื.
public interface NoteRepository extends JpaRepository<Note, Integer> {
}
ื‘ืขืฆื, ื–ื” ื”ื›ืœ. ืงืฆืจ ื•ืชืžืฆื™ืชื™. ื›ืขืช Spring Boot ื™ืฉืชืžืฉ ื‘ืจื›ื™ื‘ ืฉื ื•ืฆืจ ื›ื“ื™ ืœืืจื’ืŸ ืื™ื ื˜ืจืืงืฆื™ื•ืช ืขื ืžืกื“ ื”ื ืชื•ื ื™ื. ื™ืฉื ื ืกื•ื’ื™ื ืจื‘ื™ื ื™ื—ืกื™ืช ืฉืœ ืžืื’ืจื™ื ืžื“ื•ืจ ืงื•ื“ื ืขื ืคื•ื˜ื ืฆื™ืืœ ืคืขื•ืœื” ืžืฉืชื ื”. JpaRepository ื ืžืฆื ื‘ืจืืฉ ื”ืกื•ืœื ื•ื™ืฉ ืœื• ืืช ื”ืคื•ื˜ื ืฆื™ืืœ ื”ืจื‘ ื‘ื™ื•ืชืจ, ื›ื•ืœืœ CrudRepository ื•-PageAndSortingRepository ืฉืžืชื—ืชื™ื•. ืœื ื ืจื—ื™ืง ื™ื•ืชืจ ื•ื ืกื˜ื” ืžื”ื ื•ืฉื, ื›ื™ ื—ืœืง ืžื”ื“ืงื•ื™ื•ืช ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืืชืจ Pivotel ื‘ืชื™ืขื•ื“ ื”ื˜ื›ื ื™. ื›ืขืช, ืœืื—ืจ ื”ื˜ืžืขืช ืชืžื•ื ืช ื”ื ืชื•ื ื™ื ื•ืฆื™ื•ืŸ ืฉื™ื˜ื•ืช ืชืงืฉื•ืจืช ื‘ืฆื“ ื”ืืคืœื™ืงืฆื™ื”, ืขืœื™ืš ืœืฉื™ื ืœื‘ ืœื™ืฆื™ืจืช ืžืกื“ ื ืชื•ื ื™ื MySQL ื‘ืกื‘ื™ื‘ื” ื”ื—ื™ืฆื•ื ื™ืช ื”ืžืชืื™ืžื” "MySQL Workbench", ื”ืžื•ืชืงื ืช ืžืจืืฉ ืขืœ ืคืœื˜ืคื•ืจืžืช ืฉื•ืœื—ืŸ ื”ืขื‘ื•ื“ื” ื‘ื”ืจื›ื‘ื” ืžื”ืžืคืชื— ื”ืจืฉืžื™ ืขื ื—ื‘ื™ืœื•ืช ื ื•ืกืคื•ืช ืœื™ืฆื™ืจืช ืฉืจืช ืžืงื•ืžื™:
Conquest Spring Boot - 4
ืœืื—ืจ ืžื›ืŸ, ื‘ืขืงื‘ื•ืช ื”ื•ืจืื•ืช ื”ืกื‘ื™ื‘ื” ืœืื—ืจ ืœื—ื™ืฆื” ืขืœ ื”ืื™ื™ืงื•ืŸ ืขื ื”ืฉืจืช ื”ืžืงื•ืžื™ ื”ื ื•ื›ื—ื™ ื‘ื—ืœื•ืŸ ื”ืจืืฉื™, ืื ื• ื™ื•ืฆืจื™ื ื“ื™ืื’ืจืžืช ื˜ื‘ืœื” ืœืคื™ ืฉื“ื•ืช ื”ื™ืฉื•ืช ืฉืœื ื• (ื”ืขืจื”) ื•ืžืžืœืื™ื ืื•ืชื” ื‘ื ืชื•ื ื™ื ื”ืžืชืื™ืžื™ื. ื™ืฉ ืฆื•ืจืš ืœื”ื‘ื”ื™ืจ ื‘ื ืคืจื“ ืืช ื”ื“ืงื•ื™ื•ืช ืฉืœ ื ื™ื‘ MySQL, ื”ื“ื•ืจืฉื™ื ืชืฉื•ืžืช ืœื‘ ื‘ื“ื—ื™ืคื•ืช ื›ื“ื™ ืœื”ืฉื™ื’ ืืช ื”ืชื•ืฆืื” ื”ืจืฆื•ื™ื” ื‘ื”ืฆืœื—ื”:
  • ืื™ืŸ ืกื•ื’ ื‘ื•ืœื™ืื ื™ ื ืคืจื“ ื›ื›ื–ื”. ื›ืœ ืคืขื•ืœื•ืช ืขื™ื‘ื•ื“ ื‘ืงืฉื•ืช ื™ืžื™ืจื• "true" ืื• "false" ืœืขืจืš ื”ืกื™ื‘ื™ื•ืช "1" ืื• "0", ื‘ื”ืชืืžื”;
  • ื”ืชืืจื™ืš ืžืื•ื—ืกืŸ ื›ื•ืœื• ื‘ืกื•ื’ ื—ื•ืชืžืช ื–ืžืŸ. ืื ืืชื” ืžืฉืชืžืฉ ื‘-Date, ื”ืžื•ื›ืจ ืขื“ ื”ื™ืกื•ื“, ืชืฆื˜ืจืš ืœื”ื’ื‘ื™ืœ ืืช ืขืฆืžืš ืจืง ืœืžื™ืงื•ื ื‘ืœื•ื— ื”ืฉื ื”.
Conquest Spring Boot - 5
ืœืื—ืจ ื”ื”ืฉืœืžื” ื”ืกื•ืคื™ืช ืฉืœ ืฉืœื‘ื™ ื”ื”ื›ื ื”, ืื ื• ืžืฆื™ื™ื ื™ื "MySQL Workbench" ื›ื“ื™ ืœืฉืœื•ื— ื ืชื•ื ื™ื ืœืฉืจืช ื”ืžืงื•ืžื™ ืขืœ ื™ื“ื™ ืœื—ื™ืฆื” ืขืœ ืกืžืœ ื”"ื‘ืจืง" ื‘ืกืจื’ืœ ื”ื›ืœื™ื. ื›ืขืช, ืื ื”ื•ืกืคืช ื”ืžื™ื“ืข ื”ื•ืฉืœืžื” ื›ื”ืœื›ื”, ื ื•ื›ืœ ืœื—ื–ื•ืจ ื‘ื‘ื™ื˜ื—ื•ืŸ ืœ-IDE ื”ืžืงื•ืจื™ ืฉืœื ื• ื›ื“ื™ ืœื”ืžืฉื™ืš ื‘ืคื™ืชื•ื— ืขืœ ื™ื“ื™ ื”ื•ืกืคืช ืชืฆื•ืจืช ืžืกื“ ื”ื ืชื•ื ื™ื ื”ื ื•ื›ื—ื™ืช ืœ- application.properties (ื‘ื“ืจืš ื›ืœืœ ืžืžื•ืงืžืช ื‘ืกืคืจื™ื™ืช "resources"):
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
ื•ืœื‘ืกื•ืฃ ืžื—ื™ื™ื‘ ืืช ื”ื™ืฉื•ืช Note ืœ-MySQL ื‘ืืžืฆืขื•ืช ื”ืขืจื•ืช. @Table ืžืฆื™ื™ืŸ ืืช ื”ืฉื™ืžื•ืฉ ื‘ื˜ื‘ืœื” ืขื ื”ืฉื ื•ื”ืกื›ื™ืžื” ืฉื ื‘ื—ืจื•, ื•-@Column ืžืฆื™ื™ืŸ ืฉื”ืžืฉืชื ื™ื ืฉื™ื™ื›ื™ื ืœืฉื“ื” ืกืคืฆื™ืคื™.
@Entity
@Table(name = "test", schema = "test", catalog = "")
public class Note {

   @Id
   @GeneratedValue
   private int id;
   @Column(name = "message")
   private String message;
   @Column(name = "date")
   private Date date;
   @Column(name = "done")
   private boolean done;

   public Note() {
   }

   public Note(String message) {
       this.message = message;
       this.date = new Date();
       this.done = false;
   }
}

ื”ืฆื’ ืื• ืžืžืฉืง ืžืฉืชืžืฉ

ืœืžืจื‘ื” ื”ืฆืขืจ, ืื ื• ื™ื›ื•ืœื™ื ืœื•ืžืจ ื‘ื‘ื˜ื—ื” ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื: "ื•ื™ื–ื•ืืœื™ื–ืฆื™ื” ืฉืœ ื”ืืคืœื™ืงืฆื™ื” ืชื”ืคื•ืš ืœืื‘ืŸ ื”ื ื’ืฃ ื”ืขื™ืงืจื™ืช ืœืœื ืฉืžืฅ ืฉืœ ื™ื“ืข ืชื™ืื•ืจื˜ื™ ืื• ืžืขืฉื™." ืœืžืขืŸ ื”ืืžืช, ื”ืจื›ื™ื‘ ื”ืงื“ืžื™ ืชืคืก ื›ืžื•ืช ืžื“ื”ื™ืžื” ืžื›ืžื•ืช ื”ืขื‘ื•ื“ื” ื”ื›ื•ืœืœืช ื•ืจื™ืกืง ืืช ื”ืขืฆื‘ื™ื ืฉืœื™ ื‘ื‘ื™ื˜ื—ื•ืŸ ืœืื•ืจืš ืชืงื•ืคื” ืืจื•ื›ื”. ืื‘ืœ ื‘ื–ื›ื•ืช ื”ืคืฉื˜ื•ืช ื”ืžื“ื”ื™ืžื” ืฉืœ Thymeleaf, ืืคืฉืจ ื”ื™ื” ืœืžืฆื•ื ืคืฉืจื” ืžืชืื™ืžื” ืœืื—ืจ ืกื“ืจื” ืฉืœ ืชื‘ื•ืกื•ืช ืงืกื•ืžื•ืช. ื“ื™ื•ืŸ ื ื•ืกืฃ ื™ื”ื™ื” ืขืœ ื”ืžื•ืจื›ื‘ื•ื™ื•ืช ืฉืœ ื”ืฉื™ืžื•ืฉ ื‘ืžื ื•ืข ื”ื ื‘ื—ืจ, ืื ื›ื™ ื”ืจืขื™ื•ืŸ ื”ื›ืœืœื™ ื“ื‘ืง ื‘ืขืžื“ื” ื“ื•ืžื”. ื”ื˜ื›ื ื™ืงื” ื”ืขื™ืงืจื™ืช ื”ื™ื ื”ื™ื›ื•ืœืช ืœื”ืฉืชืžืฉ ื‘-HTML ื”ื˜ื”ื•ืจ ื‘ื™ื•ืชืจ ื•ืœื”ืจื›ื™ื‘ ืืช ื”ืชืฆื•ื’ื” ื”ืกื•ืคื™ืช ืžืคืจื’ืžื ื˜ื™ื ื‘ื•ื“ื“ื™ื ื›ื“ื™ ืœืžื ื•ืข ื—ื–ืจื•ืช ืžืจื•ื‘ื•ืช ืฉืœ ืงื˜ืขื™ื ื–ื”ื™ื. ื ื ื™ื— ืฉืืจื›ื™ื˜ืงื˜ื•ืจืช ืžืžืฉืง ื”ืžืฉืชืžืฉ ืžื•ืจื›ื‘ืช ืžืขืžื•ื“ ืจืืฉื™ ื”ืžื•ืจื›ื‘ ืžืกืจื’ืœ ื ื™ื•ื•ื˜ ืขื ืคืงื“ื™ื (ื”ื•ืกืคืช ืขืจืš ื—ื“ืฉ, ื—ื–ืจื” ืœืขืžื•ื“ ื”ืจืืฉื™) ื•ื˜ื‘ืœื” ื“ื™ื ืžื™ืช ืœื”ืฆื’ืช ื™ืฉื•ื™ื•ืช ืžืžื•ื™ื ื•ืช ืœืคื™ ื–ืžืŸ ื”ื•ืกืคืช ื”ื”ืขืจื” ื‘ืจืฉื™ืžื” ืขื•ืœื” (ASC). ืื• ื”ืงื˜ื ื” (DESC) ื›ื™ื•ื•ืŸ.ืžืฉืžืขื•ื™ื•ืช. ื”ื‘ื” ื ื™ืงื— ื›ืžื™ืงื•ื ื”ืกื˜ื ื“ืจื˜ื™ ืืช ื”ืชืฆื•ื’ื” ืฉืœ ื›ืœ ื”ืจืฉื•ืžื•ืช ื‘ืกื“ืจ ืขื•ืœื”. ืขืœ ืคื™ ื”ืžื“ื™ื ื™ื•ืช ื”ื”ื™ืจืจื›ื™ืช ืฉืœ ืžื ื•ืข ื”ืชื‘ื ื™ื•ืช ืฉื ื‘ื—ืจ, ืจื›ื™ื‘ื™ ื”ื”ื“ืžื™ื” ืฉืœ ื”ืจื›ื™ื‘ ืฆืจื™ื›ื™ื ืœื”ื™ื•ืช ืžืžื•ืงืžื™ื ื‘ืขื ืฃ "ืชื‘ื ื™ื•ืช" ื‘ืกืคืจื™ื™ืช "ืžืฉืื‘ื™ื". ื›ืชื•ืฆืื” ืžื›ืš, ืžื ื™ืคื•ืœืฆื™ื•ืช ื ื•ืกืคื•ืช ืขื ืจื›ื™ื‘ื™ื ืœื•ืงื—ื•ืช ื‘ื—ืฉื‘ื•ืŸ ืืช ื”ืชื ืื™ื ืฉื”ื•ืฆืขื•. ื‘ื•ืื• ื ื™ืฆื•ืจ ืขืžื•ื“ ืจืืฉื™ ืขื ื”ืฉื "ืื™ื ื“ืงืก" (ืื• ื›ืœ ืฉื ืื—ืจ ืœืคื™ ื”ืขื“ืคื” ืื™ืฉื™ืช) ื‘ืชื‘ื ื™ืช html5. ืœื“ื•ื’ืžื”:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/head :: head"></head>
<body>
<div class="container">
   <div th:replace="fragments/header :: header"></div>
   <div th:if="${not #lists.isEmpty(notes)}">
       <div th:replace="operations/list :: notebook"></div>
   </div>
   <div th:replace="fragments/footer :: footer"></div>
</div>
</body>
</html>
ื•ื›ืš, ื‘ื•ืื• ื ืคืจืง ืืช ืžืจื›ื™ื‘ื™ ื”ืžืคืชื— ืฉืœ ื”ื™ื™ืฉื•ื ื”ืกื•ืคื™. Thymeleaf ืžืฉืชืžืฉ ื‘ืชื—ื‘ื™ืจ ื ืคืจื“ ื›ื“ื™ ืœืฆื™ื™ืŸ ืืช ื”ืฉื™ืžื•ืฉ ื‘ืคืจื•ืฆื“ื•ืจื•ืช ื•ืžืชื—ื™ืœ ื‘ืžื™ืœืช ื”ืžืคืชื— "th:", ื”ืงื™ืฉื•ืจ ืœืกืคืจื™ื™ื” ืฉืื™ืชื• ื ื›ืœืœ ื‘ื”ื›ืจื— ื‘ืชื’ ื”ืคืชื™ื—ื” <html>.
<div th:if="${not #lists.isEmpty(notes)}">
ืคืขื•ืœืช "ืื" ืื™ื ื” ืฉื•ื ื” ืœื—ืœื•ื˜ื™ืŸ ืžื”ื“ืจืš ื”ืจื’ื™ืœื” ืœืขืฉื•ืช ื“ื‘ืจื™ื ื•ื‘ื•ื“ืงืช ืืช ืชื›ื•ื ืช "ื”ืขืจื•ืช" ื”ื ื›ื ืกื•ืช ืขื‘ื•ืจ ื ื•ื›ื—ื•ืชื ืฉืœ ืื•ื‘ื™ื™ืงื˜ื™ื ืœืชืฆื•ื’ื” ื ื•ืกืคืช. ืจืื•ื™ ืœื”ื–ื›ื™ืจ ื‘ื ืคืจื“ ืืช ื”ื—ืคื™ืคื” ืฉืœ ื”ื ื•ืฉื ืขื ื”ืฉื™ืžื•ืฉ ื‘ื‘ืงืจ, ืชื•ืš ื”ืชื—ืฉื‘ื•ืช ื‘ืฉื™ืžื•ืฉ ื‘ื• ืœืืจื’ื•ืŸ ื”ืื™ื ื˜ืจืืงืฆื™ื” ืฉืœ ื”ืžื•ื“ืœ ื•ื”ื“ืžื™ื”. ืจื’ืขื™ื ืžืขื•ืจืคืœื™ื ืจื‘ื™ื ืžืชื’ื‘ืฉื™ื ื‘ืขืชื™ื“, ืคืฉื•ื˜ ื—ื–ื•ืจ ืื—ื•ืจื” ืื ืชืจืฆื”.
<head th:replace="operations/list :: notebook"></head>
ืคืขื•ืœืช "ื”ื—ืœืคื”" ืžืฆื™ื™ื ืช ื”ื—ืœืคื” ืฉืœ "ืกื˜ื‘" ืื• ื‘ืœื•ืง ืคืขื™ืœ ืขื ืงื˜ืข ื ื‘ื—ืจ ืžื”ื“ืฃ ื”ื ื•ื›ื—ื™ ืื• ื”ื ืคืจื“ - ื”ืžืงืจื” ื”ืื—ืจื•ืŸ ื ืฆืคื” ื‘ื‘ื™ืจื•ืจ ื‘ื“ื•ื’ืžื”. ืื ื• ืžืขืชื™ืงื™ื ืืช ื”ืคืจื’ืžื ื˜ ืฉื ืงืจื "ืžื—ื‘ืจืช" ืž-"list.html" ืฉืœ ืกืคืจื™ื™ืช "ืคืขื•ืœื•ืช" ืืœ <div></div> ืฉืœ ืงื•ื‘ืฅ ื”"ืื™ื ื“ืงืก", ื•ืžื—ืœื™ืฃ ืœื—ืœื•ื˜ื™ืŸ ืืช ื”ืชื•ื›ืŸ ื‘ื™ืขื“ ื”ืกื•ืคื™. ืœื™ื•ืฆื ื™ืฉ ืืช ื”ืชื•ื›ืŸ ื”ื‘ื:
<!DOCTYPE html>
<!--suppress ALL -->
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:th="http://www.thymeleaf.org">

<div th:fragment="notebook">
   <table class="table table-bordered table-hover horizontal-align">
       <thead>
       <tr>
           <th style="width: 5%">#</th>
           <th style="width: 60%">Message</th>
           <th class="dropdown" style="width: 20%">Date
               <a th:href="@{'/sort/{sortDate}' (sortDate = 'ASC')}"><i class="fa fa-chevron-circle-up"></i></a>
               <a th:href="@{'/sort/{sortDate}' (sortDate = 'DESC')}"><i class="fa fa-chevron-circle-down"></i></a>
           </th>
           <th style="width: 5%">Done</th>
           <th style="width: 5%">Edit</th>
           <th style="width: 5%">Delete</th>
       </tr>
       </thead>
       <tbody>
       <tr th:each="note : ${notes}">
           <td th:text="${note.id}" style="text-align: center">#</td>
           <td th:text="${note.message}">Message</td>
           <td th:text="${#dates.format(note.date, 'EEE, d MMM yyyy HH:mm')}" style="text-align: center">Date</td>
           <td style="text-align: center">
               <i th:if="${note.done} == true" class="fa fa-plus-square-o" style="font-size:20px;color:#337ab7"></i>
               <i th:if="${note.done} == false" class="fa fa-minus-square-o" style="font-size:20px;color:#337ab7"></i>
           </td>
           <td style="text-align: center"><a th:href="@{'/edit/{id}'(id=${note.id})}"><i class="fa fa-edit" style="font-size:20px"></i></a></td>
           <td style="text-align: center"><a th:href="@{'/delete/{id}'(id=${note.id})}"><i class="fa fa-trash" style="font-size:20px"></i></a></td>
       </tr>
       </tbody>
   </table>
</div>
</html>
ื ื—ื–ื•ืจ ืœืกืงื™ืจื” ื”ืงื•ื ืกื˜ืจื•ืงื˜ื™ื‘ื™ืช ื•ื ืขื‘ื•ืจ ืขืœ ืคื•ื ืงืฆื™ื•ืช Thymeleaf ื”ืžืฉืžืฉื•ืช ืœืคื™ ื”ืกื“ืจ, ืชื•ืš ื”ืฉืžื˜ืช ืชื—ื‘ื™ืจ HTML ืื• ืกื’ื ื•ื ื•ืช ื’ืจืคื™ื™ื ืกื˜ื ื“ืจื˜ื™ื™ื ื‘ืฉื™ืžื•ืฉ, ื•ื ืชืžืงื“ ื‘ืžื™ื•ื—ื“ ื‘ื”ื‘ื ืช ืžื ื’ื ื•ืŸ ืžื ื•ืข ื”ืชื‘ื ื™ืช.
<div th:fragment="notebook">
ืคืขื•ืœืช "fragment" ืžืฆื™ื™ื ืช ืืช ืฉื ื”ืคืจื’ืžื ื˜ ื•ืžืืคืฉืจืช ืœื”ืฉืชืžืฉ ื‘ืชื•ื›ืŸ ื”ื‘ืœื•ืง ืขื‘ื•ืจ ื”ืคืงื•ื“ื” "replace". ื™ืชืจ ืขืœ ื›ืš! ืฉื™ืžื•ืฉื™ื ืžืจื•ื‘ื™ื ื‘ืชื•ืš ืขืžื•ื“ ื‘ื•ื“ื“ ืื™ื ื ื ื›ืœืœื™ื ื‘ืฉื•ื ืื•ืคืŸ, ื“ื‘ืจ ื”ืžื‘ื™ื ืฉื•ื‘ ืืช ื”ืื ืœื•ื’ื™ื” ืขื ื ื”ืœื™ื ืื• ืคื•ื ืงืฆื™ื•ืช ื‘ืฉืคื•ืช ืชื›ื ื•ืช.
<a th:href="@{'/sort/{sortDate}' (sortDate = 'ASC')}">
ืงืจื™ืื” ืœื‘ื™ืื•ืจ @PostMapping ืžืฉืžืฉืช ื‘ื‘ืงืจ ืขื ื”ืžื™ืคื•ื™ "/sort/{sortDate}", ื›ืืฉืจ {sortDate} ื”ื™ื ืชื›ื•ื ืช ื›ื™ื•ื•ืŸ ื”ืžื™ื•ืŸ ื”ื™ื•ืฆื. ืžืฉื”ื• ื“ื•ืžื” ื ื™ืชืŸ ืœืจืื•ืช ื‘ื‘ืœื•ืง ื”ื‘ื, ืฉืžื•ืกื™ืฃ ืฉื™ื ื•ื™ ื“ื™ื ืžื™ ื‘ื”ืชืื ืœืžื™ืงื•ื ื”ืืœืžื ื˜ ืฉื ื‘ื—ืจ ืขืœ ื™ื“ื™ ื”ืžืฉืชืžืฉ ื‘ืœื•ืœืืช ื”ืื™ื˜ืจืฆื™ื”:
<a th:href="@{'/edit/{id}'(id=${note.id})}">
<tr th:each="note : ${notes}">
ืกืคื™ืจืช ืขืจื›ื™ื ื“ื•ืžื” ืžืื•ื“ ืœืฉื™ืžื•ืฉ ื”ืžื•ื›ืจ ืฉืœ ื‘ืœื•ืง for ื‘ืชื—ื‘ื™ืจ Java: ื”ืžืฉืชื ื” "note" ืœื•ืงื— ืืช ื”ืืœืžื ื˜ ื”ื ื•ื›ื—ื™ ืžืžืขืจืš ืชื›ื•ื ืช ื”ืงืœื˜ ${notes} - ืžืขืจืš ืฉืœ ื™ืฉื•ื™ื•ืช - ื•ืžืฉืžืฉ ืœืฉื™ื ื•ื™ ื”ืขืจื›ื™ื ืžืื•ื—ืจ ื™ื•ืชืจ. ืœืžืขืŸ ื”ืืžืช, ื ื•ื›ืœ ืœื”ืงื“ื™ืฉ ืžืืžืจ ื ืคืจื“ ืœืจืฉื™ืžืช ื”ืžื’ื•ื•ืŸ ื”ืจื—ื‘ ืฉืœ ื™ื›ื•ืœื•ืช Thymeleaf ืขื ื“ื•ื’ืžืื•ืช ืœื™ื™ืฉื•ื ืžืขืฉื™ - ืžื ื•ืข ื”ืชื‘ื ื™ื•ืช ืคืฉื•ื˜ ื‘ื™ื•ืชืจ ื•ืื™ื ื• ื“ื•ืจืฉ ืœืžื™ื“ื” ื›ืœืœ ืžื˜ืขืŸ ืžืจืฉื™ื ืฉืœ ืชื—ื‘ื™ืจ ื ื•ืกืฃ. ื”ืคื•ื ืงืฆื™ื•ืช ื”ืžืชื•ืืจื•ืช ืœืขื™ืœ ืžืชื•ืืจื•ืช ื‘ืชื™ืขื•ื“ ื”ื˜ื›ื ื™ ื‘ืืชืจ ื”ืจืฉืžื™ ืฉืœ ื”ืžืคืชื—ื™ื ื•ื”ืŸ ื‘ืขืœื•ืช ื—ืฉื™ื‘ื•ืช ืžืจื›ื–ื™ืช ื‘ืืจื’ื•ืŸ ื”ืชืงืฉื•ืจืช ืขื ื”ืงืฆื” ื”ืื—ื•ืจื™. ืœื›ืŸ, ืืชื” ื™ื›ื•ืœ ืœืขื‘ื•ืจ ื‘ื‘ื™ื˜ื—ื•ืŸ ืœื—ืœืง ื”ื‘ื ื•ื”ืื—ืจื•ืŸ. ื›ืžื•ื‘ืŸ, ืขืœ ื™ื“ื™ ืฆื™ืจื•ืฃ ืฉืืจ ืžืจื›ื™ื‘ื™ ื”ื”ื“ืžื™ื” ื‘ืงื™ืฉื•ืจ ืœืืคืœื™ืงืฆื™ื” ื”ืžื•ื’ืžืจืช ื‘ืกื•ืฃ ื”ืžืืžืจ.

ื‘ืงืจ, ืžื ื”ืœ ื‘ื—ื‘ืจื” ืงื˜ื ื”

"ืื‘ืŸ ื”ื™ืกื•ื“ ื‘ืืจื›ื™ื˜ืงื˜ื•ืจื” ืฉืœ ืืคืœื™ืงืฆื™ื™ืช ืื™ื ื˜ืจื ื˜" - ืื•ืœื™ ืื™ืŸ ื“ืจืš ืœืžืฆื•ื ืชื™ืื•ืจ ืžื“ื•ื™ืง ื™ื•ืชืจ ืฉืœ ื—ืฉื™ื‘ื•ืช ืจื›ื™ื‘ ื”-Controller ื‘ืืจื’ื•ืŸ ืขื‘ื•ื“ืช ื”ืชื•ื›ื ื™ืช: ืจื•ื‘ ื”ืคืขื•ืœื•ืช ืžืชื‘ืฆืขื•ืช ื‘ื“ื™ื•ืง ืขืœ ื™ื“ื™ ื”ืืœืžื ื˜ ื”ืžืงืฉืจ ื‘ื™ืŸ ื”ื“ื’ื ื•ื”ื ื•ืฃ. ื”ื•ื“ื•ืช ืœืžื›ื ื™ืงืช ื”ืคืขื•ืœื” ืฉืœ Spring Boot, ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ื‘ื™ื˜ื—ื•ืŸ ื‘ืฉื™ื˜ื•ืช ืžื™ืคื•ื™ ื•ื‘ืงืฉื•ืช GET/POST ืœืœื ื›ืœ ื‘ืขื™ื”, ื•ืœื—ื‘ืจ ืื•ื˜ื•ืžื˜ื™ืช ืืช ืžืื’ืจ ื”ื ืชื•ื ื™ื. ื‘ื•ืื• ื ื™ืฆื•ืจ ืืช ื”ืžื—ืœืงื” NoteController ื‘ืงื•ื‘ืฅ ื ืคืจื“ ื‘ืกืคืจื™ื™ืช "ื‘ืงืจื™ื", ืฉื•ื‘ ื‘ื”ืชื™ื™ื—ืกื•ืช ืœืฉื™ืžื•ืฉ ื‘ื”ืขืจื” ื”ืžืชืื™ืžื”:
@Controller
public class NoteController {

   private NoteService service;

   @Autowired
   public void setNoteService(NoteService service) {
       this.service = service;
   }

   @GetMapping("/")
   public String list(Model model) {
       return "index";
   }
}
ืขื™ืŸ ืงืคื“ื ื™ืช ืขืฉื•ื™ื” ืœื”ื‘ื—ื™ืŸ ื‘ืฉื™ื ื•ื™ ื—ืฉื•ื‘ ื‘ืขื™ืฆื•ื‘ ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”ืืคืœื™ืงืฆื™ื” ื”ืงืฉื•ืจื” ืœื”ื•ืกืคืช ืฉื™ืจื•ืช ื›ื“ื™ ืœื‘ื•ื“ื“ ืืช ื”ื”ื™ื’ื™ื•ืŸ ื”ืขืกืงื™ ืžืขื‘ื•ื“ื” ืขื ืฉื™ืจื•ืช ื ื™ื”ื•ืœ ืžืกื“ื™ ื”ื ืชื•ื ื™ื. ื”ืคืขื•ืœื•ืช ืฉื”ื•ืฉืœืžื• ื ื“ืจืฉื•ืช ื›ื“ื™ ืœื”ื’ื‘ื™ืจ ืืช ื”ืจื‘ื’ื•ื ื™ื•ืช ืฉืœ ื”ืžื•ืฆืจ ื”ืžื•ื’ืžืจ ื•ืœืกืคืง ืžืจื—ื‘ ืจื—ื‘ ืœืฉื™ื ื•ื™ ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืฉืœ ืžืžืฉืง ื”ืžืฉืชืžืฉ ืœืœื ืฆื•ืจืš ื‘ืฉื™ื ื•ื™ื™ื ื‘ืฉื™ื˜ื•ืช ื”ืชืงืฉื•ืจืช ืขื ืžืกื“ ื”ื ืชื•ื ื™ื. ื”ื™ื™ืฆื•ื’ ื”ืกื˜ื ื“ืจื˜ื™ ื‘ืฉื•ื ืื•ืคืŸ ืœื ื‘ื•ืœื˜ ืžื”ืžื•ืŸ ื”ื“ื•ืžื™ื: ื”ืžืžืฉืง ืžืžื•ืงื ื‘ืกืคืจื™ื” ื ืคืจื“ืช ื•ืžื™ื•ืฉื ืขืœ ื™ื“ื™ ืžื—ืœืงื” ืขื ื”ืขืจืช @Service ืœื–ื™ื”ื•ื™ Spring Boot:
public interface NoteService {
   Note getNoteById(Integer id);
   void saveNote(Note note);
   void updateNote(Integer id, String message, boolean done);
   void deleteNote(Integer id);
   List<Note> findAll();
}

@Service
public class NoteServiceImpl implements NoteService{

   private NoteRepository repository;

   @Autowired
   public void setProductRepository(NoteRepository repository) {
       this.repository = repository;
   }

   @Override
   public Note getNoteById(Integer id) {
       return repository.findOne(id);
   }

   @Override
   public void saveNote(Note note) {
       repository.save(note);
   }

   @Override
   public void updateNote(Integer id, String message, boolean done) {
       Note updated = repository.findOne(id);
       updated.setDone(done);
       updated.setMessage(message);
       repository.save(updated);
   }

   @Override
   public void deleteNote(Integer id) {
       repository.delete(id);
   }

   @Override
   public List<Note> findAll() {
       return repository.findAll();
   }
}
ื‘ื•ืื• ื ื—ื–ื•ืจ ืœืกืงื•ืจ ืืช ื”ื‘ืงืจ ื•ื ื‘ื—ืŸ ืืช ื”ืžื•ืจื›ื‘ื•ื™ื•ืช ืฉืœ ืืจื’ื•ืŸ ื”ืขื‘ื•ื“ื” ื‘ืฉื™ื˜ื•ืช Spring Boot. ื”ื”ืขืจื” @Autowired ืžืฆื™ื™ื ืช ืืช ื”ืฆื•ืจืš ืœืื’ื“ ืฉื™ืจื•ืช ืื•ื˜ื•ืžื˜ื™ืช ืœืžืฉืชื ื” ืžื•ื’ื“ืจ ืžื”ืกื•ื’ ื”ืžืชืื™ื ื•ืœื™ืฆื•ืจ ื—ื™ื‘ื•ืจ ืขื ืžืกื“ ื”ื ืชื•ื ื™ื. ื™ืฉ ืœื”ืงื“ื™ืฉ ืชืฉื•ืžืช ืœื‘ ืจื‘ื” ื™ื•ืชืจ ืœื“ืจืš ืฉื‘ื” ื”ืชืฆื•ื’ื” ืžืชืงืฉืจืช, ื”ืžืฆื•ื™ื ืช ืขืœ ื™ื“ื™ ื”ื”ืขืจื” @GetMapping ("/"), ื”ืžื—ื–ื™ืจื” ื“ืฃ ื‘ืฉื "ืื™ื ื“ืงืก" ื‘ืขืช ืงื‘ืœืช ืงืจื™ืื” ืœ-localhost:8080. ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ื’ื™ืฉื” ืื—ืจืช, ืœืฆื™ื™ืŸ ืืช ื”ืชื™ืื•ืจ ื”ืžื•ืจื—ื‘ @RequestMapping(value = "/", method = RequestMethod.GET) ืื• ืœื”ื—ืœื™ืฃ ืืช ืกื•ื’ ื”ื”ื—ื–ืจื” ื‘-ModelAndView ืžื•ื›ืŸ. ืขื ื–ืืช, ืขืœ ืคื™ ืžืฆื‘ ื”ื ื™ืกื™ื•ืŸ ื”ื ื•ื›ื—ื™ ื‘ื™ื™ืฉื•ื ืžืขืฉื™, ืื ื™ ืœื ืฉื ืœื‘ ืœื”ื‘ื“ืœื™ื ืžื”ื•ืชื™ื™ื ื‘ืชื•ืฆืื” ื”ืกื•ืคื™ืช ื•ืžืฉืชืžืฉ ื‘ืืคืฉืจื•ืช ื”ืจื’ื™ืœื”. ื‘ื•ืื• ื ืจื—ื™ื‘ ืืช ื”ื‘ืงืจ ืขืœ ื™ื“ื™ ื”ื•ืกืคืช ืืœืžื ื˜ื™ื ื—ื“ืฉื™ื ื‘ืืžืฆืขื•ืช ื›ืจื˜ื™ืกื™ื™ื” ื ื•ืกืคืช. ืœืื—ืจ ืฉื”ืžืฉืชืžืฉ ืœื•ื—ืฅ ืขืœ ืืœืžื ื˜ ื‘ืกืจื’ืœ ื”ื ื™ื•ื•ื˜, @GetMapping("/new") ื ืงืจื ื•ืžื•ืคื ื” ืœื“ืฃ "ื—ื“ืฉ" ืžืกืคืจื™ื™ืช "ืคืขื•ืœื•ืช", ื•ืžื—ื–ื™ืจ ืคืจืžื˜ืจ ื‘ืฉื "ื”ื•ื“ืขื”" ื‘ืขืช ืื™ืฉื•ืจ ื”ื ืชื•ื ื™ื ืฉื”ื•ื–ื ื• ื‘ืืžืฆืขื•ืช ื”ื›ืคืชื•ืจ ื•ื”ืคื ื™ื” ืžื—ื“ืฉ ืœื‘ืœื•ืง ื”ืจืืฉื™. ื”ืฆื•ืจืš ื‘ื”ืชืืžื” ืžืœืื” ืฉืœ ืฉื ื”ืžืฉืชื ื” ื‘ื—ืœื•ืŸ ื”ืงืœื˜ ืขื ืฉื ื”ืขืจืš ื”ืžื•ืขื‘ืจ ื“ื•ืจืฉ ืื–ื›ื•ืจ ืžื™ื•ื—ื“.
<input type="text" class="form-control" id="message" th:name="message" placeholder="Enter your note." maxlength="100"/>
@GetMapping("/new")
public String newNote() {
   return "operations/new";
}

@PostMapping("/save")
public String updateNote(@RequestParam String message) {
   service.saveNote(new Note(message));
   return "redirect:/";
}
ื˜ื›ื ื™ืงื” ื“ื•ืžื” ืžืฉืžืฉืช ืœืขื“ื›ื•ืŸ ืจืฉื•ืžื”. ืœืื—ืจ ืœื—ื™ืฆื” ืขืœ ื”ืคืงื“, ืžื™ืคื•ื™ @GetMapping("/edit/{id}") ื ืงืจื ื•ื”ืžื–ื”ื” ืžืžื—ืจื•ื–ืช ื›ืชื•ื‘ืช ื”ืืชืจ ืžื•ืขื‘ืจ, ื”ืชื›ื•ื ื” "ื”ืขืจื”" ืžืชื•ื•ืกืคืช ืขื ืขืจืš ืœืขืจื™ื›ื” ื ื•ืกืคืช. @RequestParam(value = "done", required = false) boolean done) ืฆื™ื•ืŸ ืขืจืš ืกืคืฆื™ืคื™ ืžืžืœื ืชืคืงื™ื“ ืžืคืชื— ื‘ืฉื™ืžื•ืฉ ื‘ืชื™ื‘ืช ื”ืกื™ืžื•ืŸ ื‘ืขืช โ€‹โ€‹ืฉื™ืžื•ืฉ ื‘ืžื ื•ืข ื”ืชื‘ื ื™ืช Thymeleaf ื•ืžื•ื’ื“ืจ ื›"false" ื›ื‘ืจื™ืจืช ืžื—ื“ืœ.
@GetMapping("/edit/{id}")
public String edit(@PathVariable Integer id, Model model) {
   Note note = service.getNoteById(id);
   model.addAttribute("note", note);
   return "operations/edit";
}

@PostMapping("/update")
public String saveNote(@RequestParam Integer id, @RequestParam String message,
                      @RequestParam(value = "done", required = false) boolean done) {
   service.updateNote(id, message, done);
   return "redirect:/";
}
ื”ืกืจืช ืคืจื™ื˜ื™ื ืžืžืกื“ ื”ื ืชื•ื ื™ื ื”ื™ื ืคืฉื•ื˜ื” ื‘ื™ื•ืชืจ ื•ืื™ื ื” ื“ื•ืจืฉืช ื›ืœ ืžื ื™ืคื•ืœืฆื™ื” ืžืฉืžืขื•ืชื™ืช ืขืœ ื™ื“ื™ ืงืจื™ืื” ืœืคื•ื ืงืฆื™ื™ืช ื”ืฉื™ืจื•ืช ื”ืžืชืื™ืžื” ื‘ืืžืฆืขื•ืช ื”ืขืจืš ืฉืขื‘ืจ:
@GetMapping("/delete/{id}")
public String delete(@PathVariable Integer id) {
   service.deleteNote(id);
   return "redirect:/";
}
ื›ืขืช ื‘ื•ืื• ื ืขืฉื” ื”ืชืืžื•ืช ืงื˜ื ื•ืช ืœืคืจื’ืžื ื˜ื™ื ื”ืžื•ื’ืžืจื™ื ื•ื ืขื‘ื•ืจ ืœืชืงืฉื•ืจืช ืžืจื’ืฉืช ืขื MySQL ื‘ืืžืฆืขื•ืช ืฉืื™ืœืชื•ืช ืฉืื™ืœืชื•ืช ื‘-Spring Data JPA, ื”ื•ืกืคืช ื‘ื ืคืจื“ ืคื•ื ืงืฆื™ื” ืœื ื™ื”ื•ืœ ืกื™ื ื•ืŸ ืคืฉื•ื˜ ืœืคื ื™ ืกื’ื™ืจืช ื”ื‘ืงืจ.
@Controller
public class NoteController {

   private String sortDateMethod = "ASC";

   @GetMapping("/")
   public String list(Model model) {
       List<Note> notebook = filterAndSort();
       model.addAttribute("notes", notebook);
       model.addAttribute("sort", sortDateMethod);
       return "index";
   }

private List<Note> filterAndSort() {
   List<Note> notebook = null;
   switch (sortDateMethod) {
       case "ASC":
           notebook = service.findAllByOrderByDateAsc();
           break;
       case "DESC":
           notebook = service.findAllByOrderByDateDesc();
           break;
   }
   return notebook;
}

ื›ืœ ื›ืš ืงื˜ืŸ, ืื‘ืœ ื›ืœ ื›ืš ื—ืฉื•ื‘ ืฉืื™ืœืชื”.

ื–ื” ืžื‘ื™ืš ืœื”ื•ื“ื•ืช, ืกื™ื ื•ืŸ ืขืจื›ื™ื, ื‘ื ื™ื’ื•ื“ ืœืฆื™ืคื™ื•ืช, ื”ืชื‘ืจืจ ื›ืื‘ืŸ ื ื’ืฃ ื ื•ืกืคืช ื‘ืžื™ืœื•ื™ ื”ืžืฉื™ืžื” ื”ื˜ื›ื ื™ืช, ืชื•ืš ื”ืชื’ื‘ืจื•ืช ื‘ื‘ื™ื˜ื—ื•ืŸ ืขืœ ืกืฃ ื”ืžื•ืจื›ื‘ื•ืช ืฉื ืงื‘ืข ืขืœ ื™ื“ื™ ืขื™ืžื•ื“ - ืคื™ืจื•ืง ืžืขืจืš ื”ื ืชื•ื ื™ื ืœื“ืคื™ื ื ืคืจื“ื™ื ื‘ื’ื•ื“ืœ ืžืกื•ื™ื ืœืชืฆื•ื’ื” ื ื•ืกืคืช. ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉื”ืขื™ื™ืคื•ืช ื”ืžืฆื˜ื‘ืจืช ืขืฉืชื” ืืช ืฉืœื”, ืื‘ืœ... ื”ื”ืฉืจืื” ื”ื’ื™ืขื” ืœืื—ืจ ืžืคื’ืฉ ืžืงืจื™ ืœื—ืœื•ื˜ื™ืŸ ืขื ืฉืื™ืœืชื•ืช ืฉืื™ืœืชื•ืช.
public interface NoteRepository extends JpaRepository<Note, Integer> {
   List<Note> findAllByOrderByDateAsc();
   List<Note> findAllByOrderByDateDesc();
}
Spring Data JPA ืžืกืคืงืช ืืช ื”ื™ื›ื•ืœืช ืœื™ืฆื•ืจ ืฉืื™ืœืชื•ืช ืžืกื“ ื ืชื•ื ื™ื ืžืคื•ืจื˜ื•ืช ื‘ื™ื•ืชืจ ื”ืžื‘ื˜ืœื•ืช ืืช ื”ืฆื•ืจืš ืœืžื™ื™ืŸ ืžื™ื“ืข ื‘ืจื’ืข ืฉื”ื•ื ืžืชืงื‘ืœ ื•ื™ืฉ ืœื”ื ืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ืคื•ื˜ื ืฆื™ืืœ ื™ื™ืฉื•ื. ืœื“ื•ื’ืžื”:
List<Note> findAllByOrderByDateAsc();
ื”ืฉื™ื˜ื” ืชื•ืžืจ ืœืฉืื™ืœืชืช SQL ื•ืชืฆื™ื’ ืืช ื›ืœ ื”ืจืฉื•ืžื•ืช (findAll) ืžืžื•ื™ื ื•ืช (byOrder) ืœืคื™ ืชืืจื™ืš (byDate) ื‘ืกื“ืจ ืขื•ืœื” (Asc). ื™ืชืจ ืขืœ ื›ืŸ, ืืชื” ื™ื›ื•ืœ ืœื™ืฆื•ืจ ืฉื™ืœื•ื‘ื™ื ืžื•ืจื›ื‘ื™ื ื•ืœื“ื’ื•ื ืขืœ ืคื ื™ ืฉื“ื•ืช ืจื‘ื™ื ืขื ื“ืจื™ืฉื” ืื—ืช. ื ื ื™ื—, ื‘ื—ืจ ืืช ื›ืœ ื”ืจืฉื•ืžื•ืช (findAll) ืฉื”ื•ืฉืœืžื• (byDoneTrue) ืœืคื™ ืกื“ืจ (ืœืคื™ ื”ื–ืžื ื”) ื‘ื™ืจื™ื“ื” (Decs) ืœืคื™ ืขืจืš ื”ืชืืจื™ืš (byDate):
Page<Note> findAllByDoneTrueOrderByDateDesc(Pageable pageable);

ืžืกืงื ื” ืื• ื•ื™ื“ื•ื™ ืื—ืจ ืฉืœ ืžืชื›ื ืช ืžืชื—ื™ืœ

ืืช ื›ืœ! ืืชื” ื™ื›ื•ืœ ืœื”ืคืขื™ืœ ืืช ื™ื™ืฉื•ื ื”ืื™ื ื˜ืจื ื˜ ื‘ื‘ื˜ื—ื” ื‘ืืžืฆืขื•ืช ื”ืฉื™ืœื•ื‘ Shift+F10 ืื• ืขืœ ื™ื“ื™ ืœื—ื™ืฆื” ืขืœ ื”ืกืžืœ ื”ืžืชืื™ื. Spring Boot ื™ื‘ื ื” ืืช ื”ืชื•ื›ื ื™ืช ืขืœ Apache Maven ื•ืชืชืงื™ืŸ ืฉืจืช Apache Tomcat ืžืงื•ืžื™ ื‘-localhost:8080. ืขื›ืฉื™ื• ืืชื” ืจืง ืฆืจื™ืš ืœืขืงื•ื‘ ืื—ืจ ื”ืงื™ืฉื•ืจ ื‘ื›ืœ ื“ืคื“ืคืŸ.
Conquest Spring Boot - 6
ื•ื›ืžื•ื‘ืŸ, ืœืคืชื— ืžืชื•ื“ื•ืœื•ื’ื™ื” ืœืžื™ืœื•ื™ ื“ืจื™ืฉื•ืช ืขืกืงื™ื•ืช ืื—ืจื•ืช. ื”ืคื•ื˜ื ืฆื™ืืœ ืฉืœ ื”ืืคืœื™ืงืฆื™ื” ืžื•ื’ื‘ืœ ืขืœ ื™ื“ื™ ื”ืžืืžืฅ, ื”ืชื•ืฉื™ื™ื” ื•ื”ื“ืžื™ื•ืŸ ืฉืœ ื”ืžืคืชื—.
Conquest Spring Boot - 7
ื‘ื”ื™ื•ืชื™ ื›ื ื” ื•ืฉื ืœื‘ ืœื“ืจืš ืฉืขื‘ืจืชื™, ืื ื™ ืฉื•ื‘ ื•ืฉื•ื‘ ืžืฉื•ื›ื ืข ื‘ื ื›ื•ื ื•ืช ื”ื›ื™ื•ื•ืŸ ื”ื ื‘ื—ืจ ื•ืžื‘ื™ืŸ ืืช ื”ื™ืชืจื•ื ื•ืช ืฉืœ ืœื™ืžื•ื“ ื‘ืคื•ืจื˜ืœ ื”ื—ื™ื ื•ื›ื™ JavaRush. ื”ื•ื“ื•ืช ืœืžื’ื•ื•ืŸ ืžืฉื™ืžื•ืช ืžืขืฉื™ื•ืช, ื ื™ืชืŸ ื”ื™ื” ืœื”ื—ื–ื™ืจ ืืช ื”ืขื ื™ื™ืŸ ื”ืžืคืชื” ื‘ืœื™ืžื•ื“ ืชื›ื ื•ืช, ืฉื ื“ื—ืง ืœื—ืœื•ื˜ื™ืŸ ื‘ืชื›ื ื™ืช ื”ืžื™ื•ืฉื ืช ื•ื”ืžืฉืขืžืžืช ืœื”ืคืชื™ืข ืฉืœ ืžื•ืกื“ ืœื”ืฉื›ืœื” ื’ื‘ื•ื”ื” ื‘ื›ื™ื•ื•ืŸ ื“ื•ืžื”. ืืจื‘ืขื” ื—ื•ื“ืฉื™ื ืฉืœ ืœื™ืžื•ื“ ืคืขื™ืœ ืฉืœ ื—ื•ืžืจ ื‘ืขืจื™ืžืช ื”ื˜ื›ื ื•ืœื•ื’ื™ื” ื”ืื—ื•ืจื™ืช ื”ืฉืงื™ืขื• ื”ืจื‘ื” ื™ื•ืชืจ ื™ื“ืข ื‘ื”ืฉื•ื•ืื” ืœืฉื ื™ื ืฉืœืžื•ืช ืฉืœ ื”ืฉืชืชืคื•ืช ื‘ื”ืจืฆืื•ืช ื•ืฉื™ืขื•ืจื™ ืžืขื‘ื“ื”. ืชืืžื™ืŸ ืœื–ื” ืื• ืœื. ืื ื™ ืžืื—ืœ ืœืš ืœื ืœื”ื™ื›ื ืข ืœืงืฉื™ื™ื ื‘ื›ื ื™ืกื” ืœื—ื•ืžืจื™ื ืžื•ืจื›ื‘ื™ื, ื›ื™ ื“ืจืš ื”ืชื’ื‘ืจื•ืช ืขืœ ืžื›ืฉื•ืœื™ื ืื ื—ื ื• ืžืฉืชืคืจื™ื ื•ืžืชืคืชื—ื™ื ืžืงืฆื•ืขื™ืช ื•ืื™ืฉื™ืช. ืื ื™ ืžืงื•ื•ื” ืฉื”ืกื™ืคื•ืจ ื”ืงื˜ืŸ ื”ื–ื” ืขื–ืจ ืœื™ ืœื’ืœื•ืช ื›ืžื” ืจืขื™ื•ื ื•ืช ื—ื“ืฉื™ื ืœืฉื™ืžื•ืฉ ื‘ื›ืœื™ ื”ืžื“ื”ื™ื ืฉื ืงืจื SpringBoot. ื .ื‘ Github .
ื”ืขืจื•ืช
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION