Tương tác Spring Boot, JPA và cơ sở dữ liệu H2
1. Mục tiêu của bài học
H2 là một cơ sở dữ liệu quan hệ (Relational database), mã nguồn mở, gọn nhẹ, được viết bằng ngôn ngữ Java. Bộ cài đặt H2 có dung lượng rất nhỏ, chỉ khoảng 8MB.
Một trong các tính năng thú vị của H2 là bạn có thể tạo ra một cơ sở dữ liệu trên bộ nhớ (In Memory Database) thay vì được lưu trữ trên ổ cứng máy tính. Điều này làm cho tốc độ truy vấn và thao tác với dữ liệu rất nhanh. Tuy nhiên nếu bạn lựa chọn tính năng "In Memory Database" các dữ liệu chỉ tồn tại khi ứng dụng hoạt động, khi ứng dụng bị tắt (shutdown), các dữ liệu cũng sẽ bị xóa khỏi bộ nhớ.
H2 cung cấp cho bạn một công cụ quản trị có tên H2 Console, và bạn có làm việc với nó thông qua trình duyệt.
Trong bài học này tôi sẽ hướng dẫn bạn tạo một dự án Spring Boot tương tác với cơ sở dữ liệu H2(In Memory Database), cấu hình để sử dụng công cụ quản trị H2 Console.
Cũng không có nhiều khác biệt nếu bạn muốn kết nối vào cơ sở dữ liệu H2 cài đặt trên máy tính (Xem thêm phụ lục phía cuối bài viết này).
2. Tạo dự án Spring Boot
Trên Eclipse tạo dự án Spring Boot:
OK, project đã được tạo ra.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SpringBootJpaH2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootJpaH2</name>
<description>Spring Boot + Jpa + H2</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringBootJpaH2Application.java
package org.o7planning.springbooth2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJpaH2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaH2Application.class, args);
}
}
3. Entity Class, DAO, DataInit, Controller
Person.java
package org.o7planning.springbooth2.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "PERSON")
public class Person {
@Id
@GeneratedValue
@Column(name = "Id", nullable = false)
private Long id;
@Column(name = "Full_Name", length = 64, nullable = false)
private String fullName;
@Temporal(TemporalType.DATE)
@Column(name = "Date_Of_Birth", nullable = false)
private Date dateOfBirth;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
}
PersonDAO là một interface mở rộng (extends) từ CrudRepository<Person, Long>. Spring Data JPA sẽ tự tạo cho bạn một lớp thực hiện (implements) interface này tại thời điểm khởi động ứng dụng.
PersonDAO.java
package org.o7planning.springbooth2.dao;
import java.util.Date;
import java.util.List;
import org.o7planning.springbooth2.entity.Person;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonDAO extends CrudRepository<Person, Long> {
public List<Person> findByFullNameLike(String name);
public List<Person> findByDateOfBirthGreaterThan(Date date);
}
Lớp DataInit thực hiện interface ApplicationRunner, nó sẽ tự động được chạy tại thời điểm ứng dụng đang khởi động. Trong lớp này chúng ta sẽ trèn một vài bản ghi (record) vào bảng PERSON.
DataInit.java
package org.o7planning.springbooth2.init;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.o7planning.springbooth2.dao.PersonDAO;
import org.o7planning.springbooth2.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class DataInit implements ApplicationRunner {
private PersonDAO personDAO;
private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
@Autowired
public DataInit(PersonDAO personDAO) {
this.personDAO = personDAO;
}
@Override
public void run(ApplicationArguments args) throws Exception {
long count = personDAO.count();
if (count == 0) {
Person p1 = new Person();
p1.setFullName("John");
Date d1 = df.parse("1980-12-20");
p1.setDateOfBirth(d1);
//
Person p2 = new Person();
p2.setFullName("Smith");
Date d2 = df.parse("1985-11-11");
p2.setDateOfBirth(d2);
personDAO.save(p1);
personDAO.save(p2);
}
}
}
MainController.java
package org.o7planning.springbooth2.controller;
import org.o7planning.springbooth2.dao.PersonDAO;
import org.o7planning.springbooth2.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@Autowired
private PersonDAO personDAO;
@ResponseBody
@RequestMapping("/")
public String index() {
Iterable<Person> all = personDAO.findAll();
StringBuilder sb = new StringBuilder();
all.forEach(p -> sb.append(p.getFullName() + "<br>"));
return sb.toString();
}
}
4. Cấu hình Spring Boot & H2
Trong ví dụ này tôi sẽ cấu hình Spring Boot để sử dụng H2 như là một database trong bộ nhớ (In memory Database), điều đó có nghĩa là chúng ta không cần cài đặt cơ sở dữ liệu H2, nó sẽ tự động được tạo ra và lưu trữ trên bộ nhớ máy tính.
Trong một trường hợp khác, nếu bạn đã cài đặt sẵn một cơ sở dữ liệu H2 trên máy tính của bạn, và muốn tương tác ứng dụng Spring Boot với cơ sở dữ liệu này, bạn có thể xem thêm phụ lục ở phía cuối bài viết này.
application.properties
# To See H2 Console in Browser:
# http://localhost:8080/h2-console
# Enabling H2 Console
spring.h2.console.enabled=true
# ===============================
# DB
# ===============================
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# ===============================
# JPA / HIBERNATE
# ===============================
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
Cấu hình này nói với Spring hãy khởi động công cụ quản trị cơ sở dữ liệu H2. Và bạn có thể truy cập vào công cụ này trên trình duyệt:
spring.datasource.url=jdbc:h2:mem:testdb
Cấu hình này nói với Spring rằng bạn muốn sử dụng cơ sở dữ liệu H2 trong bộ nhớ (In Memory Database).
spring.jpa.hibernate.ddl-auto=update
Cấu hình này nói với Spring tạo (Hoặc cập nhập) cấu trúc của các bảng theo cấu trúc của các lớp Entity. Như vậy bảng PERSON sẽ tự động được tạo ra theo cấu trúc của lớp Person.
5. Chạy ứng dụng
Trên Eclipse chạy ứng dụng của bạn:
Lúc này H2 Console cũng được khởi động cùng ứng dụng, và bạn có thể truy cập vào công cụ quản trị này:
Bảng PERSON đã được tự động tạo ra dựa trên cấu trúc của lớp Person.
Truy vấn (query) bảng PERSON:
6. Phụ lục H2
Với trường hợp bạn sử dụng H2 (Server):
application.properties (H2 Server)
# To See H2 Console in Browser:
# http://localhost:8080/h2-console
# Enabling H2 Console
spring.h2.console.enabled=true
# ===============================
# DB
# ===============================
spring.datasource.url=jdbc:h2:tcp://localhost/~/testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# ===============================
# JPA / HIBERNATE
# ===============================
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
Các hướng dẫn Spring Boot
- Cài đặt Spring Tool Suite cho Eclipse
- Hướng dẫn lập trình Spring cho người mới bắt đầu
- Hướng dẫn lập trình Spring Boot cho người mới bắt đầu
- Các thuộc tính thông dụng của Spring Boot
- Hướng dẫn sử dụng Spring Boot và Thymeleaf
- Hướng dẫn sử dụng Spring Boot và FreeMarker
- Hướng dẫn sử dụng Spring Boot và Groovy
- Hướng dẫn sử dụng Spring Boot và Mustache
- Hướng dẫn sử dụng Spring Boot và JSP
- Hướng dẫn sử dụng Spring Boot, Apache Tiles, JSP
- Sử dụng Logging trong Spring Boot
- Giám sát ứng dụng với Spring Boot Actuator
- Tạo ứng dụng web đa ngôn ngữ với Spring Boot
- Sử dụng nhiều ViewResolver trong Spring Boot
- Sử dụng Twitter Bootstrap trong Spring Boot
- Hướng dẫn và ví dụ Spring Boot Interceptor
- Hướng dẫn sử dụng Spring Boot, Spring JDBC và Spring Transaction
- Hướng dẫn và ví dụ Spring JDBC
- Hướng dẫn sử dụng Spring Boot, JPA và Spring Transaction
- Hướng dẫn sử dụng Spring Boot và Spring Data JPA
- Hướng dẫn sử dụng Spring Boot, Hibernate và Spring Transaction
- Tương tác Spring Boot, JPA và cơ sở dữ liệu H2
- Hướng dẫn sử dụng Spring Boot và MongoDB
- Sử dụng nhiều DataSource với Spring Boot và JPA
- Sử dụng nhiều DataSource với Spring Boot và RoutingDataSource
- Tạo ứng dụng Login với Spring Boot, Spring Security, Spring JDBC
- Tạo ứng dụng Login với Spring Boot, Spring Security, JPA
- Tạo ứng dụng đăng ký tài khoản với Spring Boot, Spring Form Validation
- Ví dụ OAuth2 Social Login trong Spring Boot
- Chạy các nhiệm vụ nền theo lịch trình trong Spring
- Ví dụ CRUD Restful Web Service với Spring Boot
- Ví dụ Spring Boot Restful Client với RestTemplate
- Ví dụ CRUD với Spring Boot, REST và AngularJS
- Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication
- Bảo mật Spring Boot RESTful Service sử dụng Auth0 JWT
- Ví dụ Upload file với Spring Boot
- Ví dụ Download file với Spring Boot
- Ví dụ Upload file với Spring Boot và jQuery Ajax
- Ví dụ Upload file với Spring Boot và AngularJS
- Tạo ứng dụng Web bán hàng với Spring Boot, Hibernate
- Hướng dẫn và ví dụ Spring Email
- Tạo ứng dụng Chat đơn giản với Spring Boot và Websocket
- Triển khai ứng dụng Spring Boot trên Tomcat Server
- Triển khai ứng dụng Spring Boot trên Oracle WebLogic Server
- Cài đặt chứng chỉ SSL miễn phí Let's Encrypt cho Spring Boot
- Cấu hình Spring Boot chuyển hướng HTTP sang HTTPS
- Tìm nạp dữ liệu với Spring Data JPA DTO Projections
Show More