sirven - recorrer enum java
Datos persistentes adecuados para enumeraciones (8)
Almacenamos valores enum usando algún valor explícito de cadena o carácter en la base de datos. Luego, para pasar del valor de la base de datos a enum, escribimos un método estático en la clase enum para iterar y encontrar el correcto.
Si espera muchos valores enum, puede crear una asignación estática HashMap<String,MyEnum>
para traducir rápidamente.
No almacene el nombre real de la enumeración (es decir, "ACTIVO" en su ejemplo) porque los desarrolladores pueden refactorizarlo fácilmente.
La mayoría de los proyectos tienen algún tipo de datos que son esencialmente estáticos entre lanzamientos y adecuados para su uso como enumeración, como estados, tipos de transacciones, códigos de error, etc. Por ejemplo, usaré una enumeración de estado común:
public enum Status {
ACTIVE(10, "Active");
EXPIRED(11, "Expired");
/* other statuses... */
/* constructors, getters, etc. */
}
Me gustaría saber qué hacen los demás en términos de persistencia con respecto a datos como estos. Veo algunas opciones, cada una de las cuales tiene algunas ventajas y desventajas obvias:
- Persista los estados posibles en una tabla de estado y mantenga todos los posibles objetos de dominio de estado almacenados en caché para su uso en toda la aplicación
- Solo use una enumeración y no persista en la lista de estados disponibles, creando una guerra santa de coherencia de datos entre mí y mi DBA
- Persista los estados y mantenga una enumeración en el código, pero no los una, creando datos duplicados
Mi preferencia es la segunda opción, aunque mi DBA afirma que nuestros usuarios finales pueden querer acceder a los datos brutos para generar informes, y no persistir los estados daría lugar a un modelo de datos incompleto (argumento en contra: esto podría resolverse con la documentación) .
¿Existe una convención que la mayoría de la gente usa aquí? ¿Cuáles son las experiencias de las personas con cada una y existen otras alternativas?
Editar:
Después de pensarlo por un tiempo, mi lucha real por la persistencia viene con el manejo de los valores de id que están ligados a los estados en la base de datos. Estos valores se insertarán como datos predeterminados al instalar la aplicación. En este punto, tendrían identificadores que se pueden utilizar como claves externas en otras tablas. Siento que mi código necesita saber acerca de estos identificadores para que pueda recuperar fácilmente los objetos de estado y asignarlos a otros objetos. ¿Qué debo hacer al respecto? Podría agregar otro campo, como "código", para buscar cosas, o simplemente buscar estados por nombre, lo cual es asqueroso.
Bueno, no tenemos un DBA para responder, por lo que nuestra preferencia es para la opción 2).
Simplemente guardamos el valor de Enum en la base de datos, y cuando estamos cargando datos fuera de la base de datos y en nuestros objetos de dominio, simplemente convertimos el valor entero en el tipo de enumeración. Esto evita cualquiera de los dolores de cabeza de sincronización con las opciones 1) y 3). La lista se define una vez: en el código.
Sin embargo, tenemos una política que nadie más accede directamente a la base de datos; Deben venir a través de nuestros servicios web para acceder a cualquier información. Entonces esta es la razón por la cual funciona bien para nosotros.
En su base de datos, la clave principal de esta tabla de "dominio" no tiene que ser un número. Solo use un varchar pk y una columna de descripción (para los fines de su dba). Si necesita garantizar el orden de sus valores sin depender del sordo alfabético, simplemente agregue una columna numérica llamada "orden o secuencia".
En su código, cree una clase estática con constantes cuyo nombre (en camello o no) se asigna a la descripción y asigna mapas al pk. Si necesita más que esto, cree una clase con la estructura necesaria y los operadores de comparación y use instancias de ella como el valor de las constantes.
Si hace esto demasiado, cree un script para generar el código de instalación / declaración.
Estoy usando una combinación de los tres enfoques que has documentado ...
Use la base de datos como fuente autorizada para los valores de Enum. Almacene los valores en una tabla de ''código'' de algún tipo. Cada vez que construya, genere un archivo de clase para que Enum sea incluido en su proyecto.
De esta forma, si la enumeración cambia el valor en la base de datos, su código se invalidará correctamente y recibirá los errores de compilación apropiados de su servidor de integración continua. Tiene un enlace fuertemente tipado a sus valores enumerados en la base de datos, y no tiene que preocuparse por sincronizar manualmente los valores entre el código y los datos.
Joshua Bloch ofrece una excelente explicación de las enumeraciones y cómo usarlas en su libro " Effective Java, Second Edition " (p.147)
Allí puedes encontrar todo tipo de trucos sobre cómo definir tus enumeraciones, persistirlas y cómo mapearlas rápidamente entre la base de datos y tu código (p.154).
Durante una charla en el Jazoon 2007, Bloch dio las siguientes razones para usar un atributo adicional para asignar enumeraciones a los campos DB y viceversa: una enumeración es una constante pero el código no lo es. Para asegurarse de que un desarrollador que edita el código fuente no puede romper accidentalmente el mapeo DB al reordenar las enumeraciones o cambiar el nombre a continuación, debe agregar un atributo específico (como "nombrebd") a la enumeración y usarlo para asignarlo.
Las enumeraciones tienen una identificación intrínseca (que se utiliza en la instrucción switch ()) pero esta identificación cambia cuando usted cambia el orden de los elementos (por ejemplo clasificándolos o agregando elementos en el medio).
Entonces, la mejor solución es agregar un método toDB () y fromDB () y un campo adicional. Sugiero usar cadenas cortas y legibles para este nuevo campo, para que pueda decodificar un volcado de base de datos sin tener que buscar las enumeraciones.
Lo que utilicé en varias ocasiones es definir la enumeración en el código y una representación de almacenamiento en la capa de persistencia (DB, archivo, etc.) y luego tener métodos de conversión para asignarlos entre sí. Estos métodos de conversión solo se deben utilizar al leer o escribir en la tienda persistente y la aplicación puede usar el tipo de enumeraciones seguras en todas partes. En los métodos de conversión utilicé las declaraciones de cambio para hacer la asignación. Esto también permite emitir una excepción si se quiere convertir un estado nuevo o desconocido (generalmente porque la aplicación o los datos son más nuevos que el otro y se han declarado estados nuevos o adicionales).
Si bien no estoy familiarizado con la idea de "atributos" en Java (y no sé qué idioma estás usando), generalmente he usado la idea de una tabla de códigos (o tablas específicas de dominio) y he atribuí mis valores enum con datos más específicos, como cadenas legibles por humanos (por ejemplo, si mi valor enum es NewStudent, lo atribuiría con "New Student" como valor de visualización). Luego uso Reflection para examinar los datos en la base de datos e insertar o actualizar registros para alinearlos con mi código, usando el valor enum real como ID de clave.
Si hay al menos una posibilidad menor de que la lista de valores deba actualizarse de lo que es 1. De lo contrario, es 3.