Nutz es una suite de micro-frameworks modulares y livianos. Sus componentes pueden ser utilizados de forma independiente, encapsulando la esencia de tecnologías como Spring, Hibernate y Struts en un único JAR de aproximadamente 1MB. Nutz no tiene dependencias externas, lo que permite crear aplicaciones web completas con un solo JAR, excluyendo las dependencias de conexión a base de datos y logging.
La documentación exhaustiva es un pilar fundamental de Nutz, diferenciándolo de otros frameworks de código abierto. Sin embargo, incluso con un excelente producto, pueden surgir desafíos, como ocurrió con la anotación de índices en entidades.
Inicialmente, la falta de información clara y ejemplos sobre cómo implementar índices mediante anotaciones en Nutz representó un obstáculo. Tras una búsqueda infructuosa en motores de búsqueda y la documentación oficial, la solución se encontró en GitHub. A continuación, se detalla el procedimiento.
Consideremos las siguientes entidades:
/**
* Representa a un usuario.
*/
@Table("t_user")
public class User {
/**
* Identificador único del usuario.
*/
@Id
private long id;
// Otros atributos...
}
/**
* Registra las acciones realizadas por un usuario.
*/
@Table("t_user_record")
public class UserRecord {
/**
* Identificador único del registro.
*/
@Id
private long id;
/**
* ID del usuario asociado (clave foránea).
*/
@Column("user_id")
private long userId;
/**
* Fecha de creación del registro.
*/
@Column("create_date")
private Date createDate;
// Otros atributos...
}
Estas entidades modelan la relación entre usuarios y sus registros de actividad. El campo userId en UserRecord actúa como una clave foránea. Dado que un usuario puede generar múltiples registros, es crucial añadir un índice a este campo para optimizar las consultas.
Es importante destacar que la adición de índices debe ser estratégica. Un número excesivo de índices puede degradar significativamente el rendimiento de las operaciones de escritura. Campos con una cardinalidad muy baja (pocos valores únicos), como el género, generalmente no se benefician de un índice.
Para aplicar un índice al campo userId en la entidad UserRecord, se utiliza la anotación @TableIndexes junto con @Index:
/**
* Registra las acciones realizadas por un usuario.
*/
@Table("t_user_record")
@TableIndexes({
@Index(name="idx_user_record_user_id", fields={"userId"}, unique=false)
})
public class UserRecord {
/**
* Identificador único del registro.
*/
@Id
private long id;
/**
* ID del usuario asociado (clave foránea).
*/
@Column("user_id")
private long userId;
/**
* Fecha de creación del registro.
*/
@Column("create_date")
private Date createDate;
// Otros atributos...
}
La anotación @TableIndexes permite definir múltiples índices para una tabla. Cada anotación @Index dentro de @TableIndexes declara un índice específico.
Para definir varios índices:
@TableIndexes({
@Index(name="idx_user_record_user_id", fields={"userId"}, unique=false),
@Index(name="idx_user_record_combined", fields={"userId", "createDate"}, unique=false)
})
Los parámetros de la anotación @Index son:
- name: El nombre del índice. Se recomienda incluir el nombre de la tabla para evitar colisiones de nombres, dado que los índices son globales.
- fields: Una colección de nombres de propiedades de la entidad sobre las cuales se creará el índice. Esto permite la creación de índices compuestos (o conjuntos) sobre múltiples campos. Es crucial usar los nombres de las propiedades de la entidad, no los nombres de las columnas de la base de datos.
- unique: Un valor booleano que indica si el índice debe ser único. Existen principalmente tres tipos de índices: normales, únicos y de texto completo.
unique=falsedefine un índice normal.unique=truedefine un índice único, que además impone una restricción de unicidad en los valores del campo o campos indexados. Nutz no soporta índices de texto completo, que se utilizan para optimizar búsquedas en cadenas de texto extensas.
En cuanto a los índices compuestos, si se realizan consultas frecuentes que involucran múltiples campos, como:
SELECT * FROM T_TABLE WHERE FIELD1=? AND FIELD2=? AND FIELD3=?
Crear índices individuales para cada campo puede ser ineficiente. En su lugar, se puede crear un índice compuesto sobre FIELD1, FIELD2 y FIELD3. Al definir un índice compuesto, el ordan de los campos es importante. Si un campo se consulta frecuentemente de forma individual, se recomienda colocarlo al principio de la lista de campos en el índice compuesto.