post-image

Hướng dẫn gọi Stored Procedure trong Spring Boot

JDBC & Hibernate

Stored procedure là một khái niệm khá phổ biến trong MySQL và các hệ cơ sở dữ liệu khác. Nó giúp giảm thời gian giao tiếp giữa các ứng dụng với MySQL. Vậy làm thế nào để chúng ta có thể gọi được nó trong Spring Boot. Cùng tìm hiểu ở bài viết này nhé.

Cài đặt thư viện

Mọi người tạo một ứng dụng Spring Boot ở trong IntelIJ hoặc trên https://start.spring.io/


implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

Cấu hình file application.properties

Chúng ta truy cập vào file application.properties và cấu hình đường dẫn tới cơ sở dữ liệu và cấu hình Hibernate như sau:

server.port=${port:8080}
#Database
spring.datasource.url=jdbc:mysql://localhost:3306/demo-stored-procedure
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#Hibernate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.id.new_generator_mappings = true
spring.jpa.properties.hibernate.show.sql = true
spring.jpa.properties.hibernate.format_sql = true
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.hb2dll.auto = update
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Chuẩn bị

Model

Tạo model Employee với các thuộc tính như sau:

package com.example.demo.model;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name = "employees")
@Data
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;

    private String lastName;
    
    private String address;
}

Tạo Stored Procedure

Chúng ta sẽ cùng tạo procedure get_all_employees đơn giản như sau:

DELIMITER $$
CREATE PROCEDURE get_all_employee()
BEGIN
    SELECT * FROM employees;
end

Repository

Tạo interface EmployeeRepository như sau:

package com.example.demo.repository;

import com.example.demo.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    @Query(value = "CALL `demo-stored-procedure`.get_all_employee();", nativeQuery = true)
    List<Employee> getAllEmployees();
}

Ở đây chúng ta sử dụng @Query với nativeQuery bằng true để gọi câu lệnh Call Procedure của MySQL.

Service

Chúng ta một interface GeneralService chứa các phương thức CRUD để dùng chung.

IGeneralService.java

package com.example.demo.service;

import java.util.Optional;

public interface IGeneralService<T> {
    Iterable<T> findAll();

    Optional<T> findById(Long id);

    T save(T t);

    void remove(Long id);
}

IEmployeeService

package com.example.demo.service;

import com.example.demo.model.Employee;

import java.util.List;

public interface IEmployeeService extends IGeneralService<Employee> {
    List<Employee> getAllEmployees();
}

EmployeeService.java

package com.example.demo.service;

import com.example.demo.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class EmployeeService implements IEmployeeService {
    @Autowired
    private IEmployeeService employeeService;

    @Override
    public List<Employee> getAllEmployees() {
        return employeeService.getAllEmployees();
    }

    @Override
    public Iterable<Employee> findAll() {
        return employeeService.findAll();
    }

    @Override
    public Optional<Employee> findById(Long id) {
        return employeeService.findById(id);
    }

    @Override
    public Employee save(Employee employee) {
        return employeeService.save(employee);
    }

    @Override
    public void remove(Long id) {
        employeeService.remove(id);
    }
}

 Cài đặt Controller để sử dụng Stored Procedure

Chúng ta sẽ tạo một class EmployeeController để test phương thức vừa tạo ở trên

EmployeeController.java

package com.example.demo.controller;

import com.example.demo.model.Employee;
import com.example.demo.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@CrossOrigin("*")
@RequestMapping("/employees")
public class EmployeeController {
    @Autowired
    private IEmployeeService employeeService;

    @GetMapping
    public ResponseEntity<List<Employee>> getAllEmployee() {
        return new ResponseEntity<>(employeeService.getAllEmployees(), HttpStatus.OK);
    }
}

Test Stored Procedure bằng Postman

Các bạn vào postman và truy cập đường dẫn sau để kiểm tra kết quả: http://localhost:8080/employees

Stored Procedure

Kết luận

Ở bài viết này mình đã hướng dẫn mọi người cách gọi một stored procedure của MySQL trong Spring Boot. Mọi người có thể thử và làm thêm một vài Procedure khác để hiểu rõ hơn nhé ^^

Leave a Reply

Your email address will not be published. Required fields are marked *