diff --git a/persistence-modules/spring-boot-mysql/mysql-server/convertcerts.sh b/persistence-modules/spring-boot-mysql/mysql-server/convertcerts.sh
new file mode 100644
index 0000000000..eb3700e578
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/mysql-server/convertcerts.sh
@@ -0,0 +1,7 @@
+# Convert pem to jks file
+mkdir certs
+
+keytool -importcert -alias MySQLCACert.jks -file ./data/ca.pem \
+ -keystore ./certs/truststore.jks -storepass mypassword
+openssl pkcs12 -export -in ./data/client-cert.pem -inkey ./data/client-key.pem -out ./certs/certificate.p12 -name "certificate"
+keytool -importkeystore -srckeystore ./certs/certificate.p12 -srcstoretype pkcs12 -destkeystore ./certs/client-cert.jks
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/mysql-server/createuser_query.sql b/persistence-modules/spring-boot-mysql/mysql-server/createuser_query.sql
new file mode 100644
index 0000000000..b7e170eb85
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/mysql-server/createuser_query.sql
@@ -0,0 +1,2 @@
+CREATE USER 'test_user'@'%' IDENTIFIED BY 'Password2022' require X509;
+GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'%';
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/mysql-server/docker-compose.yml b/persistence-modules/spring-boot-mysql/mysql-server/docker-compose.yml
new file mode 100644
index 0000000000..ee5bc75bfb
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/mysql-server/docker-compose.yml
@@ -0,0 +1,21 @@
+version: '3.8'
+
+services:
+ mysql-service:
+ image: "mysql/mysql-server:8.0.30"
+ container_name: mysql-db
+ command: [ "mysqld",
+ "--require_secure_transport=ON",
+ "--default_authentication_plugin=mysql_native_password",
+ "--general_log=ON" ]
+ ports:
+ - "3306:3306"
+ volumes:
+ - type: bind
+ source: ./data
+ target: /var/lib/mysql
+ restart: always
+ environment:
+ MYSQL_ROOT_HOST: "%"
+ MYSQL_ROOT_PASSWORD: "Password2022"
+ MYSQL_DATABASE: test_db
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/pom.xml b/persistence-modules/spring-boot-mysql/pom.xml
index 239378c7b1..6c8266e034 100644
--- a/persistence-modules/spring-boot-mysql/pom.xml
+++ b/persistence-modules/spring-boot-mysql/pom.xml
@@ -42,4 +42,21 @@
8.0.23
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.1.5.RELEASE
+
+
+
+ repackage
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/Employee.java b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/Employee.java
new file mode 100644
index 0000000000..28869d0ac1
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/Employee.java
@@ -0,0 +1,59 @@
+package com.baeldung.boot.jpa;
+
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.util.Date;
+
+@Entity
+public class Employee implements Serializable {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "id")
+ private Integer id;
+
+ @Column(name = "emp_name")
+ private String empName;
+
+ @Column(name = "job_title")
+ private String jobTitle;
+
+ @Column(name = "emp_doj")
+ private LocalDate empDoj;
+
+ @Column(name = "created_date")
+ private Date createdDate = new Date();
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getEmpName() {
+ return empName;
+ }
+
+ public void setEmpName(String empName) {
+ this.empName = empName;
+ }
+
+ public String getJobTitle() {
+ return jobTitle;
+ }
+
+ public void setJobTitle(String jobTitle) {
+ this.jobTitle = jobTitle;
+ }
+
+ public LocalDate getEmpDoj() {
+ return empDoj;
+ }
+
+ public void setEmpDoj(LocalDate empDoj) {
+ this.empDoj = empDoj;
+ }
+
+ public Date getCreatedDate() {
+ return createdDate;
+ }
+}
diff --git a/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeController.java b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeController.java
new file mode 100644
index 0000000000..ac394476d5
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeController.java
@@ -0,0 +1,26 @@
+package com.baeldung.boot.jpa;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.util.Optional;
+
+@RestController
+public class EmployeeController {
+
+ @Autowired
+ private EmployeeRepository empRepository;
+
+ @GetMapping("/employee/{empId}")
+ public Employee get(@PathVariable(name = "empId") Integer empId) {
+ Optional emp = empRepository.findById(empId);
+ return emp.orElse(null);
+ }
+
+ @PostMapping("/employee")
+ public Employee createUser(@RequestBody Employee employee) {
+ empRepository.save(employee);
+ return employee;
+ }
+}
diff --git a/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeRepository.java b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeRepository.java
new file mode 100644
index 0000000000..38ace202d6
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/src/main/java/com/baeldung/boot/jpa/EmployeeRepository.java
@@ -0,0 +1,10 @@
+package com.baeldung.boot.jpa;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.io.Serializable;
+
+@Repository
+public interface EmployeeRepository extends JpaRepository {
+}
diff --git a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
index f660ab4759..d70c21aad2 100644
--- a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
+++ b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
@@ -1,9 +1,8 @@
spring:
- datasource:
- url: jdbc:mysql://localhost:3306/test?
- username: root
- password:
-
+ profiles:
+ active: "dev2"
+ main:
+ banner-mode: "off"
jpa:
hibernate:
ddl-auto: update
@@ -11,4 +10,26 @@ spring:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
jdbc:
- time_zone: UTC
\ No newline at end of file
+ time_zone: UTC
+---
+
+spring:
+ profiles: "dev1"
+ datasource:
+ url: jdbc:mysql://localhost:3306/test?
+ username: root
+ password:
+
+---
+
+spring:
+ profiles: "dev2"
+ datasource:
+ url: >-
+ jdbc:mysql://localhost:3306/test_db?sslMode=VERIFY_CA&
+ trustCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/truststore.jks&
+ trustCertificateKeyStorePassword=mypassword&
+ clientCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/client-cert.jks&
+ clientCertificateKeyStorePassword=mypassword
+ username: test_user
+ password: Password2022
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/src/test/java/com/baeldung/boot/jpa/EmployeeControllerUnitTest.java b/persistence-modules/spring-boot-mysql/src/test/java/com/baeldung/boot/jpa/EmployeeControllerUnitTest.java
new file mode 100644
index 0000000000..812e6a6b29
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/src/test/java/com/baeldung/boot/jpa/EmployeeControllerUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.boot.jpa;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import java.time.LocalDate;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(EmployeeController.class)
+public class EmployeeControllerUnitTest {
+
+ @MockBean
+ private EmployeeRepository employeeRepository;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Test
+ public void givenEmployeeId_whenGetEmployeeCalled_ThenReturnEmployee() throws Exception {
+ Employee employeeExpected = new Employee();
+ employeeExpected.setEmpName("Test Emp");
+ employeeExpected.setEmpDoj(LocalDate.now());
+ employeeExpected.setJobTitle("Manager");
+
+ when(employeeRepository.findById(1234)).thenReturn(Optional.of(employeeExpected));
+
+ MvcResult result = mockMvc.perform(get("/employee/1234"))
+ .andExpect(status().isOk()).andReturn();
+
+ Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
+ assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
+ assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
+ assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
+ }
+
+ @Test
+ public void givenEmployee_whenCreateEmployeeCalled_ThenReturnEmployee() throws Exception {
+ Employee employeeExpected = new Employee();
+ employeeExpected.setEmpName("Test Emp");
+ employeeExpected.setEmpDoj(LocalDate.now());
+ employeeExpected.setJobTitle("Manager");
+
+ when(employeeRepository.save(employeeExpected)).thenReturn(employeeExpected);
+
+ MvcResult result = mockMvc.perform(post("/employee")
+ .content(objectMapper.writeValueAsString(employeeExpected))
+ .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();
+
+ Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
+ assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
+ assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
+ assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
+ }
+}
diff --git a/persistence-modules/spring-boot-mysql/start_app.sh b/persistence-modules/spring-boot-mysql/start_app.sh
new file mode 100644
index 0000000000..2f126a9c88
--- /dev/null
+++ b/persistence-modules/spring-boot-mysql/start_app.sh
@@ -0,0 +1,13 @@
+export TRUSTSTORE=./mysql-server/certs/truststore.jks
+export TRUSTSTORE_PASSWORD=mypassword
+export KEYSTORE=./mysql-server/certs/client-cert.jks
+export KEYSTORE_PASSWORD=mypassword
+export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/test_db?sslMode=VERIFY_CA
+export SPRING_DATASOURCE_USERNAME=test_user
+export SPRING_DATASOURCE_PASSWORD=Password2022
+
+java -Djavax.net.ssl.keyStore=$KEYSTORE \
+ -Djavax.net.ssl.keyStorePassword=$KEYSTORE_PASSWORD \
+ -Djavax.net.ssl.trustStore=$TRUSTSTORE \
+ -Djavax.net.ssl.trustStorePassword=$TRUSTSTORE_PASSWORD \
+ -jar ./target/spring-boot-mysql-0.1.0.jar
\ No newline at end of file