# Inheritance
==========================
# Association
=================
- Relationship between classes
- Binary Association
- ======================
- two classes
- Unary Association(course-prerequisite)
- ====================
- two instances of same class
- Ternary Association
- ========================
- three classes (eg. student-course-professor)
# Link
=================
- Relationship between two objects/instances
# Multiplicity
========================
- # of instances of A that may be associated with
- a given instance of B.
# 1:1
==================
- 1 instance of A is related to only 1 instance of B and v/s
- e..g Student-->transcript
- professor-->department :role=chairs
# 1:M
=====================
- 1 instance of A is related to many instance of B but
- single instance of B is related to exactly one instance
- of A.
- e.g Department-->professors (role:employs)
- Professors-->students(role: advises)
# M:M
=======================
- 1 instance of A can be related to many instance of B, and v/s
- e.g Student-->course (role: enrolls)
# Inheritance
===============================
- Assume: you've rigorously tested Student class
- new Requirement: GraduateStudents
- fields: underGradDegree and underGradInstitution
# Options?
===========
# Option 1:
- modifying the student class
# Option 2:
- clone the student class to GraduateStudent class
# Option 3:
- Take advantage of inheritance concept
# is-a nature of inheritance
=================================
- anything we can say about superclass is true about all
- subclasses
# Benefits of Inheritance
==========================
- reduces code redundancy
- use thoroughly tested codes without modifying it
- we can derive a new class even if we don't own the source
- code for the later-enhances productivity
# Method Overriding
=============================
- void print(){id,name,major,jpa};-->of student class
- void print(){id,name,major,jpa,underGradDeg,underGradIns};-->of
GraduateStudent class
## code redundancy
## solution????
=================================
- using the 'super' keyword to reuse code.
- on the Student class
- void print() {sout(getId()+"\n"+getName())}
- on GradStudent class,
- void print(){
super.print();
sout(this.getUnderGradDegree()+"\n"+...) }
- on the main method:
- create Student and GraduateStudent objects
- student.print();
- graduateStudent.print();
# Polymorphism
============================
- ability of two or more objects belonging to
- different classes to respond to exactly the same message
- (method call) in different class-specific ways.
# Constructors and Inheritance (using super(...) for constructor
reuse)
===================================================================
=
- constructors aren't inherited
# Assumptions:
===================================
- the following basic spring dependencies are installed/downloaded
- during your spring boot project creation:
- *******************************
- spring web
- spring data jpa
- lombok
- validation
- postgresql
- thymeleaf
- devtools
- ************************************
# Steps you need to follow:
=======================================
# Step 1:
===================
- create 5 packages under src/main/java/com.srms.demo
- model
- controller
- repository
- service
- serviceImplementation
- how?
- Right click on com.srms.demo/New/package
# Step 2:
===================================================================
==========
- under the model package, create your java classes
- how?
- RC on model/New/java class
- e.g
- Supplier (supplierId:Long, supplierNumber:int,
SupplierName:String,phoneNumber:String)
- Product(productId:Long, productNumber:Long,
productName:String, unitPrice:double, quantityInStock:int,
dateSupplied:LocalDate)
# Step 3:
===================================================================
============
- annotate the two entities/classes with the following spring
anotations:
- @Entity
- for both of the classes
- @Table(name="SUPPLIERS") for the Supplier table and
@Table(name="")
- for the Product class
- annotate the primary keys(supplierId, and productId) with:
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
# Step 4:
===================================================================
==========
- annotate the two classes with:
- @Getter
- @Setter
- to automatically use the getter and setter accessor
methods
# Step 5:
===================================================================
===========
- Generate a default constructor and a parameterized constructor
without the
- primary keys for both of the classes.
- How?
- RC/Generate/Constructor
- call also the default constructor inside your parameterized
constructor
- using super();
# Step 6:
===================================================================
============
- Make sure that you have already installed postgresql in your
machine
# Step 7:
===================================================================
=============
- Open the psql shell and follow the following steps:
- Server [localhost]: press Enter key-server name;
- Database [postgres]: press Enter key- postgres is the DB name
- Port [5432]: press Enter- 5432 is the default port number
- Username [postgres]: press Enter- postgres is the default
user name
- Password for user postgres-type password-eg. root
- postgres=#
- postgres=#\l -lists your databases
- postgres=#\CREATE DATABASE srmsdb; -creates a DB
named srmsdb
- postgres=#\l -make sure that the newly created DB
appears
# Step 8:
=======================
- Open the appliction.properties file found under:
- src/main/resources/application.properties
- and type the following commands on it:
--------------------------------------------------
spring.datasource.url=jdbc:postgresql://localhost:5432/srmsdb
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Postg
reSQLDialect
spring.jpa.properties.hibernate.format_sql=true
-------------------------------------------------------------
----
- N.B. the user name and password should match with
- your username and password you provided during the
- initial postgres installation!!!!!!
# Step 9:
===================================================================
===
- run your main method found under src/main/java/
- how?
- RC/Run
# Step 10:
===================================================================
==
- make sure that the two classes persist in your DB:
- how?
- go to your psql shell
- postgres=#\c srmsdb; -connect to srmsdb
database
- srmsdb=# \dt -list relations
- now, product and suppliers tables are created or
persisted
- srmsdb=# \d product
- \d product;
- \d suppliers;
# Step 11:
===================================================================
======
# Creating Repository
===================================================================
======
- Create the following Interfaces under your repository package:
- ISupplierRepository
- IProductRepository
- how?
- RC on repository package/New/Java class/type the above
- interface names/select Interface from the options/Enter
# Step 12:
============================================================
- annotate your interfaces with:
- @Repository
# Step 13:
=============================================================
- extend your interfaces to JpaRepository<>
- inside the angle brackets, put the Product and Supplier class
names
- then comma and then the datatype of their corresponding primary
keys' datatype
- e.g public interface ISupplierRepository extends
JpaRepository<Supplier, Long>
# Step 14:
==========================================================
# Creating Interface Services
=======================================================
- create the following interfaces inside the service package:
- ISupplierService
- IProductService
# Step 15:
=============================================================
- add the following abstract methods inside the above corresponding
interfaces:
- e.g under the IProductService:
- ------------------------------------------------------
- public abstract List<Product> findAll();
public abstract Product save(Product product);
public abstract Product findById(Long id);
public abstract void delete(Long id);
- -----------------------------------------------
- under the ISupplierService:
-------------------------------------------------
public abstract List<Supplier> findAll();
public abstract Supplier save(Supplier supplier);
public abstract Supplier findById(Long id);
public abstract void delete(Long id);
----------------------------------------------------------
# Step 16:
===================================================
- Create the following classes under serviceImplementation package:
- SupplierService
- ProductService
- implement the above classes to their corresponding interfaces:
- e.g public class SupplierService implements ISupplierService
- Autowired these classes with the following spring annotations:
- @Service
# Step 17:
==============================================================
- hover on the class names and select implement methods option
- Then automatically all the interface abstract methods will
- be overriden and implemented in the child classes
- N.B. It is a must to implement the abstract methods
# Step 18
==============================================================
- Autowired your service implementation classes with your
- repository interface with the following annotaion and declare
- a reference variable of type repository:
- e.g on the SupplierService class;
- @Autowired
- ISupplierRepository iSupplierRepository;
- and on the ProductService class;
- @Autowired
- IProductRepository iProductRepository;
- N.B. you can also put the Repository and Service names like:
- @Repository("supplierRepository")
- @Service("SupplierService")
# Step 19:
==================================================
- write the implementation bodies of the overriden methods:
- e.g
- @Override
public List<Product> findAll() {
return productRepository.findAll();
}
@Override
public Product save(Product product) {
return productRepository.save(product);
}
@Override
public Product findById(Long id) {
Optional<Product> op =productRepository.findById(id);
return op.orElse(null);
}
@Override
public void delete(Long id) {
productRepository.deleteById(id);
- do the same for the SupplierService class
# Step 20:
======================================================
- Create the following classes under the controller package:
- RESTAPIController
- HomePageController
- ProductController
- SupplierController
# Step 21:
=================================================
# Working with REST API
================================================
- Open the RESEController class
- annotate that class with:
- @RestController
- @RequestMapping("/api")
- autowired this class to the productService using:
- @Autowired
- ProductService productService;
# CRUD Operation using RESTAPI
===================================================
# Step 22:
================================================
- implement all the methods:
- e.g- GetMapping
- =================================================
@GetMapping(value = "/products/{id}")
@ResponseBody
public Product findProductById(@PathVariable Long id) {
return productService.findById(id);
}
# Step 23: @GetMapping -retrieving
=======================================================
- open your browser or postman and type the following:
- http://localhost:8080/api/products/1
- and hit enter
# Step 24: @PostMapping -saving
=========================================
@PostMapping(value = "/products/add")
public ResponseEntity<Product> addProduct(@RequestBody Product
product) {
Product newProduct = productService.save(product);
return new ResponseEntity<Product>(newProduct ,
HttpStatus.CREATED);
//return new ResponseEntity<String>("Product Successfully
Created!", HttpStatus.CREATED);
}
# Step 25:
====================================================
# Play with postman by using GET and POST methods
# but you need to get connected with internet while using,
at least to start working with postman!!!!
======================================================
# Step 26
===============================================================
- annotate the dataSupplied attribute of the Product class with
- @DateTimeFormat(pattern = "yyyy-MM-dd")
# Step 26: @DeleteMapping -deleting
===============================================================
@DeleteMapping(value = "/products/delete/{id}")
//@ResponseBody
public ResponseEntity<String> deleteProductById(@PathVariable Long
id) {
productService.delete(id);
return new ResponseEntity<String>("Product Deleted Successfully!
Product ID: " + id,
HttpStatus.OK);
}
# Step 27: @PutMapping -updating
===================================================================
===
@PutMapping(value = "/products/update")
public Product updateProduct(@RequestBody Product product) {
return productService.save(product);
}
# Step 28: @GetMapping -retrieving all fields
=======================================================
@RequestMapping(value = "/products", method = RequestMethod.GET)
@ResponseBody
// @CrossOrigin(origins = "http://localhost:4200")
public List<Product> getAllProducts() {
return productService.findAll();
}
# Step 29:
=======================================================
Creating Relationship Between Supplier and Product
========================================================
- A given supplier can supply one or more (many) products
- but
- A specific product can only be supplied by one supplier
- ----------------------------------------------------------
-Supplier ----------------> Product
- one-------------------------->many
- on the supplier side:
- @OneToMany
# Step 30:
=====================================================
- add the following attribute to the Supplier class:
- private List<Product> products = new ArrayList<Product>();
# Step 31:
===========================================
- annotate this attribute with:
- @OneToMany(mappedBy = "supplier", cascade =
CascadeType.PERSIST)
-
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator
.class,property="@id", scope = Product.class)
# Step 32:
================================================
- Add the following attribute to the Product class
- private Supplier supplier;
# Step 33:
====================================================
- annotate this attribute with:
- @ManyToOne
@JoinColumn(name = "supplierId", nullable = false)
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator
.class,property="@id", scope = Supplier.class)
# Step 34:
===================================================
- if error occurs while running your application, make the
following
- change to your application.properties file and rerun it again:
// spring.jpa.hibernate.ddl-auto=create-drop
- spring.jpa.hibernate.ddl-auto=update
# Step 35:
===========================================================
- make some changes to your Supplier and Product classes
- to add the above attributes to their corresponding constructors.
-------------------------------------------------------------------
----
POST http://localhost:8080/api/supplier/add
Content-Type: application/json
{
"supplier": {
"supplierName": "solomon",
"supplierNumber": 23,
"phoneNumber": "2345"
}
}
------------------------------------------------------------
POST http://localhost:8080/api/products/add
Content-Type: application/json
{
"productNumber": 23,
"dateSupplied": "2023-01-01",
"productName": "laptop",
"unitPrice": 23.45,
"quantityInStock": 23,
"supplier": {
"supplierId": 1
}
}
-------------------------------------------------------------------
----
# Step 36:
==========================================
- copy and paste the following thymeleaf configuration file into
- application.properties file:
- -----------------------------------------------------
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.mode=HTML5
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
- -----------------------------------------------------
# Step 37:
========================================================
- create the following directories under the ff path:
- src/main/resources/templates:
- common
- homepage
- product
- supplier
# Step 38:
===================================================================
=
- add the following dependencies
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.5.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
# Step 38:
=================================================================
- create html file named masterlayout.html file under the
- common directory, copy and paste the following code to
- your html file:
- -----------------------------------------------------------
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<link rel="stylesheet" type="text/css"
th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<link rel="stylesheet" type="text/css"
th:href="@{/css/masterlayout.css}" />
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-primary">
<a class="navbar-brand" href="#">Home</a>
<button class="navbar-toggler" type="button" data-
toggle="collapse" data-target="#navbarSupportedContent" aria-
controls="navbarSupportedContent" aria-expanded="false" aria-
label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse"
id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#">Product</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Supplier</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search"
placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0"
type="submit">Search</button>
</form>
</div>
</nav>
<div class="container">
<!--Thymeleaf placeholder for the page Content-->
<th:block layout:fragment="content"></th:block>
<!--End placeholder-->
</div>
<!--Thymeleaf placeholder for additional footer content-->
<th:block layout:fragment="footer"></th:block>
<!--End placeholder-->
<footer class="footer">
<div class="container">
<span class="text-muted">
Supplier Relation Management System | Nov
2023</span><span
style="float: right;" class="text-muted">© No
2023</span>
</div>
</footer>
<!--bootstrap script-->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-
KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.
min.js" integrity="sha384-
ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap
.min.js" integrity="sha384-
JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
- -------------------------------------------------------------
# Step 39:
=========================================================
- create html file named index.html under homepage directory:
- RC/New/HTML File/name it index, and add:
- ----------------------------------------------------
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{common/masterlayout.html}">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css"
th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<!-- <link rel="stylesheet" type="text/css"
th:href="@{/css/masterlayout.css}" />-->
</head>
<body>
<th:block layout:fragment="content">
<h3> Supplier Relation Management System</h3>
</th:block>
<th:block layout:fragment="footer"></th:block>
<!--<div class="container-fluid text-center" >-->
<!--<h1>Welcome to my home page</h1>-->
<!-- <a class="h2" th:href="@{/users}">Manage Users</a>-->
<!--</div>-->
</body>
</html>
- -----------------------------------------------------
# Step 40:
==============================================
- go to the HomePageController class found under the controller
- package and write the following method:
- -----------------------------------------------------------------
@Controller
public class HomePageController {
@GetMapping("/home")
public String homeController(){
return "homepage/index";
}
}
-------------------------------------------------------------------
------