En Mybatis, las relaciones de asociación entre tablas de bases de datos se configuran mediante archivos XML y clases Java, permitiendo mapear entidades relacionadas de forma eficiente.
Relación Uno a Muchos: Pedido y Detalles de Pedido
Para demostrar una relación uno a muchos, se utilizan tablas de ejemplo: una tabla de pedidos y otra de detalles de pedido. Se crean clases de representación (VO) para incluir las colecciones anidadas.
Clase de representación para Pedido (PedidoRep.java):
package com.ejemplo.modelo;
import java.util.ArrayList;
import java.util.List;
public class PedidoRep extends Pedido {
private List<DetallePedido> detalles = new ArrayList<>();
public List<DetallePedido> getDetalles() {
return detalles;
}
public void setDetalles(List<DetallePedido> detalles) {
this.detalles = detalles;
}
}
Clase de representación para Detalle de Pedido (DetallePedidoRep.java):
package com.ejemplo.modelo;
public class DetallePedidoRep extends DetallePedido {
private Pedido pedido;
public Pedido getPedido() {
return pedido;
}
public void setPedido(Pedido pedido) {
this.pedido = pedido;
}
}
Interfaz del mapper para Pedido (PedidoMapper.java):
package com.ejemplo.mapper;
import com.ejemplo.modelo.PedidoRep;
import org.apache.ibatis.annotations.Param;
public interface PedidoMapper {
PedidoRep obtenerPedidoConDetalles(@Param("idPedido") Integer idPedido);
}
Configuración XML para mapeo uno a muchos (PedidoMapper.xml):
<resultMap id="PedidoRepMap" type="com.ejemplo.modelo.PedidoRep">
<result property="idPedido" column="id_pedido"/>
<result property="numeroPedido" column="numero_pedido"/>
<collection property="detalles" ofType="com.ejemplo.modelo.DetallePedido">
<result property="idDetalle" column="id_detalle"/>
<result property="idProducto" column="id_producto"/>
<result property="cantidad" column="cantidad"/>
<result property="fkPedido" column="fk_pedido"/>
</collection>
</resultMap>
<select id="obtenerPedidoConDetalles" resultMap="PedidoRepMap" parameterType="java.lang.Integer">
SELECT p.id_pedido, p.numero_pedido, d.id_detalle, d.id_producto, d.cantidad, d.fk_pedido
FROM tabla_pedido p INNER JOIN tabla_detalle_pedido d ON p.id_pedido = d.fk_pedido
WHERE p.id_pedido = #{idPedido}
</select>
Para la relación muchos a uno, se invierte el enfoque. Interfaz del mapper para DetallePedido (DetallePedidoMapper.java):
package com.ejemplo.mapper;
import com.ejemplo.modelo.DetallePedidoRep;
import org.apache.ibatis.annotations.Param;
public interface DetallePedidoMapper {
DetallePedidoRep obtenerDetalleConPedido(@Param("idDetalle") Integer idDetalle);
}
Configuración XML para mapeo muchos a uno (DetallePedidoMapper.xml):
<resultMap id="DetallePedidoRepMap" type="com.ejemplo.modelo.DetallePedidoRep">
<result property="idDetalle" column="id_detalle"/>
<result property="idProducto" column="id_producto"/>
<result property="cantidad" column="cantidad"/>
<result property="fkPedido" column="fk_pedido"/>
<association property="pedido" javaType="com.ejemplo.modelo.Pedido">
<result property="idPedido" column="id_pedido"/>
<result property="numeroPedido" column="numero_pedido"/>
</association>
</resultMap>
<select id="obtenerDetalleConPedido" resultMap="DetallePedidoRepMap" parameterType="java.lang.Integer">
SELECT p.id_pedido, p.numero_pedido, d.id_detalle, d.id_producto, d.cantidad, d.fk_pedido
FROM tabla_pedido p INNER JOIN tabla_detalle_pedido d ON p.id_pedido = d.fk_pedido
WHERE d.id_detalle = #{idDetalle}
</select>
Relación Muchos a Muchos: Libros y Categorías
Para relaciones muchos a muchos, se usa una tabla intermedia. Ejemplo con libros y categorías.
Clase de representación para Libro (LibroRep.java):
package com.ejemplo.modelo;
import java.util.ArrayList;
import java.util.List;
public class LibroRep extends Libro {
private List<Categoria> categorias = new ArrayList<>();
public List<Categoria> getCategorias() {
return categorias;
}
public void setCategorias(List<Categoria> categorias) {
this.categorias = categorias;
}
}
Clase de representación para Categoria (CategoriaRep.java):
package com.ejemplo.modelo;
import java.util.ArrayList;
import java.util.List;
public class CategoriaRep extends Categoria {
private List<Libro> libros = new ArrayList<>();
public List<Libro> getLibros() {
return libros;
}
public void setLibros(List<Libro> libros) {
this.libros = libros;
}
}
Interfaz del mapper para la tabla intermedia (LibroCategoriaMapper.java):
package com.ejemplo.mapper;
import com.ejemplo.modelo.CategoriaRep;
import com.ejemplo.modelo.LibroRep;
import org.apache.ibatis.annotations.Param;
public interface LibroCategoriaMapper {
LibroRep buscarLibroConCategorias(@Param("idLibro") Integer idLibro);
CategoriaRep buscarCategoriaConLibros(@Param("idCategoria") Integer idCategoria);
}
Configuración XML para mapeos muchos a muchos (LibroCategoriaMapper.xml):
<resultMap id="LibroRepMap" type="com.ejemplo.modelo.LibroRep">
<result property="idLibro" column="id_libro"/>
<result property="titulo" column="titulo"/>
<result property="precio" column="precio"/>
<collection property="categorias" ofType="com.ejemplo.modelo.Categoria">
<result property="idCategoria" column="id_categoria"/>
<result property="nombreCategoria" column="nombre_categoria"/>
</collection>
</resultMap>
<resultMap id="CategoriaRepMap" type="com.ejemplo.modelo.CategoriaRep">
<result property="idCategoria" column="id_categoria"/>
<result property="nombreCategoria" column="nombre_categoria"/>
<collection property="libros" ofType="com.ejemplo.modelo.Libro">
<result property="idLibro" column="id_libro"/>
<result property="titulo" column="titulo"/>
<result property="precio" column="precio"/>
</collection>
</resultMap>
<select id="buscarLibroConCategorias" resultMap="LibroRepMap" parameterType="java.lang.Integer">
SELECT l.id_libro, l.titulo, l.precio, c.id_categoria, c.nombre_categoria
FROM tabla_libro l
INNER JOIN tabla_libro_categoria lc ON l.id_libro = lc.fk_libro
INNER JOIN tabla_categoria c ON lc.fk_categoria = c.id_categoria
WHERE l.id_libro = #{idLibro}
</select>
<select id="buscarCategoriaConLibros" resultMap="CategoriaRepMap" parameterType="java.lang.Integer">
SELECT c.id_categoria, c.nombre_categoria, l.id_libro, l.titulo, l.precio
FROM tabla_categoria c
INNER JOIN tabla_libro_categoria lc ON c.id_categoria = lc.fk_categoria
INNER JOIN tabla_libro l ON lc.fk_libro = l.id_libro
WHERE c.id_categoria = #{idCategoria}
</select>
Estos ejemplos ilustran cómo configurar relaciones uno a muchos y muchos a muchos en Mybatis, adaptando las clases VO y configuraciones XML para reflejar las asociaciones necesarias.