Config :

Pasted image 20240316092322.png

Dependencies Used :

Pasted image 20240316092558.png

  • Spring Security will be used later in this project.

Updating application.properties :

spring.application.name=examtool  
server.port=8085

Connecting a database :

  • If a database is not connected to our application then we will not be able to run the application as we have included the MySQLDriver dependency.
    • Error that we get if we have not connected a database :
      Pasted image 20240316093329.png

Pasted image 20240316093506.png

  • Using the highlighted database.

Create a new Schema :

Pasted image 20240316093637.png

Spring boot will require the URL to the database, user id and password to this database.

  • Our work with workbench is done here, queries will be executed using JPA.

application.properties :

spring.application.name=examtool
server.port=8085

# Database Connection
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/examportal
#spring.datasource.url=jdbc:mysql://localhost:3306/Local instance MySQL80
spring.datasource.username=root
spring.datasource.password=homealone

# Hibernate Configuration
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.generate-ddl=true
# generate ddl automatically created a table
  • JDBC driver is used to connect to MySQL
  • Notice the second half of the above code block, JPA is used for automatic creation and execution of queries to avoid manual query writing. We can also create custom queries to meet our own requirements.

Including Lombok :

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
    <scope>provided</scope>
</dependency>

What are @Getter and @Setter? @Getter and @Setter are annotation belonging to Lombok library, these can be used to automatically generate getter and setter methods for fields in a Java class. This can save you a lot of time and boilerplate code, especially if you have a lot of fields in your class.

Configuring Lombok according to our project :

Adding lombok plugin :
Pasted image 20240316095749.png
Pasted image 20240316095600.png

In sts we'll have to install lombok manually using lombok.jar, which can be downloaded from https://projectlombok.org/download

Using Lombok : Getter Setters and More :

package com.tool.erp.modules;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Vector;

// Following Getter and Setter annotations are from Lombok library
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class APIReturnModel {
    private String status = "fail";
    private String message = "Something went wrong";
    private Vector<?> data;
    private int count = 0;
}

APIReturnModel.java

Pasted image 20240323125420.png

package com.tool.erp.setup;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Vector;

@Getter
@Setter
@NoArgsConstructor // Lombok will generate a constructor with no arguments
@AllArgsConstructor // Lombok will generate a constructor with all properties in the class
public class APIReturnModel {
    private String status = "fail";
    private String message = "Something Went Wrong !!";
    private Vector<?> data; // "?" means any type of data
    private int count = 0; // count of data
}

  • We are creating folders to organize our code. This is called Modular Approach, and it helps us in identifying the source of a bug/error.

UsersModel.java

  • We want this model to be inserted into the database. To achieve this, we'll have to define some fields (like @Entity).

For data type validations, we use the spring-boot-starter-validation dependency (otherwise we'll have to separately use if and else conditions for validations) :

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
package com.tool.erp.users.model;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;

import java.util.Date;
@Data // This annotation is used to generate getters, setters, toString, equals, and hashCode methods
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity // This annotation is used to mark the class as a persistent Java class
@Table(name = "User")
// This annotation is used to specify the table name (Note: A name like "User Employee" will be converted to "user_employee" in the database)
public class UsersModel {
    @Id // This annotation is used to specify the primary key of an entity
    @GeneratedValue(strategy = GenerationType.AUTO)
    // This annotation is used to specify how the primary key should be generated
    private int userId;

    @NotBlank(message = "User Name can't be Null")
    @Column(unique = true, nullable = false, updatable = false)
    private String userName;

    @NotBlank(message = "First Name can't be Null")
    @Column(nullable = false, updatable = false)
    @Size(max = 20, min = 2, message = "First Name must be between 2 and 20 characters")
    private String firstName;

    private String lastName;

    @NotBlank(message = "Password can't be Null")
    @Column(nullable = false)
    @Size(max = 20, min = 2, message = "Password must be between 8 and 20 characters")
    private String password;

    private String email;

    private String phoneNo;

    @CreationTimestamp
    @Column(updatable = false, nullable = false)
    @Temporal(TemporalType.TIMESTAMP)// This annotation is used to specify the type of data of the property
    private Date createdDate;

    @CreationTimestamp
    @Column(nullable = false, updatable = true)
    private Date modifiedDate;

    private String createdBy;

    private String modifiedBy;
}

Creating a new Schema :

Pasted image 20240323135054.png

  • Pasted image 20240323135132.png
    Schema has been created.
    When we run our spring application now a new table will be created by JPA Hibernate itself.
    Pasted image 20240323142321.png
    Pasted image 20240323142408.png

Continue From the Video :

Service

  • Service Classes are used to define how data is handled.

UsersController.java

  • To declare any class as a controller in spring boot, we use the @RestController annotation.
  • To connect Service class to this class we'll make an instance of the Service class.

Spring Security :

There are 2 ways, spring security handles 2 things : OAuth 2, and a "cheaper" version of OAuth 2 which is JWT and encrypted password.

JWT

So an encrypted password will be sent to the backend and on successful login a token will be returned. Each time the user hits an API the token will be matched before performing something.

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
		<groupId>io.jsonwebtoken</groupId>
		<artifactId>jjwt</artifactId>
		<version>0.12.2</version>
</dependency>

To use a custom username and password :

  • In application.properties
    Pasted image 20240414123324.png

Steps taken to make the auth package :

  • ! (images below depict a vague idea of the implementation only, taking a look at the final and completed project is recommended)
  1. During user login, we first think of what all things should be sent by the user in the post call (username and password of course) : JwtRequestModel
    Pasted image 20240414131801.png
  2. In the response we want a token