---
# System prepended metadata

title: mentor workthrough@ctbc

---

# 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);
	}
}

```