Spring Boot makes it easy to create production-grade Spring applications that require minimal configuration. It provides tools to generate a single jar file containing an embedded web server so applications can be run with no external dependencies. The document discusses setting up a Spring Boot project with MySQL database integration using JPA to store and retrieve objects. It demonstrates creating a basic RESTful service to add and fetch items from the database with minimal code.
2. Why Spring Boot?
✦It’s popular & modern
✦It’s easy to use - practically like building a
command line app
✦Trivial to install
✦Provides integration to web services & Database
✦It’s still Java
✦It has integration to all major IDE’s
3. IDE Support
✦NetBeans - http://plugins.netbeans.org/plugin/
67888/nb-springboot
✦IntelliJ - https://www.jetbrains.com/help/idea/
2016.3/creating-spring-boot-projects.html
✦Eclipse - https://spring.io/tools/sts/all
4. So what is it?
Spring Boot makes it easy to create stand-alone,
production-grade Spring based Applications that
you can "just run". We take an opinionated view of
the Spring platform and third-party libraries so you
can get started with minimum fuss. Most Spring
Boot applications need very little Spring
configuration.
“
5. So what is it?
✦A set of tools that generate a single jar web app
✦Tomcat is bundled right in your fat jar
✦Literally just write a simple single class code
✦Deploy one jar to your server
6. MySQL
✦We will go with MySQL for storage
✦It’s easy to map it to JPA objects in Spring Boot
✦I chose it mostly for convenience as it had better
installers than MariaDB for Mac
✦You can use MariaDB as it should be compatible
✦MySQL is familiar, simple, performant & powerful
7. Why not NoSQL?
✦NoSQL is easier and more scalable on some
fronts but harder on others
✦Data migration to/from NoSQL is really difficult
✦Reporting and query 3rd party tools aren’t as easy
✦Moving to NoSQL is easier than moving out of
NoSQL architecture
✦E.g. when Google needed performance for
search they used NoSQL when they needed
reliability for adsense they used SQL
9. Setup MySQL
✦Setup and configure MySQL create a database
✦Once installed launch the database daemon
process
✦Login to MySQL using a command similar to this:
/usr/local/mysql/bin/mysql -h localhost -u root -p
10. Configure Database
✦We’ll do the initial work in the test database
✦To create it we will need to issue:
CREATE DATABASE test;
✦Notice the db might require you to set your
password the first time around
UPDATE mysql.user SET
Password=PASSWORD('your_new_password') WHERE User='root';
18. New Project
Selections
Make sure to pick the
following: Web, Websocket,
Jersey, JPA & MySQL.
There are many other
interesting options but I want
to keep things simple
22. The Main App
✦The main app of bootstrap doesn’t do much:
package com.codename1.testapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestAppApplication {
public static void main(String[] args) {
SpringApplication.run(TestAppApplication.class, args);
}
}
24. JPA Storage
✦Lets store some elements into MySQL
✦We’ll use JPA (Hibernate)
✦JPA allows us to map objects to database tables
and mostly hides SQL
✦I won’t go into the working/philosophy behind it
and use it in a relatively simplistic way
25. import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Item {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private boolean marked;
private boolean deleted;
private String owner;
public Item() {}
public Item(Long id, String name, boolean marked, boolean deleted, String owner) {
…
}
}
Item
26. import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Item {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private boolean marked;
private boolean deleted;
private String owner;
public Item() {}
public Item(Long id, String name, boolean marked, boolean deleted, String owner) {
…
}
}
Item
Trimmed Code
I trimmed a lot of boilerplate
code, the method body,
getters/setters to all the
elements
28. package com.codename1.testapp;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface ItemRepository extends CrudRepository<Item, Long> {
List<Item> findByOwner(String owner);
}
ItemRepository
CRUD
Spring injects the
implementation of this interface.
It includes API’s for Create,
Read, Update & Delete for the
entity.
29. @Controller
@RequestMapping("/item")
public class ItemService {
@Autowired
private ItemRepository repo;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Item[] go(@RequestParam(value="id", required=false) Long id,
@RequestParam(value="owner", required=false) String owner) {
if(id != null) {
Item c = repo.findOne(id);
return new Item[] {c};
}
if(owner != null) {
List<Item> c = repo.findByOwner(owner);
Item[] i = new Item[c.size()];
return c.toArray(i);
}
return new Item[0];
}
@RequestMapping(method=RequestMethod.PUT)
public @ResponseBody Item add(@RequestBody(required=true) Item i) {
i = repo.save(i);
return i;
}
}
ItemService
30. @Controller
@RequestMapping("/item")
public class ItemService {
@Autowired
private ItemRepository repo;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Item[] go(@RequestParam(value="id", required=false) Long id,
@RequestParam(value="owner", required=false) String owner) {
if(id != null) {
Item c = repo.findOne(id);
return new Item[] {c};
}
if(owner != null) {
List<Item> c = repo.findByOwner(owner);
Item[] i = new Item[c.size()];
return c.toArray(i);
}
return new Item[0];
}
@RequestMapping(method=RequestMethod.PUT)
public @ResponseBody Item add(@RequestBody(required=true) Item i) {
i = repo.save(i);
return i;
}
}
ItemService
Injection
This value is injected implicitly
by Spring
31. @Controller
@RequestMapping("/item")
public class ItemService {
@Autowired
private ItemRepository repo;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Item[] go(@RequestParam(value="id", required=false) Long id,
@RequestParam(value="owner", required=false) String owner) {
if(id != null) {
Item c = repo.findOne(id);
return new Item[] {c};
}
if(owner != null) {
List<Item> c = repo.findByOwner(owner);
Item[] i = new Item[c.size()];
return c.toArray(i);
}
return new Item[0];
}
@RequestMapping(method=RequestMethod.PUT)
public @ResponseBody Item add(@RequestBody(required=true) Item i) {
i = repo.save(i);
return i;
}
}
ItemService
32. @Controller
@RequestMapping("/item")
public class ItemService {
@Autowired
private ItemRepository repo;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Item[] go(@RequestParam(value="id", required=false) Long id,
@RequestParam(value="owner", required=false) String owner) {
if(id != null) {
Item c = repo.findOne(id);
return new Item[] {c};
}
if(owner != null) {
List<Item> c = repo.findByOwner(owner);
Item[] i = new Item[c.size()];
return c.toArray(i);
}
return new Item[0];
}
@RequestMapping(method=RequestMethod.PUT)
public @ResponseBody Item add(@RequestBody(required=true) Item i) {
i = repo.save(i);
return i;
}
}
ItemService
Bad Design
I’m returning the Item object
which is an Entity & an internal
representation of the database.
This is bad design as I might
expose internal state!
I’m doing it here as a shortcut
33. Add an Item
✦We can add an item using this curl request:
curl -H "Content-Type: application/json" -X PUT
-d '{"name":"Item Name", "marked":false, "deleted":false, "owner":"Shai"}'
http://localhost:8080/item
✦The output is:
{"id":1,"name":"Item Name","marked":false,"deleted":false,"owner":"Shai"}
34. Fetch My Items
✦We can fetch my items using:
curl http://localhost:8080/item?owner=Shai
✦The output is:
[{"id":1,"name":"Item Name","marked":false,"deleted":false,"owner":"Shai"},
{"id":2,"name":"Item Name","marked":false,"deleted":false,"owner":"Shai"},
{"id":3,"name":"Item Name","marked":false,"deleted":false,"owner":"Shai"}]
35. What did we learn?
✦Why we chose Spring Boot and why it’s cool
✦How to set it up with MySQL
✦Implementing a restful service that’s moderately
useful with almost no code…