Opinionated Framework - Models & Migrations
What you will learn
- How to set the database settings
- how create models and migrations
- how to use models to add, update, and delete records
Setup
- We will keep using our demo lesson from this mornings lesson.
- open the command palette and select Spring -> Add Starters
- Add JPA Data and Postgres Drivers
- Allow the pom.xml file to updated with the new dependencies
Setting Up the Database Settings
- create a new local postgres database
createdb javaspringtest
Open up src/main/resources/application.properties and add the following... Make sure to use the username & password for your local postgres
# Database Settings
spring.datasource.url=jdbc:postgresql://localhost:5432/javaspringtest
spring.datasource.username=test5
spring.datasource.password=test5
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
# Allows for auto creation of tables
spring.jpa.hibernate.ddl-auto = update
Models and Migrations
JPA/Hibernate manages all of our database needs and will auto generate the tables based our Entities/Models when we first access them, so no need for migrations like in other setups.
So let's create another folder in our code folder (demo) called entities.
Let's create our first entity!
package learning.java.demo.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Turtle {
//**************************************** */
// Entity Properties
//**************************************** */
@Id //Denotes this property as the id/primary key
@GeneratedValue(strategy = GenerationType.AUTO) //auto generates
public Integer id;
public String name;
public Integer age;
//**************************************** */
// Constructors
//**************************************** */
public Turtle(){
}
public Turtle(String name, Integer age){
this.name = name;
this.age = age;
}
//**************************************** */
// GETTERS AND SETTERS
//**************************************** */
public Integer getId(){
return this.id;
}
public void setId(Integer id){
this.id = id;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public Integer getAge(){
return this.age;
}
public void setAge(Integer age){
this.age = age;
}
}
Creating Our Repository
Our entity works very similar to a mongoose schema in that it defines the shape of our data, but a repository is like a mongoose model with functions that allow us to actually add, update and delete data in the database. Create another folder called repositories and create a file called TurtleRepository.java inside of it.
package learning.java.demo.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import learning.java.demo.entities.Turtle;
// Our Repository, the two types in <> are the Entity and type of the ID
public interface TurtleRepository extends JpaRepository<Turtle, Integer>{
}
That's it time to make another controller and put this repository to work.
Using the Model
In the controllers folder create TurtleController.java
package learning.java.demo.controllers;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TurtleController {
}
In order to use our repository we to receive it in two steps...
- Create a property we can store the repository in
- Add the repository as an argument to the controllers constructor so spring passes an instance of the repository to our controller which we can store in the property.
// Property to hold Turtle Repository
public TurtleRepository Turtles;
// Receive Turtle Repository via Dependency Injection
public TurtleController(TurtleRepository Turtles){
this.Turtles = Turtles;
}
index
- get request to "/turtles/" that returns all turtles
package learning.java.demo.controllers;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import learning.java.demo.repositories.TurtleRepository;
import learning.java.demo.entities.Turtle;
@RestController
public class TurtleController {
// Property to hold Turtle Repository
public TurtleRepository Turtles;
// Receive Turtle Repository via Dependency Injection
public TurtleController(TurtleRepository Turtles){
this.Turtles = Turtles;
}
// get request to /turtles
@GetMapping("/turtles")
public List<Turtle> index(){
return Turtles.findAll();
}
}
Show
- get request to /turtles/:id to get a particular turtle
// get request to /turtles/:id
@GetMapping("/turtles/{id}")
public Optional<Turtle> show(@PathVariable Integer id){
return Turtles.findById(id);
}
Create
- post request to /turtles to create a turtle
@PostMapping("/turtles")
public List<Turtle> create(@RequestBody Turtle newTurtle){
Turtles.save(newTurtle); // Create the New Turtle
return Turtles.findAll();
}
Update
@PutMapping("/turtles/{id}")
public List<Turtle> update(@RequestBody Turtle fixTurtle, @PathVariable Integer id){
// Find turtle by it's then use map to update it
Turtles.findById(id).map(turtle -> {
turtle.setName(fixTurtle.getName());
turtle.setAge(fixTurtle.getAge());
Turtles.save(turtle);
return turtle;
});
// return all turtles
return Turtles.findAll();
}
Destroy
@DeleteMapping("/turtles/{id}")
public List<Turtle> destroy(@PathVariable Integer id){
Turtles.deleteById(id);
return Turtles.findAll();
}