Ejecución de Store Procedures en Spring Data

Clase 24 de 25Curso de Java Spring Data JPA: Bases de Datos

Resumen

¿Cómo utilizar store procedures en Spring Data?

En el desarrollo de aplicaciones, recurrir a los store procedures es una práctica común para manejar operaciones complejas en bases de datos, garantizando mantenimiento y eficiencia. Spring Data, un proyecto del ecosistema Spring, nos facilita esta tarea a través de la anotación @Procedure, permitiendo declarar y ejecutar store procedures de una manera sencilla. En esta guía aprenderás a implementar funciones que añaden valor a tus aplicaciones mediante un ejemplo práctico.

¿Qué es un store procedure y cómo lo manejamos?

Un store procedure es un bloque de código almacenado y reutilizable que permite realizar operaciones complejas en la base de datos, agrupando múltiples instrucciones SQL. Esto puede incluir selecciones, inserciones, o control de transacciones, incrementando tanto la eficiencia como la seguridad de las operaciones. En nuestro caso, utilizamos un store procedure que brinda una promoción del 20% de descuento al ordenar una pizza aleatoria.

¿Cómo implementar un store procedure en Spring Data?

Paso 1: Definir el store procedure en la base de datos

En este ejemplo, comenzamos definiendo nuestro store procedure en MySQL, nombrando el procedimiento TakeRandomPizzaOrder. Este procedimiento:

  • Recibe como parámetros: la identificación del usuario y el método de envío.
  • Gira dentro de una transacción para controlar errores y asegurar el rollback en casos de fallo.
  • Selecciona una pizza de manera aleatoria, calcula el precio con un 20% de descuento y registra la orden en la base de datos.

Código del store procedure

DELIMITER //

CREATE PROCEDURE TakeRandomPizzaOrder(
    IN userId INT, 
    IN method VARCHAR(255), 
    OUT orderTaken BOOLEAN
)
BEGIN
    DECLARE pId INT;
    DECLARE price DECIMAL(8,2);
    DECLARE discountPrice DECIMAL(8,2);
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        SET orderTaken = FALSE;
        ROLLBACK;
    END;

    START TRANSACTION;

    SELECT id, price INTO pId, price
    FROM pizza
    WHERE available = TRUE
    ORDER BY RAND() LIMIT 1;

    SET discountPrice = price - (price * 0.2);

    INSERT INTO pizza_order (customer_id, date, discounted_price, method, notes)
    VALUES (userId, NOW(), discountPrice, method, '20% discount for random order');

    SET orderTaken = TRUE;

    COMMIT;
END //

DELIMITER ;

Paso 2: Implementación en el repositorio de Spring Data

Declara el store procedure en tu repositorio utilizando la anotación @Procedure. Define los parámetros de entrada y el parámetro de salida que recibirá su valor booleano.

Código en Java en el repositorio

public interface OrderRepository extends CrudRepository<Order, Integer> {

    @Procedure(name = "TakeRandomPizzaOrder")
    boolean saveRandomOrder(@Param("id_customer") String idCustomer,
                            @Param("method") String method);
}

¿Cómo crear un servicio y controlador que utilicen el store procedure?

Paso 3: Crear el servicio

Utiliza la anotación @Transactional para manejar de manera adecuada las transacciones del store procedure en tu método saveRandomOrder.

Código del servicio

@Service
public class OrderService {

    private final OrderRepository orderRepository;

    @Autowired
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @Transactional
    public boolean saveRandomOrder(RandomOrderDTO dto) {
        return orderRepository.saveRandomOrder(dto.getIdCustomer(), dto.getMethod());
    }
}

Paso 4: Configurar el controlador

Desarrolla el controlador para gestionar las peticiones HTTP. Esto permitirá recibir peticiones POST y ejecutar el store procedure en consecuencia.

Código del controlador

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/order/random")
    public ResponseEntity<Boolean> randomOrder(@RequestBody RandomOrderDTO dto) {
        boolean result = orderService.saveRandomOrder(dto);
        return ResponseEntity.ok(result);
    }
}

¿Qué aspectos debemos verificar antes de ejecutar el Store Procedure?

  • Asegúrate de que el store procedure esté correctamente definido en tu base de datos antes de su ejecución.
  • Utiliza herramientas como Postman para enviar las solicitudes post y verificar su correcto funcionamiento.
  • Con la anotación @Transactional, gestiona el compromiso de los datos evitando inconsistencias.

Con estos pasos, estarás listo para integrar store procedures eficazmente en tus aplicaciones desarrolladas con Spring Data. ¡Ah! Y dale la bienvenida al 20% de descuento para tus clientes más aventureros.