MyBatis-Plus ofrece una funcionalidad de "Auto-Fill" que permite asignar valores automáticamente a campos específicos durante operaciones de inserción (INSERT) o actualización (UPDATE), sin necesidad de intervención manual en el código. Esta característica es especialmente útil para campos comunes como fechas de creación, fechas de modificación, o identificadores de usuarios creadores/modificadores, promoviendo la reutilización de código y la consistencia de datos.
Mecanismo de Auto-Fill
La magia detrás del Auto-Fill en MyBatis-Plus reside en su sistema de interceptores. Antes de que una sentencia SQL sea ejecutada, MyBatis-Plus intercepta la operación y, basándose en reglas predefinidas, asigna valores a los campos designados.
Pasos para Implementar el Auto-Fill
- Definir Campos en la Entidad: En tu clase de entidad (POJO), declara los campos que deseas que se auto-rellenen. Utiliza las anotaciones proporcionadas por MyBatis-Plus para marcarlos.
- Crear un Manejador de Metadatos: Desarrolla una clase que implemente la interfaz
MetaObjectHandler. En esta clase, definirás la lógica para la asignación de valores. - Configurar MyBatis-Plus: Registra tu manejador de metadatos en la configuración de MyBatis-Plus para que el framework pueda utilizarlo.
Ejemplo Práctico: Campos de Tiempo de Creación y Actualización
Consideremos una entidad Usuario con campos fechaCreacion y fechaActualizacion que queremos que se copmleten automáticamente.
1. Definición de la Entidad
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("usuarios")
public class Usuario implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
private Long id;
private String nombre;
private Integer edad;
private String correoElectronico;
@TableField(fill = FieldFill.INSERT) // Se rellena solo al insertar
private LocalDateTime fechaCreacion;
@TableField(fill = FieldFill.INSERT_UPDATE) // Se rellena al insertar y actualizar
private LocalDateTime fechaActualizacion;
}
Explicación:
@TableField(fill = FieldFill.INSERT): Indica que este campo se rellenará automáticamente cuando se ejecute una operación de inserción.@TableField(fill = FieldFill.INSERT_UPDATE): Indica que este campo se rellenará automáticamente tanto en insercionse como en actualizaciones.LocalDateTime: Se utiliza aquí como tipo de dato para las fechas y horas. Otras opciones válidas incluyenDateoInstant.
2. Implementación del Manejador de Metadatos
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Slf4j
@Component // Es crucial añadir esta anotación para que Spring lo gestione
public class ConfiguracionAutoRelleno implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("Iniciando relleno para inserción...");
// Versión 3.3.0+ recomienda estos métodos por ser más seguros
this.strictInsertFill(metaObject, "fechaCreacion", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "fechaActualizacion", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("Iniciando relleno para actualización...");
this.strictUpdateFill(metaObject, "fechaActualizacion", LocalDateTime.class, LocalDateTime.now());
}
}
Explicación:
- La clase
ConfiguracionAutoRellenoimplementaMetaObjectHandler. insertFill(MetaObject metaObject): Este método se ejecuta durante las operaciones de inserción. Aquí, asignamos la fecha y hora actual afechaCreacionyfechaActualizacion.updateFill(MetaObject metaObject): Se ejecuta durante las actualizaciones. Asignamos la fecha y hora actual afechaActualizacion.strictInsertFillystrictUpdateFill: Métodos introducidos en MyBatis-Plus 3.3.0 para un manejo más robusto y seguro, verificando la existencia del campo y su tipo, y evitando sobrescribir valores ya existentes.@Component: Asegura que esta clase sea gestionada por Spring, permitiendo a MyBatis-Plus descubrrila automáticamente.
3. Configuración de MyBatis-Plus
Generalmente, no se requiere una configuración explícita en los archivos application.yml o application.properties para habilitar el Auto-Fill. Siempre que tu clase manejadora (ConfiguracionAutoRelleno) esté anotada con @Component y sea escaneada por Spring, MyBatis-Plus la detectará y utilizará automáticamente. 🎉
Ejemplo de Uso
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class UsuarioMapperTest {
@Autowired
private UsuarioMapper usuarioMapper;
@Test
public void probarInsercion() {
Usuario usuario = new Usuario();
usuario.setNombre("UsuarioEjemplo");
usuario.setEdad(30);
usuario.setCorreoElectronico("ejemplo@dominio.com");
// No se asignan fechaCreacion ni fechaActualizacion manualmente
int filasAfectadas = usuarioMapper.insert(usuario);
System.out.println("Filas afectadas por la inserción: " + filasAfectadas);
System.out.println("ID del nuevo usuario: " + usuario.getId());
System.out.println("Fecha de creación asignada: " + usuario.getFechaCreacion());
System.out.println("Fecha de actualización asignada: " + usuario.getFechaActualizacion());
}
@Test
public void probarActualizacion() {
Usuario usuarioExistente = usuarioMapper.selectById(1L); // Asumiendo que el usuario con ID 1 existe
if (usuarioExistente != null) {
usuarioExistente.setNombre("UsuarioActualizado");
int filasAfectadas = usuarioMapper.updateById(usuarioExistente);
System.out.println("Filas afectadas por la actualización: " + filasAfectadas);
System.out.println("Fecha de actualización tras modificación: " + usuarioExistente.getFechaActualizacion());
}
}
}
Explicación:
- En
probarInsercion, creamos un objetoUsuarioy solo establecemos sus datos básicos. Al llamar ausuarioMapper.insert(usuario), MyBatis-Plus invocaráinsertFillen nuestro manejador para poblarfechaCreacionyfechaActualizacion. - En
probarActualizacion, modificamos el nombre de un usuario existente. Al ejecutarusuarioMapper.updateById(usuarioExistente), se llamará aupdateFillpara actualizarfechaActualizacion.
Consideraciones Importantes
- Asegúrate de que tu clase manejadora de metadatos esté registrada como un componente de Spring (
@Component). - El uso de
strictInsertFillystrictUpdateFillpreviene la sobrescritura accidental de valores existentes. - Ajusta el tipo de dato en el manejador si tus campos de fecha no son
LocalDateTime(p. ej.,Date,Instant). - Si tus nombres de campo difieren de
fechaCreacionyfechaActualizacion, actualiza las cadenas de texto correspondientes en el manejador. - Para campos de base de datos de tipo
TIMESTAMP, se recomienda usarLocalDateTimeoInstanten Java, con la configuración adecuada de tipo. - Si tu campo en la base de datos es de tipo
DATE, considera usarLocalDateen Java.
La funcionalidad de Auto-Fill de MyBatis-Plus simplifica significativamente el desarrollo al automatizar la gestión de campos como fechas de creación y actualización, garantizando la consistencia y reduciendo el código repetitivo.