| Line 89: |
Line 89: |
| | </syntaxhighlight> | | </syntaxhighlight> |
| | | | |
| − | == Dev Tools == | + | ==Dev Tools== |
| | Add at pom.xml<syntaxhighlight lang="xml"> | | Add at pom.xml<syntaxhighlight lang="xml"> |
| | .... | | .... |
| Line 106: |
Line 106: |
| | Provides: | | Provides: |
| | | | |
| − | * Develop server reloading on changes (pom.xml changes are not detected) | + | *Develop server reloading on changes (pom.xml changes are not detected) |
| | + | |
| | + | == Example: Spring Boot with Data JPA and in memory database H2 == |
| | + | |
| | + | === /pom.xml === |
| | + | <syntaxhighlight lang="xml"> |
| | + | .... |
| | + | <dependencies> |
| | + | .... |
| | + | <dependency> |
| | + | <groupId>org.springframework.boot</groupId> |
| | + | <artifactId>spring-boot-starter-web</artifactId> |
| | + | </dependency> |
| | + | <dependency> |
| | + | <groupId>org.springframework.boot</groupId> |
| | + | <artifactId>spring-boot-starter-data-jpa</artifactId> |
| | + | </dependency> |
| | + | <dependency> |
| | + | <groupId>com.h2database</groupId> |
| | + | <artifactId>h2</artifactId> |
| | + | <scope>runtime</scope> |
| | + | </dependency> |
| | + | <dependency> |
| | + | <groupId>org.springframework.boot</groupId> |
| | + | <artifactId>spring-boot-starter-actuator</artifactId> |
| | + | <scope>runtime</scope> |
| | + | </dependency> |
| | + | <dependency> |
| | + | <groupId>org.springframework.boot</groupId> |
| | + | <artifactId>spring-boot-starter-devtools</artifactId> |
| | + | <scope>runtime</scope> |
| | + | </dependency> |
| | + | .... |
| | + | </dependencies> |
| | + | .... |
| | + | </syntaxhighlight> |
| | + | |
| | + | === /src/main/resources/application.properties === |
| | + | <syntaxhighlight lang="java"> |
| | + | spring.datasource.url=jdbc:h2:mem:testdb |
| | + | |
| | + | # If using Spring Boot >=2.5.0 the following line is also required |
| | + | spring.jpa.defer-datasource-initialization=true |
| | + | </syntaxhighlight>database will be accessible via http://localhost:8080/h2-console |
| | + | |
| | + | === /src/main/java/com/in28minutes/learnspringboot/courses/bean/Course.java === |
| | + | <syntaxhighlight lang="java"> |
| | + | package com.in28minutes.learnspringboot.courses.bean; |
| | + | |
| | + | import javax.persistence.Entity; |
| | + | import javax.persistence.Id; |
| | + | import javax.persistence.GeneratedValue; |
| | + | // import javax.persistence.Column; |
| | + | |
| | + | // @Entity(name="db_table_name") |
| | + | @Entity |
| | + | public class Course { |
| | + | @Id |
| | + | @GeneratedValue |
| | + | private long id; |
| | + | |
| | + | // @Column(name="db_column_name") |
| | + | private String name; |
| | + | private String author; |
| | + | |
| | + | public Course(long id, String name, String author){ |
| | + | super(); |
| | + | this.id = id; |
| | + | this.name = name; |
| | + | this.author = author; |
| | + | } |
| | + | |
| | + | public String toString() { |
| | + | return "Course [id=" + id + ", name= " + name + ", author=" + author + " ]"; |
| | + | } |
| | + | |
| | + | public long getId() { |
| | + | return id; |
| | + | } |
| | + | public String getName() { |
| | + | return name; |
| | + | } |
| | + | public String getAuthor() { |
| | + | return author; |
| | + | } |
| | + | } |
| | + | </syntaxhighlight> |
| | + | |
| | + | === src/main/resources/data.sql === |
| | + | querys in this file will be executed at startup automatically<syntaxhighlight lang="sql"> |
| | + | insert into COURSE(ID, AUTHOR, NAME) |
| | + | values(100001, 'in28minutes', 'Learn Microservices'); |
| | + | insert into COURSE(ID, AUTHOR, NAME) |
| | + | values(100002, 'in28minutes', 'Learn FullStack with React and Angular'); |
| | + | insert into COURSE(ID, AUTHOR, NAME) |
| | + | values(100003, 'in28minutes', 'Learn AWS, GCP and Azure'); |
| | + | </syntaxhighlight> |
| | + | |
| | + | === /src/main/java/com/in28minutes/learnspringboot/courses/repository/CourseRepository.java === |
| | + | <syntaxhighlight lang="java"> |
| | + | package com.in28minutes.learnspringboot.courses.repository; |
| | + | |
| | + | import org.springframework.data.jpa.repository.JpaRepository; |
| | + | import com.in28minutes.learnspringboot.courses.bean.Course; |
| | + | |
| | + | public interface CourseRepository extends JpaRepository<Course, Long> {} |
| | + | </syntaxhighlight> |
| | + | ---- |
| | + | |
| | + | === /src/main/java/com/in28minutes/learnspringboot/courses/controller/CourseController.java === |
| | + | <syntaxhighlight lang="java"> |
| | + | package com.in28minutes.learnspringboot.courses.controller; |
| | + | |
| | + | import java.util.List; |
| | + | import java.util.Optional; |
| | + | |
| | + | import org.springframework.beans.factory.annotation.Autowired; |
| | + | import org.springframework.web.bind.annotation.DeleteMapping; |
| | + | import org.springframework.web.bind.annotation.GetMapping; |
| | + | import org.springframework.web.bind.annotation.PathVariable; |
| | + | import org.springframework.web.bind.annotation.PostMapping; |
| | + | import org.springframework.web.bind.annotation.PutMapping; |
| | + | import org.springframework.web.bind.annotation.RequestBody; |
| | + | import org.springframework.web.bind.annotation.RestController; |
| | + | |
| | + | import com.in28minutes.learnspringboot.courses.bean.Course; |
| | + | import com.in28minutes.learnspringboot.courses.repository.CourseRepository; |
| | + | |
| | + | @RestController |
| | + | public class CourseController { |
| | + | |
| | + | @Autowired |
| | + | private CourseRepository repository; |
| | + | |
| | + | // http://localhost:8080/courses |
| | + | @GetMapping("/courses") |
| | + | public List<Course> getAllCourses() { |
| | + | return repository.findAll(); |
| | + | } |
| | + | |
| | + | //// http://localhost:8080/courses/1 |
| | + | @GetMapping("/courses/{id}") |
| | + | public Course getCourseDetails(@PathVariable long id) { |
| | + | |
| | + | Optional<Course> course = repository.findById(id); |
| | + | |
| | + | if(course.isEmpty()) { |
| | + | throw new RuntimeException("Course not found with id " + id); |
| | + | } |
| | + | |
| | + | return course.get(); |
| | + | } |
| | + | |
| | + | /* |
| | + | POST http://localhost:8080/courses |
| | + | { |
| | + | "name": "Learn DevOps", |
| | + | "author": "in28minutes" |
| | + | }*/ |
| | + | |
| | + | //POST - Create a new resource (/courses) |
| | + | @PostMapping("/courses") |
| | + | public void createCourse(@RequestBody Course course){ |
| | + | repository.save(course); |
| | + | } |
| | + | |
| | + | /* |
| | + | PUT - http://localhost:8080/courses/100001 |
| | + | { |
| | + | "id": 100001, |
| | + | "name": "Learn Microservices 2", |
| | + | "author": "in28minutes" |
| | + | } |
| | + | */ |
| | + | |
| | + | //PUT - Update/Replace a resource (/courses/1) |
| | + | @PutMapping("/courses/{id}") |
| | + | public void updateCourse(@PathVariable long id, @RequestBody Course course){ |
| | + | repository.save(course); |
| | + | } |
| | + | |
| | + | |
| | + | //DELETE - Delete a resource (/courses/1) |
| | + | @DeleteMapping("/courses/{id}") |
| | + | public void deleteCourse(@PathVariable long id){ |
| | + | repository.deleteById(id); |
| | + | } |
| | + | |
| | + | |
| | + | // docker run --detach |
| | + | // --env MYSQL_ROOT_PASSWORD=dummypassword |
| | + | // --env MYSQL_USER=courses-user |
| | + | // --env MYSQL_PASSWORD=dummycourses |
| | + | // --env MYSQL_DATABASE=courses |
| | + | // --name mysql |
| | + | // --publish 3306:3306 mysql:5.7 |
| | + | } |
| | + | </syntaxhighlight> |
| | | | |
| | ==Build== | | ==Build== |