Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Spring Boot 2.0 Cookbook

You're reading from   Spring Boot 2.0 Cookbook Configure, test, extend, deploy, and monitor your Spring Boot application both outside and inside the cloud

Arrow left icon
Product type Paperback
Published in Feb 2018
Publisher
ISBN-13 9781787129825
Length 286 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Alex Antonov Alex Antonov
Author Profile Icon Alex Antonov
Alex Antonov
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Getting Started with Spring Boot 2. Configuring Web Applications FREE CHAPTER 3. Web Framework Behavior Tuning 4. Writing Custom Spring Boot Starters 5. Application Testing 6. Application Packaging and Deployment 7. Health Monitoring and Data Visualization 8. Spring Boot DevTools 9. Spring Cloud 10. Other Books You May Enjoy

Setting up a data repository service

Connecting to a database and then executing good old SQL, though simplistic and straightforward, is not the most convenient way to operate on the data, map it in a set of domain objects, and manipulate the relational content. This is why multiple frameworks emerged to aid you with mapping the data from tables to objects, better known as object-relational mapping (ORM). The most notable example of such a framework is Hibernate.

In the previous example, we covered how to set up a connection to a database and configure the settings for the username and password, and we also discussed which driver to use, and so on. In this recipe, we will enhance our application by adding a few entity objects that define the structure of the data in the database and a CrudRepository interface to access the data.

As our application is a book-tracking catalogue, the obvious domain objects would be Book, Author, Reviewers, and Publisher.

How to do it...

  1. Create a new package folder named entity under the src/main/java/com/example/bookpub directory from the root of our project.
  2. In this newly created package, create a new class named Book with the following content:
@Entity 
public class Book { 
  @Id 
  @GeneratedValue 
  private Long id; 
  private String isbn; 
  private String title; 
  private String description; 
 
  @ManyToOne 
  private Author author; 
  @ManyToOne 
  private Publisher publisher; 
 
  @ManyToMany 
  private List<Reviewers> reviewers; 
 
  protected Book() {} 
 
  public Book(String isbn, String title, Author author, 
Publisher publisher) { this.isbn = isbn; this.title = title; this.author = author; this.publisher = publisher; } //Skipping getters and setters to save space, but we do need them }
  1. As any book should have an author and a publisher, and ideally some reviewers, we need to create these entity objects as well. Let's start by creating an Author entity class, under the same directory as our Book, as follows:
@Entity 
public class Author { 
  @Id 
  @GeneratedValue 
  private Long id; 
  private String firstName; 
  private String lastName; 
  @OneToMany(mappedBy = "author") 
  private List<Book> books; 
 
  protected Author() {} 
 
  public Author(String firstName, String lastName) {...} 
    //Skipping implementation to save space, but we do need 
it all }
  1. Similarly, we will create the Publisher and Reviewer classes, as shown in the following code:
@Entity 
public class Publisher { 
  @Id 
  @GeneratedValue 
  private Long id; 
  private String name; 
  @OneToMany(mappedBy = "publisher") 
  private List<Book> books; 
 
  protected Publisher() {} 
 
  public Publisher(String name) {...} 
} 
 
@Entity 
public class Reviewer { 
  @Id 
  @GeneratedValue 
  private Long id; 
  private String firstName; 
  private String lastName; 
 
  protected Reviewer() {} 
 
  public Reviewer(String firstName, String lastName) 
{...}
}
  1. Now we will create our BookRepository interface by extending Spring's CrudRepository interface under the src/main/java/com/example/bookpub/repository package, as follows:
@Repository 
public interface BookRepository 
extends CrudRepository<Book, Long> { public Book findBookByIsbn(String isbn); }
  1. Finally, let's modify our StartupRunner class in order to print the number of books in our collection, instead of some random datasource string, by autowiring a newly created BookRepository and printing the result of a .count() call to the log, as follows:
public class StartupRunner implements CommandLineRunner { 
  @Autowired private BookRepository bookRepository; 
 
  public void run(String... args) throws Exception { 
    logger.info("Number of books: " + 
bookRepository.count()); } }

How it works...

As you have probably noticed, we didn't write a single line of SQL, or even mention anything about database connections, building queries, or things like that. The only hint about the fact that we are dealing with the database-backed data in our code is the presence of class and field annotations: @Entity, @Repository, @Id, @GeneratedValue, and @ManyToOne, along with @ManyToMany and @OneToMany. These annotations, which are a part of the JPA, along with the extension of the CrudRepository interface, are our ways of communicating with Spring about the need to map our objects to the appropriate tables and fields in the database and provide us with the programmatic ability to interact with this data.

Let's go through the following annotations:

  • @Entity indicates that the annotated class should be mapped to a database table. The name of the table will be derived from the name of the class, but it can be configured, if needed. It is important to note that every entity class should have a default protected constructor, which is needed for automated instantiation and Hibernate interactions.
  • @Repository indicates that the interface is intended to provide you with the access and manipulation of data for a database. It also serves as an indication to Spring during the component scan that this instance should be created as a bean that will be available for use and injection into other beans in the application.
  • The CrudRepository interface defines the basic common methods to read, create, update, and delete data from a data repository. The extra methods that we will define in our BookRepository extension, public Book findBookByIsbn(String isbn), indicate that Spring JPA should map the call to this method to a SQL query selecting a book by its ISBN field. This is a convention-named mapping that translates the method name into a SQL query. It can be a very powerful ally, allowing you to build queries, such as findByNameIgnoringCase(String name) and others.
  • The @Id and @GeneratedValue annotations provide you with an indication that an annotated field should be mapped to a primary key column in the database and that the value for this field should be generated, instead of being explicitly entered.
  • The @ManyToOne and @ManyToMany annotations define the relational field associations that refer to the data stored in the other tables. In our case, multiple books belong to one author, and many reviewers review multiple books.
  • The mappedBy attribute in the @OneToMay annotation defines a reverse association mapping. It indicates to Hibernate that the mapping source of truth is defined in the Book class, in the author or publisher fields.
For more information about all the vast capabilities of Spring Data, visit http://docs.spring.io/spring-data/data-commons/docs/current/reference/html/.
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime