Download as pdf or txt
Download as pdf or txt
You are on page 1of 32

Web Applications - Server Side Track – week 4

External data
sources

Gerralt Gottemaker
2020 - 2021
<h1>Today’s subjects:</h1>
Web Applications <ul>
week 4 <li>Revision of MVC</li>
Adding a (remote) data <li>Introduction to Hibernate</li>
source to our APIs.
<li class=“diy”>Adding data source</li>
<li>Entities and Repositories</li>
<li class=“diy”>CRUD data source</li>
<li>Custom queries</li>
<li class=“diy”>Deeper dive</li>
</ul>
Controller sends Controller requests
MVC model data back to the view Controller information from
a service

Last week… Remember?


Service

Service gets data


View

User does HTTP


Whatever
request from the
The view datasource
renders browser
in the browser

Model
Controller sends Controller requests
MVC model data back to the view Controller information from
a service

Today, we expand the MVC


model by adding Hibernate. Service

Service gets data


View

User does HTTP


request from the Hibernate
The view
renders browser
in the browser

Model
Hibernate is an ORM framework that helps with abstracting
your data from your code.
Introduction to
Hibernate ORM: Object/Relational Mapping
What is Hibernate? - Makes sure (Java) Objects are mapped to a Relational
database
- Sounds easier than it is!
- It uses, just as Spring and Jackson, Java reflection

Abstracting your data from your code


- You don’t have to write (custom) queries for basic things
- Helps with speeding up your development
- Helps with reducing bugs in your code Hibernate
- Helps with if you want to change data sources

Model
Services
Introduction to
Hibernate
Let’s zoom in a bit…
Hibernate

Repositories

Config Entities

Model
Services
Introduction to
Hibernate
Let’s zoom in a bit…
Hibernate

Repositories

Config Entities

!
Which database you want to
use, doesn’t matter for Model
Hibernate. In this course, we are
using PostgreSQL.
Hibernate can be added to your project in two ways.

Introduction to Existing project:


Hibernate 1. Open your build.gradle file
Adding it to your project

2. Add the following two dependencies to it:


implementation('org.springframework.boot:spring-
boot-starter-data-jpa’)
implementation('org.postgresql:postgresql’)

The first dependency is for Hibernate, the second dependency makes


sure Hibernate can use PostgreSQL.
Hibernate can be added to your project in two ways.

Introduction to Existing project:


Hibernate 3. Reload your dependencies if that doesn’t happen
Adding it to your project automatically.
Hibernate can be added to your project in two ways.

Introduction to New project:


Hibernate 1. Start a new project the same way you are used to.
Adding it to your project

2. At the dependency step, make sure to select:


- Spring Web (standard, mandatory)
- Spring Boot DevTools (extra, optional)
- Spring Data JPA (hibernate, mandatory)
- PostgreSQL Driver (database, mandatory)

3. Make sure to check your build.gradle to see if it contains


everything
We need to configure Hibernate (and Spring) to make sure it
knows what database to use.
Introduction to
Hibernate A few prerequisites:
Configuring Hibernate ü PostgreSQL must be running
ü You have a tool to manage PostgreSQL (pgAdmin)

With that tool (pgAdmin):


ü Make sure to have a user available that your application can
use
ü Create a database with a good name, with that user as owner

Config
We need to configure Hibernate (and Spring) to make sure it
knows what database to use.
Introduction to
Hibernate Let’s say there is a database demo_db with the owner demo
Configuring Hibernate (without password).

# ---- Datasource properties ----


spring.datasource.platform=postgres
# URL to the database.
# Usually only database name has to be changed
spring.datasource.url=jdbc:postgresql://localhost:5432/demo_db
spring.datasource.username=demo
spring.datasource.password=

# ---- JPA properties ----


# Show SQL on console?
spring.jpa.show-sql=true
# Should Hibernate create the tables (schemas)?
Config spring.jpa.generate-ddl=true
# Should Hibernate drop all tables on shutdown?
# ONLY for debugging / developing!
spring.jpa.hibernate.ddl-auto=create-drop
Do It Yourself time! Connecting to your database

1. Download the project from Blackboard, located in folder:


week 4 – Server-side – During workshop

2. Create a new user for your spring boot projects, give it a


proper name

3. Create a new database for this spring boot project, give it


a proper name

4. Change the properties-file in the project from Blackboard


so it connects to your newly created database, using the
newly created user.

5. Start the project. If everything goes well, your project will


startup normally. It doesn’t serve anything yet
- Services use Repositories to access Entities (model classes)
- Repositories get their Entities from the database
Entities
- Entities are the ”simple” classes you know from OOP, with the
Introduction addition of some @annotations. Hibernate uses these
annotations to map the model classes to relational data (ORM).

Services

Hibernate
Repositories

Config Entities

Model
We start off with a (simple) Java class.

Entities public class Cat {

Simple example private Long id;


private String name;
private String gender;
private int age;

// Constructor(s), getters, setters


}
Add annotations to your class

Entities @Entity
public class Cat {
Simple example
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column
private String name;

@Column
private String gender;

@Column
private int age;

// Constructor(s), getters, setters


}
Add annotations to your class

Entities @Entity
Table (cat) public class Cat {

@Id
ID, will be automatically @GeneratedValue(strategy = GenerationType.IDENTITY)
generated private Long id;

@Column
Column (name)
private String name;

@Column
Column (gender) private String gender;

@Column
Column (age) private int age;

// Constructor(s), getters, setters


}
Want different names?

Entities @Entity(name = "my_cats")


public class Cat {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "custom_name")
private String name;

...
}

!
@Column annotations are optional if
default names are used. It is good
practice however to add them anyway
(readability, showing intentions)
Let’s add a class

Entities public class Person {

private Long id;


One-to-many relationships private String name;
private int age;
private List<Cat> cats;

// Constructor(s), getters, setters


}

public class Cat {

private Long id;


private String name;
private String gender;
private int age;

// Constructor(s), getters, setters


}
Tell Hibernate that the table person has a list of cats

Entities @Entity
public class Person {
One-to-many relationships ...
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true)
private List<Cat> cats;
...
}

@Entity
public class Cat {
...
}
Do It Yourself time! Creating your Entities

1. Use the same project as the last DIY

2. Annotate the Cat class with the proper annotations

3. Run the Spring Boot project

4. Check the database using pgAdmin. There is now a cat


table!

5. (Bonus if you have time) Create a Person entity with a one-


to-many relationship to Cat
- Services use Repositories to access Entities (model classes)
- Repositories get their Entities from the database
Repositories
- Repositories are interfaces that are the “bridge” between the
Introduction entities, database data and the Services that use the entities.
- Repositories use generics to define what entity they are serving.
- Repositories have a lot of standard methods, provided by
Hibernate.

Services

Hibernate
Repositories

Config Entities

Model
A few steps.

Repositories Create a (simple) Java interface.


public interface CatRepository {
Simple example }

Make sure you annotate it to be a Spring Repository


@Repository
public interface CatRepository {
}

And let it extend from CrudRepository


@Repository
public interface CatRepository extends
CrudRepository<Cat, Long> {
}
A Repository uses Java generics.

Repositories You’ve seen Java generics before. For example, when creating an
ArrayList and you tell it what type it holds. Or, when you created a
Simple example Comparable and you told it what to compare itself to.

We need to tell the CrudRepository two things:


@Repository
public interface CatRepository extends
CrudRepository<Cat, Long> {
}

1. What Entity are we serving? (1st generic param)


2. What is the type of the unique identifier? (2nd generic param)

And that’s all! Now, we can use the methods provided by


CrudRepository.
// Finds all rows in the cat table.
// Will return Iterable instead of List. More on this later!
Repositories
Iterable<Cat> allCats = this.catRepository.findAll();

// Checks
Standardiffunctionality
a row with id exists in the cat table
boolean exists = this.catRepository.existsById(id);

// Will find one row. Returns an Optional object, so it either holds 1 or 0 object(s).
// use cat.isPresent() and cat.isEmpty() to check if it's there or not.
// If it's there, use cat.get() to actually grab it.
Optional<Cat> cat = this.catRepository.findById(id);

// Saves a cat.
// If no ID is given, this will create a new row
// If an ID is given, it will update the existing row
// Will return the newly saved cat, including (new) id.
Cat cat = this.catRepository.save(cat);

// Deletes a cat. Will return true if succeeded, false otherwise


boolean succeeded = this.catRepository.delete(cat);
Add a reference to your Service to use it.

Repositories We can do that the same way we added our Service to our
Controller.
Usage
1. Create a (private final) instance variable of the type
CatRepository
2. Create a CatService constructor that takes the CatRepository
as a parameter and assign it to the instance variable.
3. You are now ready to use the CatRepository in your Service!
@Service
public class CatService {

private CatRepository catRepository;

public CatService(CatRepository catRepository) {


this.catRepository = catRepository;
}
...
}
If you want to do more than the basic things, you can write custom
methods in your Repository interface. Because it’s an interface,
Repositories these methods need to be abstract (and therefore have no body!)

Custom methods for There are two ways of adding custom queries:
custom queries 1. Using the @Query annotation above your custom method
@Query("select c from Cat c where c.gender = :gender")
List<Cat> yourOwnName(@Param("gender") String gender);

!
The query isn’t really SQL, because they try to make it database
independent. The language follows a mix of SQL and object-
oriented notations.
2. Using the Hibernate method naming conventions
List<Cat> findAllByGender(String gender);

ByGender = will find


findAll = multiple
anything with a given
results, so return a List
gender
Don’t worry if you can’t remember everything. IntelliJ has great
auto complete functionality for these queries!!
Repositories

Custom methods for


custom queries

Make sure to use this. Saves you lots of trouble!


One more (important!) thing.

Repositories

Custom methods for


custom queries

!
Usually, it’s good to override the default findAll() method so it
returns a List instead of an Iterator. Iterators are harder to work
with than Lists, so this one line of code saves you from a lot of
trouble.
@Repository
public interface CatRepository extends CrudRepository<Cat, Long> {

// Good way of making sure findAll returns a List instead of Iterable


@Override
List<Cat> findAll();

...
}
Do It Yourself time! Creating your Entities

1. Use the same project as the last DIY

2. Create a package “repositories” and create a


CatRepository interface. Follow the steps described in the
previous few sheets

3. Create custom methods for findAll() and to find all cats by


gender

4. Connect your CatRepository to your CatService

5. Fix the TODOs in the CatService by calling the


CatRepository methods
… we have talked about:

To summarize… - Hibernate and what an ORM framework is

- How Hibernate uses Repositories and Entities to manage


database tables

- How to create those Entities and Repositories

- That Repositories can do custom stuff using @Query or correct


named methods
Services

- That Services communicate with Repositories and that


Hibernate Repositories will reply with Entity objects (or lists of them)
Repositories

Config Entities

Model
That’s all folks!

What’s next?

This week:
• Get familiar with the usage of Repositories and its custom
methods
• Expand the TODO API with a database (homework assignment)

Next week:
• Working on our own project (final assignment)

You might also like