# mentor workthrough@ctbc ## JDK 11 ## Spring Boot 2.7.7 ## Angular ## Eclipse ## Visual Studio Code --- ### Git ### bootstrap ### lombok ### junit ### gradle/maven --- # Java ## service # Spring Boot ## JPA ==> H2 ## service ## Restful/MVC ## CRUD app # Angular ## CRUD SPA --- # Eclipse 2022.12 # git/cmd ## https://git-scm.com/ ``` git --version ``` ## https://code.visualstudio.com/ ## 名稱: Angular Snippets (Version 13) 識別碼: johnpapa.Angular2 描述: Angular version 13 snippets by John Papa 版本: 13.0.0 發行者: John Papa VS Marketplace 連結: https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2 ## 名稱: Angular Essentials (Version 13) 識別碼: johnpapa.angular-essentials 描述: Essential extensions for Angular developers 版本: 13.0.0 發行者: John Papa VS Marketplace 連結: https://marketplace.visualstudio.com/items?itemName=johnpapa.angular-essentials ## 名稱: Angular Language Service 識別碼: Angular.ng-template 描述: Editor services for Angular templates 版本: 15.1.0 發行者: Angular VS Marketplace 連結: https://marketplace.visualstudio.com/items?itemName=Angular.ng-template ## 名稱: Git Graph 識別碼: mhutchie.git-graph 描述: View a Git Graph of your repository, and perform Git actions from the graph. 版本: 1.30.0 發行者: mhutchie VS Marketplace 連結: https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph ## open eclipse ### https://projectlombok.org/ ### https://projectlombok.org/setup/eclipse ### lombok update site: ``` https://projectlombok.org/p2 ``` ![](https://i.imgur.com/3atdNxl.png) ![](https://i.imgur.com/b7yPEvW.png) # **安裝完手動關閉再啟動** ![](https://i.imgur.com/ve1ZK2E.png) # Help/About Eclipse ## https://www.digitalocean.com/community/tutorials/java-project-lombok ## https://start.spring.io/ ![](https://i.imgur.com/T1wBGL6.png) ## web, lombok, spring boot dev tools, actuator, h2, spring data jpa, validation, thymeleaf ![](https://i.imgur.com/d5Gh2Ej.png) ![](https://i.imgur.com/zmJNsNN.png) ![](https://i.imgur.com/zEzm7pp.png) ## explain `build.gradle` ```groovy= repositories { maven { url "http://10.242.136.125:8081/repository/maven-releases/"     } //mavenCentral() } ``` ![](https://i.imgur.com/wbYGvfd.png) ![](https://i.imgur.com/1TgP25v.png) ![](https://i.imgur.com/IirHVIO.png) ## download JDK11 ### https://www.microsoft.com/openjdk ### https://github.com/JetBrains/JetBrainsRuntime ### https://aws.amazon.com/corretto/?filtered-posts.sort-by=item.additionalFields.createdDate&filtered-posts.sort-order=desc ### https://aka.ms/download-jdk/microsoft-jdk-11.0.17-windows-x64.zip ```groovy= repositories { mavenCentral() //maven { //url "http://10.242.136.125:8081/repository/maven-releases/"     //} } ``` # window/Preferences ![](https://i.imgur.com/82D50KA.png) ![](https://i.imgur.com/biAeLod.png) ![](https://i.imgur.com/RVB4f8g.png) ![](https://i.imgur.com/VNnhJpv.png) ![](https://i.imgur.com/A3FaZf2.png) ![](https://i.imgur.com/6aeTMBd.png) ![](https://i.imgur.com/gyIuwcu.png) ``` http://localhost:8080/actuator ``` # https://www.mchange.com/projects/c3p0/ # https://proxool.sourceforge.net/ # https://github.com/brettwooldridge/HikariCP # http://localhost:8080/h2-console/ ![](https://i.imgur.com/y4m02ot.png) ![](https://i.imgur.com/CqOJ3o3.png) # have a look at project lombok: ## https://projectlombok.org/features/ ## Course.java ```java package com.ctbc.mentor.lab1.model; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @NoArgsConstructor @AllArgsConstructor public class Course { @Getter @Setter private UUID id; @Getter @Setter private String name; @Getter @Setter private int price; } ``` ![](https://i.imgur.com/SJfRTIj.png) # CourseCategory ```java package com.ctbc.mentor.lab1.model; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @AllArgsConstructor @NoArgsConstructor public class CourseCategory { @Getter @Setter private String name; @Getter @Setter private String detail; @Getter @Setter private UUID id; } ``` ![](https://i.imgur.com/J8HLqXY.png) ![](https://i.imgur.com/Soq1TkU.png) # https://junit.org/junit5/ ![](https://i.imgur.com/aJGDuFR.jpg) ```java= package com.ctbc.mentor.lab1.lab1; import java.util.UUID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.ctbc.mentor.lab1.model.Course; import com.ctbc.mentor.lab1.model.CourseCategory; public class TestCourse { @Test public void will100PercentPass() { } @Test public void noArgumentTest() { Course course = new Course(); // Course course = null; Assertions.assertNotNull(course, "course object should not null"); } @Test public void allArgumentTest() { Course course = new Course(UUID.randomUUID(), "name", 500, null); Assertions.assertNotNull(course, "course object should not null"); } @Test public void getterSetterTest() { String name = "Java17 new feature"; CourseCategory category = new CourseCategory(); category.setName(name); Course course = new Course(UUID.randomUUID(), "Java OOP", 500, category); Assertions.assertEquals(category, course.getCategory()); Assertions.assertEquals(category.getName(), name); } } ``` # CourseService ```java package com.ctbc.mentor.lab1.service; import java.util.List; import java.util.UUID; import com.ctbc.mentor.lab1.model.Course; import com.ctbc.mentor.lab1.model.CourseCategory; public interface CourseService { List<Course> getAllCourse(); Course addCourse(String name, int price, CourseCategory category); void removeCourse(UUID id); Course modifyCourse(UUID id, String name, int price, CourseCategory category); } ``` # CourseCategory ```java package com.ctbc.mentor.lab1.service; import java.util.List; import java.util.UUID; import com.ctbc.mentor.lab1.model.Course; import com.ctbc.mentor.lab1.model.CourseCategory; public interface CourseCategoryServvice { List<CourseCategory> getAllCourseCategory(); CourseCategory addCourseCategory(String name, String detail); void removeCourseCategory(UUID id); Course modifyCourseCategory(UUID id, String name, int detail); } ``` ![](https://i.imgur.com/jeGN2ge.png) ![](https://i.imgur.com/TVNY50d.png) # CourseCategoryServiceJDKImplement ```java package com.ctbc.mentor.lab1.service; import java.util.ArrayList; import java.util.List; import java.util.UUID; import com.ctbc.mentor.lab1.model.CourseCategory; public class CourseCategoryServiceJDKImplement implements CourseCategoryService { List<CourseCategory> categories = new ArrayList<>(); @Override public List<CourseCategory> getAllCourseCategory() { return categories; } @Override public CourseCategory addCourseCategory(String name, String detail) { UUID id = UUID.randomUUID(); CourseCategory category = new CourseCategory(name, detail, id); categories.add(category); return category; } @Override public void removeCourseCategory(UUID id) { for (CourseCategory c : categories) { if (c.getId().equals(id)) { categories.remove(c); return; } } } @Override public CourseCategory modifyCourseCategory(UUID id, String name, String detail) { for (CourseCategory c : categories) { if (c.getId().equals(id)) { c.setName(name); c.setDetail(detail); return c; } } return null; } } ``` # TestCourseCategoryService ```java package com.ctbc.mentor.lab1.lab2; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.ctbc.mentor.lab1.model.CourseCategory; import com.ctbc.mentor.lab1.service.CourseCategoryService; import com.ctbc.mentor.lab1.service.CourseCategoryServiceJDKImplement; public class TestCourseCategoryService { private CourseCategoryService service; @BeforeEach public void prepareVariable() { service = new CourseCategoryServiceJDKImplement(); } @Test public void testEmpty() { List<CourseCategory> categories = service.getAllCourseCategory(); Assertions.assertEquals(categories.size(), 0); } @Test public void testAddOne() { CourseCategory c1 = service.addCourseCategory("ML", "machine learning and deep learing"); List<CourseCategory> categories = service.getAllCourseCategory(); Assertions.assertEquals(categories.size(), 1); } @Test public void testMultiple() { CourseCategory c1 = service.addCourseCategory("ML", "machine learning and deep learing"); CourseCategory c2 = service.addCourseCategory("Smart Contract", "ethereum and solidity"); List<CourseCategory> categories = service.getAllCourseCategory(); Assertions.assertEquals(categories.size(), 2); } @Test public void testDeleteSuccess() { CourseCategory c1 = service.addCourseCategory("ML", "machine learning and deep learing"); CourseCategory c2 = service.addCourseCategory("Smart Contract", "ethereum and solidity"); List<CourseCategory> categories = service.getAllCourseCategory(); service.removeCourseCategory(c1.getId()); Assertions.assertEquals(categories.size(), 1); Assertions.assertEquals(c2, service.getAllCourseCategory().get(0)); } @Test public void testDeleteFail() { CourseCategory c1 = service.addCourseCategory("ML", "machine learning and deep learing"); CourseCategory c2 = service.addCourseCategory("Smart Contract", "ethereum and solidity"); List<CourseCategory> categories = service.getAllCourseCategory(); service.removeCourseCategory(UUID.randomUUID()); Assertions.assertEquals(c1, service.getAllCourseCategory().get(0)); Assertions.assertEquals(c2, service.getAllCourseCategory().get(1)); } } ``` # CourseCategory ```java package com.ctbc.mentor.lab1.model; import java.util.ArrayList; import java.util.List; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @AllArgsConstructor @NoArgsConstructor public class CourseCategory { @Getter @Setter private String name; @Getter @Setter private String detail; @Getter @Setter private UUID id; @Getter private List<Course> courses = new ArrayList<>(); public void addCourse(Course c) { courses.add(c); } public void removeCourse(Course c) { for (Course course : courses) { if (course.getId().equals(c.getId())) { courses.remove(course); return; } } } } ``` # gradlew test # mvnw test * https://menghangho.quickconnect.to/d/s/s0ntyg6NA1vmXzyjLaTh9hu8Pjs9CU4E/VB_WUOqFadrqNSyv_zB2ca585WfzzpQo-UbJAvQyrJQo ![](https://i.imgur.com/6geXs6I.png) # CourseServiceFactory ```java package com.ctbc.mentor.lab1.util; import com.ctbc.mentor.lab1.service.CourseService; import com.ctbc.mentor.lab1.service.CourseServiceJDKImplement; public class CourseServiceFactory { private static CourseService service; public static CourseService getService() { if (service == null) { service = new CourseServiceJDKImplement(); } return service; } } ``` # TestServiceEquality ```java package com.ctbc.mentor.lab1.lab4; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.ctbc.mentor.lab1.service.CourseService; import com.ctbc.mentor.lab1.service.CourseServiceJDKImplement; import com.ctbc.mentor.lab1.util.CourseServiceFactory; public class TestServiceEquality { @Test public void normalGenerate() { CourseService s1 = new CourseServiceJDKImplement(); CourseService s2 = new CourseServiceJDKImplement(); Assertions.assertNotEquals(s1, s2); } @Test public void normalGenerate2() { CourseService s1 = new CourseServiceJDKImplement(); CourseService s2 = new CourseServiceJDKImplement(); Assertions.assertNotSame(s1, s2); } @Test public void factoryGenerate() { CourseService s1 = CourseServiceFactory.getService(); Assertions.assertNotNull(s1); CourseService s2 = CourseServiceFactory.getService(); Assertions.assertSame(s1, s2); } } ``` * https://www.advancedrestclient.com/ # Day2 ## CourseBean ```java package com.ctbc.mentor.lab1m.bean; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int price; } ``` ## CategoryBean ```java package com.ctbc.mentor.lab1m.repository; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import com.ctbc.mentor.lab1m.bean.CourseBean; @Repository public interface CourseBeanRepository extends CrudRepository<CourseBean, Long> { } ``` ![](https://i.imgur.com/X9IR2WE.png) maven syntax: `spring-boot:run` * `http://localhost:8080/h2-console` # SampleDataRunner.java ```java package com.ctbc.mentor.lab1m.runner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.repository.CourseBeanRepository; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class SampleDataRunner implements CommandLineRunner { private static final Logger LOGGER = LoggerFactory.getLogger(SampleDataRunner.class); @Autowired private CourseBeanRepository repository; @Override public void run(String... args) throws Exception { System.out.println("This line will be executed!!"); LOGGER.warn("this line will also be executed!!"); log.info("this line will also be executed!!!"); CourseBean bean1 = new CourseBean(); bean1.setName("Python and OOP"); bean1.setPrice(299); repository.save(bean1); CourseBean bean2 = new CourseBean(); bean2.setName("Python and big data"); bean1.setPrice(350); repository.save(bean2); } } ``` # coursebeantest ```java package com.ctbc.mentor.lab1m.verify1; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.repository.CourseBeanRepository; import lombok.extern.slf4j.Slf4j; // type1 //@SpringBootTest // type2 @ExtendWith(SpringExtension.class) @DataJpaTest // end of type2 @Slf4j public class CourseBeanTest { @Autowired private CourseBeanRepository repository; @Autowired private TestEntityManager manager; @Test public void checkRepositoryAndManagerNotNull() { Assertions.assertNotNull(repository); Assertions.assertNotNull(manager); } @Test public void envCheckIsEmpty() { Assertions.assertEquals(repository.count(), 0); } @Test public void testCourseAdd() { CourseBean b1 = new CourseBean(); b1.setName("Python OOP"); b1.setPrice(300); CourseBean b2 = new CourseBean(); b2.setName("Python and big data"); b2.setPrice(350); repository.save(b1); repository.save(b2); // commit manager.flush(); manager.clear(); for (CourseBean b : repository.findAll()) { log.info("get back a course bean:{}", b); } Assertions.assertEquals(repository.count(), 2); } @Test public void testCourseBdd() { Assertions.assertEquals(repository.count(), 0); } } ``` # CourseBean ```java package com.ctbc.mentor.lab1m.bean; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int price; private Date createdAt; private Date modifiedAt; @PrePersist public void onCreate() { createdAt = new Date(); } @PreUpdate public void onUpdate() { modifiedAt = new Date(); } } ``` # https://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/listeners.html ## SampleDataRunner2.java ```java package com.ctbc.mentor.lab1m.runner; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.repository.CourseBeanRepository; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class SampleDataRunner2 implements CommandLineRunner { @Autowired private CourseBeanRepository repository; @Override public void run(String... args) throws Exception { for (CourseBean b : repository.findAll()) { b.setPrice(b.getPrice() + 100); repository.save(b); } log.info("price changed, check the database"); } } ``` # CourseBeanTest2.java ```java package com.ctbc.mentor.lab1m.verify1; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.repository.CourseBeanRepository; import lombok.extern.slf4j.Slf4j; @ExtendWith(SpringExtension.class) @DataJpaTest @Slf4j public class CourseBeanTest2 { @Autowired private CourseBeanRepository repository; @Autowired private TestEntityManager manager; @Test public void testCourseBeanModify() { CourseBean b1 = new CourseBean(); b1.setName("Java OOP"); b1.setPrice(500); repository.save(b1); log.info("b1 is {}", b1); b1.setPrice(600); repository.save(b1); manager.flush(); manager.clear(); log.info("[price updated]b1 is {}", b1); CourseBean b2 = repository.findById(b2); } } ``` # CourseCategoryBean.java ```java package com.ctbc.mentor.lab1m.bean; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseCategoryBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String detail; private Date createdAt; private Date modifiedAt; @PrePersist public void onCreate() { createdAt = new Date(); } @PreUpdate public void onUpdate() { modifiedAt = new Date(); } } ``` # sampledatarunner3 ```java package com.ctbc.mentor.lab1m.runner; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseCategoryBean; import com.ctbc.mentor.lab1m.repository.CourseCategoryBeanRepository; @Component public class SampleDataRunner3 implements CommandLineRunner { @Autowired private CourseCategoryBeanRepository repository; @Override public void run(String... args) throws Exception { CourseCategoryBean c1 = new CourseCategoryBean(); c1.setName("Java"); c1.setDetail("eclipse, IntelliJ, Spring, Redis, Kafka"); CourseCategoryBean c2 = new CourseCategoryBean(); c2.setName("C#"); c2.setDetail("vs code, visual studio, EF Core7...."); repository.save(c1); repository.save(c2); } } ``` # CourseBean.java ```java package com.ctbc.mentor.lab1m.bean; import java.util.Date; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int price; private Date createdAt; private Date modifiedAt; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "category_id") private CourseCategoryBean category; @PrePersist public void onCreate() { createdAt = new Date(); } @PreUpdate public void onUpdate() { modifiedAt = new Date(); } } ``` # CourseCategoryBean ```java package com.ctbc.mentor.lab1m.bean; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseCategoryBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String detail; private Date createdAt; private Date modifiedAt; @OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER, mappedBy = "category") private List<CourseBean> courses = new ArrayList<>(); @PrePersist public void onCreate() { createdAt = new Date(); } @PreUpdate public void onUpdate() { modifiedAt = new Date(); } } ``` # SampleDataRunner5 ```java package com.ctbc.mentor.lab1m.runner; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.bean.CourseCategoryBean; import com.ctbc.mentor.lab1m.repository.CourseCategoryBeanRepository; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class SampleDataRunner5 implements CommandLineRunner { @Autowired CourseCategoryBeanRepository repository; @Override public void run(String... args) throws Exception { for (CourseCategoryBean category : repository.findAll()) { log.info("get category name:{}, detail:{}", category.getName(), category.getDetail()); for (CourseBean course : category.getCourses()) { log.info(" with course:{}", course.getName()); } } } } ``` # SampleDataRunner6 ```java package com.ctbc.mentor.lab1m.runner; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseCategoryBean; import com.ctbc.mentor.lab1m.repository.CourseCategoryBeanRepository; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class SampleDataRunner6 implements CommandLineRunner { @Autowired private CourseCategoryBeanRepository repository; @Override public void run(String... args) throws Exception { CourseCategoryBean b1 = repository.findById(1L).get(); log.info("will delete b1:{},size={}", b1.getName(), b1.getCourses().size()); repository.deleteById(1L); CourseCategoryBean b2 = repository.findById(2L).get(); log.info("will delete b2:{}, size={}", b2.getName(), b2.getCourses().size()); repository.deleteById(2L); } } ``` # remove all ```java package com.ctbc.mentor.lab1m.service; import java.util.List; import com.ctbc.mentor.lab1m.bean.CourseBean; public interface CourseBeanService { List<CourseBean> getAllCourseBean(); CourseBean getCourseBeanById(long id); CourseBean saveOrUpdateCourseBean(CourseBean bean); void removeCourseBean(long id); void clearAll(); } ``` # CourseBeanServiceJPAImplement ```java package com.ctbc.mentor.lab1m.service; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.repository.CourseBeanRepository; @Component public class CourseBeanServiceJPAImplement implements CourseBeanService { @Autowired CourseBeanRepository repository; @Override public List<CourseBean> getAllCourseBean() { List<CourseBean> allCourses = new ArrayList<>(); repository.findAll().forEach(b -> allCourses.add(b)); return allCourses; } @Override public CourseBean getCourseBeanById(long id) { CourseBean courseBean = repository.findById(id).get(); return courseBean; } @Override public CourseBean saveOrUpdateCourseBean(CourseBean bean) { CourseBean savedBean = repository.save(bean); return savedBean; } @Override public void removeCourseBean(long id) { repository.deleteById(id); } @Override public void clearAll() { repository.deleteAll(); } } ``` ## RestController ```java package com.ctbc.mentor.lab1m.controller.rest; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.service.CourseBeanService; import lombok.extern.slf4j.Slf4j; @RestController @RequestMapping("/api/category") @Slf4j @CrossOrigin public class CourseBeanRestController { @Autowired CourseBeanService service; @GetMapping("/all") public List<CourseBean> getAllCourses() { return service.getAllCourseBean(); } } ``` ## JSONIGNORE ```java package com.ctbc.mentor.lab1m.bean; import java.util.Date; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor public class CourseBean { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int price; private Date createdAt; private Date modifiedAt; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "category_id") @JsonIgnore private CourseCategoryBean category; @PrePersist public void onCreate() { createdAt = new Date(); } @PreUpdate public void onUpdate() { modifiedAt = new Date(); } } ``` # RestController ```java package com.ctbc.mentor.lab1m.controller.rest; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.service.CourseBeanService; import lombok.extern.slf4j.Slf4j; @RestController @RequestMapping("/api/category") @Slf4j @CrossOrigin public class CourseBeanRestController { @Autowired CourseBeanService service; @GetMapping("/all") public List<CourseBean> getAllCourses() { return service.getAllCourseBean(); } @PostMapping("") public ResponseEntity<?> createCourse(@RequestBody CourseBean course) { CourseBean updatedBean = service.saveOrUpdateCourseBean(course); return new ResponseEntity<>(updatedBean, HttpStatus.CREATED); } } ``` ![](https://i.imgur.com/p4xcNDO.png) ```java package com.ctbc.mentor.lab1m.controller.rest; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ctbc.mentor.lab1m.bean.CourseBean; import com.ctbc.mentor.lab1m.service.CourseBeanService; import lombok.extern.slf4j.Slf4j; @RestController @RequestMapping("/api/category") @Slf4j @CrossOrigin public class CourseBeanRestController { @Autowired CourseBeanService service; @GetMapping("/all") public List<CourseBean> getAllCourses() { return service.getAllCourseBean(); } @PostMapping("") public ResponseEntity<?> createCourse(@RequestBody CourseBean course) { log.info("get bean:{}", course); CourseBean updatedBean = service.saveOrUpdateCourseBean(course); return new ResponseEntity<>(updatedBean, HttpStatus.CREATED); } } ```