This post shows how to use a MySQL database in a Spring Boot web application, using less code and configurations as possible, with the aim to take full advantage from Spring Boot.
Spring Data JPA and Hibernate (as JPA implementation) will be used to implement the data access layer.
Dependencies
Make sure you have the following dependencies in the pom.xml
file:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
See here an example of a whole pom.xml
.
Properties file
Put in the application.properties
file pretty much all the configurations:
src/main/resources/application.properties
# DataSource settings: set here your own configurations for the database
# connection. In this example we have "netgloo_blog" as database name and
# "root" as username and password.
spring.datasource.url = jdbc:mysql://localhost:8889/netgloo_blog
spring.datasource.username = root
spring.datasource.password = root
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
No xml or java config classes are needed.
Using the hibernate configuration ddl-auto = update
the database schema will be automatically created (and updated), creating tables and columns, accordingly to java entities found in the project.
See here for other hibernate specific configurations.
Create an entity
Create an entity class representing a table in your db.
In this example we create an entity User
composed by three fields: id
, email
and name
.
An object of this class will be an entry in the users
table in your MySQL database.
src/main/java/netgloo/models/User.java
package netgloo.models;
// Imports ...
@Entity
@Table(name = "users")
public class User {
// Entity's fields (private)
// An autogenerated id (unique for each user in the db)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
// The user's email
@NotNull
private String email;
// The user's name
@NotNull
private String name;
// Public methods
public User() { }
public User(long id) {
this.id = id;
}
public User(String email, String name) {
this.email = email;
this.name = name;
}
// Getter and setter methods
// ...
}
The Entity
annotation mark this class as a JPA entity. The Table
annotation specifies the db table’s name (would be “User” as default).
The Data Access Object
A DAO (aka Repository) is needed to access the entity database’s table, with methods like save, delete, update, etc.
With Spring Data JPA a DAO for your entity is simply created by extending the CrudRepository
interface provided by Spring. The following methods are some of the ones available from such interface: save
, delete
, deleteAll
, findOne
and findAll
.
The magic is that such methods must not be implemented, and moreover it is possible to create new query methods working only by their signature definition!
Here there is the Dao class UserDao
for our entity User
:
src/main/java/netgloo/models/UserDao.java
package netgloo.models;
// Imports ...
@Transactional
public interface UserDao extends CrudRepository<User, Long> {
/**
* This method will find an User instance in the database by its email.
* Note that this method is not implemented and its working code will be
* automagically generated from its signature by Spring Data JPA.
*/
public User findByEmail(String email);
}
See here for more details on how to create query from method names.
A controller for testing
That’s all! The connection with the database is done. Now we can test it.
In the same way as in some similar previous post (one and two) we create a controller class named UserController to test interactions with the MySQL database using the UserDao class.
src/main/java/netgloo/controllers/UserController.java
package netgloo.controllers;
// Imports ...
@Controller
public class UserController {
/**
* GET /create --> Create a new user and save it in the database.
*/
@RequestMapping("/create")
@ResponseBody
public String create(String email, String name) {
User user = null;
try {
user = new User(email, name);
userDao.save(user);
}
catch (Exception ex) {
return "Error creating the user: " + ex.toString();
}
return "User succesfully created! (id = " + user.getId() + ")";
}
/**
* GET /delete --> Delete the user having the passed id.
*/
@RequestMapping("/delete")
@ResponseBody
public String delete(long id) {
try {
User user = new User(id);
userDao.delete(user);
}
catch (Exception ex) {
return "Error deleting the user:" + ex.toString();
}
return "User succesfully deleted!";
}
/**
* GET /get-by-email --> Return the id for the user having the passed
* email.
*/
@RequestMapping("/get-by-email")
@ResponseBody
public String getByEmail(String email) {
String userId;
try {
User user = userDao.findByEmail(email);
userId = String.valueOf(user.getId());
}
catch (Exception ex) {
return "User not found";
}
return "The user id is: " + userId;
}
/**
* GET /update --> Update the email and the name for the user in the
* database having the passed id.
*/
@RequestMapping("/update")
@ResponseBody
public String updateUser(long id, String email, String name) {
try {
User user = userDao.findOne(id);
user.setEmail(email);
user.setName(name);
userDao.save(user);
}
catch (Exception ex) {
return "Error updating the user: " + ex.toString();
}
return "User succesfully updated!";
}
// Private fields
@Autowired
private UserDao userDao;
}
Test the controller launching the Spring Boot web application and using these urls:
- /create?email=[email]&name=[name]: create a new user with an auto-generated id and email and name as passed values.
- /delete?id=[id]: delete the user with the passed id.
- /get-by-email?email=[email]: retrieve the id for the user with the given email address.
- /update?id=[id]&email=[email]&name=[name]: update the email and the name for the user indentified by the given id.
Get the whole code
You can get the whole code used in this post from our github repository here:
https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-mysql-springdatajpa-hibernate
References
- http://spring.io/guides/gs/accessing-data-jpa/
- http://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html
- http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html
- http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-two-crud/
- http://www.luckyryan.com/2013/02/20/spring-mvc-with-basic-persistence-spring-data-jpa-hibernate/
- https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-data-jpa