├── .env
├── README.md
├── bezkoder-app
├── Dockerfile
├── README.md
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── bezkoder
│ └── spring
│ └── datajpa
│ ├── SpringBootDataJpaApplication.java
│ ├── controller
│ └── TutorialController.java
│ ├── model
│ └── Tutorial.java
│ └── repository
│ └── TutorialRepository.java
└── docker-compose.yml
/.env:
--------------------------------------------------------------------------------
1 | MYSQLDB_USER=root
2 | MYSQLDB_ROOT_PASSWORD=123456
3 | MYSQLDB_DATABASE=bezkoder_db
4 | MYSQLDB_LOCAL_PORT=3307
5 | MYSQLDB_DOCKER_PORT=3306
6 |
7 | SPRING_LOCAL_PORT=6868
8 | SPRING_DOCKER_PORT=8080
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Docker Compose Spring Boot and MySQL example
2 |
3 | ## Run the System
4 | We can easily run the whole with only a single command:
5 | ```bash
6 | docker compose up
7 | ```
8 |
9 | Docker will pull the MySQL and Spring Boot images (if our machine does not have it before).
10 |
11 | The services can be run on the background with command:
12 | ```bash
13 | docker compose up -d
14 | ```
15 |
16 | ## Stop the System
17 | Stopping all the running containers is also simple with a single command:
18 | ```bash
19 | docker compose down
20 | ```
21 |
22 | If you need to stop and remove all containers, networks, and all images used by any service in docker-compose.yml file, use the command:
23 | ```bash
24 | docker compose down --rmi all
25 | ```
26 |
27 | For more detail, please visit:
28 | > [Docker Compose Spring Boot and MySQL example](https://www.bezkoder.com/docker-compose-spring-boot-mysql/)
29 |
30 | Related Posts:
31 | > [Spring Boot JPA + MySQL - Building Rest CRUD API example](https://www.bezkoder.com/spring-boot-jpa-crud-rest-api/)
32 |
33 | > [Spring Boot R2DBC + MySQL example](https://www.bezkoder.com/spring-r2dbc-mysql/)
34 |
35 | > [Spring Boot + GraphQL + MySQL example](https://www.bezkoder.com/spring-boot-graphql-mysql-jpa/)
36 |
37 | > [Spring Boot Rest XML example – Web service with XML Response](https://www.bezkoder.com/spring-boot-rest-xml/)
38 |
39 | > [Spring Boot: Upload CSV file data into MySQL Database](https://www.bezkoder.com/spring-boot-upload-csv-file/)
40 |
41 | > [Spring Boot: Upload Excel file data into MySQL Database](https://www.bezkoder.com/spring-boot-upload-excel-file-database/)
42 |
43 | > [Spring Boot Validate Request Body](https://www.bezkoder.com/spring-boot-validate-request-body/)
44 |
45 | > [Spring Boot and Swagger 3 example](https://www.bezkoder.com/spring-boot-swagger-3/)
46 |
47 | > [Spring Boot Redis Cache example](https://www.bezkoder.com/spring-boot-redis-cache-example/)
48 |
49 | > [Spring Boot File upload example](https://www.bezkoder.com/spring-boot-file-upload/)
50 |
51 | > [Exception handling: @RestControllerAdvice example in Spring Boot](https://www.bezkoder.com/spring-boot-restcontrolleradvice/)
52 |
53 | > [Spring Boot Repository Unit Test with @DataJpaTest](https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/)
54 |
55 | > [Spring Boot Rest Controller Unit Test with @WebMvcTest](https://www.bezkoder.com/spring-boot-webmvctest/)
56 |
57 | > [Deploy Spring Boot App on AWS – Elastic Beanstalk](https://www.bezkoder.com/deploy-spring-boot-aws-eb/)
58 |
59 | Security:
60 | > [Spring Boot + Spring Security JWT Authentication & Authorization](https://www.bezkoder.com/spring-boot-jwt-authentication/)
61 |
--------------------------------------------------------------------------------
/bezkoder-app/Dockerfile:
--------------------------------------------------------------------------------
1 | # FROM maven:3.8.5-openjdk-17 # for Java 17
2 | FROM maven:3.8.2-jdk-8
3 |
4 | WORKDIR /bezkoder-app
5 | COPY . .
6 | RUN mvn clean install
7 |
8 | CMD mvn spring-boot:run
--------------------------------------------------------------------------------
/bezkoder-app/README.md:
--------------------------------------------------------------------------------
1 | # Spring Boot JPA MySQL - Building Rest CRUD API example
2 |
3 | For more detail, please visit:
4 | > [Spring Boot JPA + MySQL - Building Rest CRUD API example](https://www.bezkoder.com/spring-boot-jpa-crud-rest-api/)
5 |
6 | > [Spring Boot JPA + PostgreSQL - Building Rest CRUD API example](https://www.bezkoder.com/spring-boot-postgresql-example/)
7 |
8 | More Practice:
9 | > [Spring Boot File upload example with Multipart File](https://www.bezkoder.com/spring-boot-file-upload/)
10 |
11 | > [Spring Boot Pagination & Filter example | Spring JPA, Pageable](https://www.bezkoder.com/spring-boot-pagination-filter-jpa-pageable/)
12 |
13 | > [Spring Data JPA Sort/Order by multiple Columns | Spring Boot](https://www.bezkoder.com/spring-data-sort-multiple-columns/)
14 |
15 | > [Spring Boot Repository Unit Test with @DataJpaTest](https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/)
16 |
17 | > [Deploy Spring Boot App on AWS – Elastic Beanstalk](https://www.bezkoder.com/deploy-spring-boot-aws-eb/)
18 |
19 | Security:
20 | > [Spring Boot + Spring Security JWT Authentication & Authorization](https://www.bezkoder.com/spring-boot-jwt-authentication/)
21 |
22 | Fullstack:
23 | > [Vue.js + Spring Boot + MySQL example](https://bezkoder.com/spring-boot-vue-js-mysql/)
24 |
25 | > [Angular 10 + Spring Boot + MySQL example](https://www.bezkoder.com/angular-10-spring-boot-crud/)
26 |
27 | > [Angular 11 + Spring Boot + MySQL example](https://www.bezkoder.com/angular-11-spring-boot-crud/)
28 |
29 | > [Angular 12 + Spring Boot + MySQL example](https://bezkoder.com/angular-12-spring-boot-mysql/)
30 |
31 | > [Angular 13 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-13-mysql/)
32 |
33 | > [Angular 14 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-14-mysql/)
34 |
35 | > [Angular 15 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-15-mysql/)
36 |
37 | > [Angular 16 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-16-mysql/)
38 |
39 | > [React + Spring Boot + MySQL example](https://www.bezkoder.com/react-spring-boot-crud/)
40 |
41 | Run both Back-end & Front-end in one place:
42 | > [Integrate Angular with Spring Boot Rest API](https://www.bezkoder.com/integrate-angular-spring-boot/)
43 |
44 | > [Integrate React.js with Spring Boot Rest API](https://www.bezkoder.com/integrate-reactjs-spring-boot/)
45 |
46 | > [Integrate Vue.js with Spring Boot Rest API](https://www.bezkoder.com/integrate-vue-spring-boot/)
47 |
48 | ## Run Spring Boot application
49 | ```
50 | mvn spring-boot:run
51 | ```
52 |
53 |
--------------------------------------------------------------------------------
/bezkoder-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.1.RELEASE
9 |
10 |
11 | com.bezkoder
12 | spring-boot-data-jpa
13 | 0.0.1-SNAPSHOT
14 | spring-boot-data-jpa
15 | Demo project for Spring Boot Apis CRUD using Spring Data JPA
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 |
33 | mysql
34 | mysql-connector-java
35 | runtime
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-test
41 | test
42 |
43 |
44 | org.junit.vintage
45 | junit-vintage-engine
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-maven-plugin
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/bezkoder-app/src/main/java/com/bezkoder/spring/datajpa/SpringBootDataJpaApplication.java:
--------------------------------------------------------------------------------
1 | package com.bezkoder.spring.datajpa;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class SpringBootDataJpaApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(SpringBootDataJpaApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/bezkoder-app/src/main/java/com/bezkoder/spring/datajpa/controller/TutorialController.java:
--------------------------------------------------------------------------------
1 | package com.bezkoder.spring.datajpa.controller;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.ResponseEntity;
10 | import org.springframework.web.bind.annotation.CrossOrigin;
11 | import org.springframework.web.bind.annotation.DeleteMapping;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.PathVariable;
14 | import org.springframework.web.bind.annotation.PostMapping;
15 | import org.springframework.web.bind.annotation.PutMapping;
16 | import org.springframework.web.bind.annotation.RequestBody;
17 | import org.springframework.web.bind.annotation.RequestMapping;
18 | import org.springframework.web.bind.annotation.RequestParam;
19 | import org.springframework.web.bind.annotation.RestController;
20 |
21 | import com.bezkoder.spring.datajpa.model.Tutorial;
22 | import com.bezkoder.spring.datajpa.repository.TutorialRepository;
23 |
24 | @CrossOrigin(origins = "http://localhost:8081")
25 | @RestController
26 | @RequestMapping("/api")
27 | public class TutorialController {
28 |
29 | @Autowired
30 | TutorialRepository tutorialRepository;
31 |
32 | @GetMapping("/tutorials")
33 | public ResponseEntity> getAllTutorials(@RequestParam(required = false) String title) {
34 | try {
35 | List tutorials = new ArrayList();
36 |
37 | if (title == null)
38 | tutorialRepository.findAll().forEach(tutorials::add);
39 | else
40 | tutorialRepository.findByTitleContaining(title).forEach(tutorials::add);
41 |
42 | if (tutorials.isEmpty()) {
43 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
44 | }
45 |
46 | return new ResponseEntity<>(tutorials, HttpStatus.OK);
47 | } catch (Exception e) {
48 | return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
49 | }
50 | }
51 |
52 | @GetMapping("/tutorials/{id}")
53 | public ResponseEntity getTutorialById(@PathVariable("id") long id) {
54 | Optional tutorialData = tutorialRepository.findById(id);
55 |
56 | if (tutorialData.isPresent()) {
57 | return new ResponseEntity<>(tutorialData.get(), HttpStatus.OK);
58 | } else {
59 | return new ResponseEntity<>(HttpStatus.NOT_FOUND);
60 | }
61 | }
62 |
63 | @PostMapping("/tutorials")
64 | public ResponseEntity createTutorial(@RequestBody Tutorial tutorial) {
65 | try {
66 | Tutorial _tutorial = tutorialRepository
67 | .save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), false));
68 | return new ResponseEntity<>(_tutorial, HttpStatus.CREATED);
69 | } catch (Exception e) {
70 | return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
71 | }
72 | }
73 |
74 | @PutMapping("/tutorials/{id}")
75 | public ResponseEntity updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
76 | Optional tutorialData = tutorialRepository.findById(id);
77 |
78 | if (tutorialData.isPresent()) {
79 | Tutorial _tutorial = tutorialData.get();
80 | _tutorial.setTitle(tutorial.getTitle());
81 | _tutorial.setDescription(tutorial.getDescription());
82 | _tutorial.setPublished(tutorial.isPublished());
83 | return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
84 | } else {
85 | return new ResponseEntity<>(HttpStatus.NOT_FOUND);
86 | }
87 | }
88 |
89 | @DeleteMapping("/tutorials/{id}")
90 | public ResponseEntity deleteTutorial(@PathVariable("id") long id) {
91 | try {
92 | tutorialRepository.deleteById(id);
93 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
94 | } catch (Exception e) {
95 | return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
96 | }
97 | }
98 |
99 | @DeleteMapping("/tutorials")
100 | public ResponseEntity deleteAllTutorials() {
101 | try {
102 | tutorialRepository.deleteAll();
103 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
104 | } catch (Exception e) {
105 | return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
106 | }
107 |
108 | }
109 |
110 | @GetMapping("/tutorials/published")
111 | public ResponseEntity> findByPublished() {
112 | try {
113 | List tutorials = tutorialRepository.findByPublished(true);
114 |
115 | if (tutorials.isEmpty()) {
116 | return new ResponseEntity<>(HttpStatus.NO_CONTENT);
117 | }
118 | return new ResponseEntity<>(tutorials, HttpStatus.OK);
119 | } catch (Exception e) {
120 | return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
121 | }
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/bezkoder-app/src/main/java/com/bezkoder/spring/datajpa/model/Tutorial.java:
--------------------------------------------------------------------------------
1 | package com.bezkoder.spring.datajpa.model;
2 |
3 | import javax.persistence.*;
4 |
5 | @Entity
6 | @Table(name = "tutorials")
7 | public class Tutorial {
8 |
9 | @Id
10 | @GeneratedValue(strategy = GenerationType.AUTO)
11 | private long id;
12 |
13 | @Column(name = "title")
14 | private String title;
15 |
16 | @Column(name = "description")
17 | private String description;
18 |
19 | @Column(name = "published")
20 | private boolean published;
21 |
22 | public Tutorial() {
23 |
24 | }
25 |
26 | public Tutorial(String title, String description, boolean published) {
27 | this.title = title;
28 | this.description = description;
29 | this.published = published;
30 | }
31 |
32 | public long getId() {
33 | return id;
34 | }
35 |
36 | public String getTitle() {
37 | return title;
38 | }
39 |
40 | public void setTitle(String title) {
41 | this.title = title;
42 | }
43 |
44 | public String getDescription() {
45 | return description;
46 | }
47 |
48 | public void setDescription(String description) {
49 | this.description = description;
50 | }
51 |
52 | public boolean isPublished() {
53 | return published;
54 | }
55 |
56 | public void setPublished(boolean isPublished) {
57 | this.published = isPublished;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]";
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/bezkoder-app/src/main/java/com/bezkoder/spring/datajpa/repository/TutorialRepository.java:
--------------------------------------------------------------------------------
1 | package com.bezkoder.spring.datajpa.repository;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.jpa.repository.JpaRepository;
6 |
7 | import com.bezkoder.spring.datajpa.model.Tutorial;
8 |
9 | public interface TutorialRepository extends JpaRepository {
10 | List findByPublished(boolean published);
11 | List findByTitleContaining(String title);
12 | }
13 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 |
3 | services:
4 | mysqldb:
5 | image: mysql:5.7
6 | restart: unless-stopped
7 | env_file: ./.env
8 | environment:
9 | - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
10 | - MYSQL_DATABASE=$MYSQLDB_DATABASE
11 | ports:
12 | - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
13 | volumes:
14 | - db:/var/lib/mysql
15 | app:
16 | depends_on:
17 | - mysqldb
18 | build: ./bezkoder-app
19 | restart: on-failure
20 | env_file: ./.env
21 | ports:
22 | - $SPRING_LOCAL_PORT:$SPRING_DOCKER_PORT
23 | environment:
24 | SPRING_APPLICATION_JSON: '{
25 | "spring.datasource.url" : "jdbc:mysql://mysqldb:$MYSQLDB_DOCKER_PORT/$MYSQLDB_DATABASE?useSSL=false",
26 | "spring.datasource.username" : "$MYSQLDB_USER",
27 | "spring.datasource.password" : "$MYSQLDB_ROOT_PASSWORD",
28 | "spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.MySQL5InnoDBDialect",
29 | "spring.jpa.hibernate.ddl-auto" : "update"
30 | }'
31 | volumes:
32 | - .m2:/root/.m2
33 | stdin_open: true
34 | tty: true
35 |
36 | volumes:
37 | db:
38 |
--------------------------------------------------------------------------------