awe-104 Obtención y manipulación de datos
Este tutorial explica el flujo de datos principal de AWE: de dónde proceden los datos de la pantalla, cómo se define la obtención de datos en el servidor y cómo se persisten los cambios. Empiece con los valores enumerados y las queries, añada después los maintains y solo entonces pase a las integraciones avanzadas, como el correo electrónico, las colas o la obtención de datos respaldada por servicios.
Ruta rápida
- Utilice un enumerado cuando la lista sea pequeña y estable.
- Utilice variables para vincular los valores de la pantalla con queries o maintains.
- Utilice
Queries.xmlpara obtener datos. - Utilice
Maintain.xmlpara insertar, actualizar o borrar datos. - Trate el correo electrónico, las colas y los flujos respaldados por servicios como extensiones avanzadas.
Antes de empezar
Esta página se complementa bien con:
Tenga presente el modelo de alto nivel:
screen criteria -> variables -> query or service -> grid/chart/value
screen action -> maintain or service -> database or side effect
Paso 1: Utilice valores enumerados para listas de opciones sencillas
Los grupos de enumerados son adecuados para listas estables de clave/valor, como indicadores Sí/No, listas de idiomas o pequeños conjuntos internos de opciones.
Se definen en global/Enumerated.xml.
<?xml version="1.0" encoding="UTF-8"?>
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
<group id="[Group Id]">
<option label="[Option label]" value="[Option value]" />
<option label="[Option label]" value="[Option value]" />
</group>
</enumerated>
Primer ejemplo
<?xml version="1.0" encoding="UTF-8"?>
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
<!-- Enumerated YES (0) | NO (1) -->
<group id="Es1Es0">
<option label="ENUM_NO" value="0" />
<option label="ENUM_YES" value="1" />
</group>
</enumerated>
Utilícelo desde un criterio de este modo:
<criteria label="PARAMETER_ACTIVE" component="select" id="CrtSta" initial-load="enum" target-action="Es1Es0" style="col-xs-6 col-sm-3 col-lg-2" optional="true" />
Otro ejemplo típico:
<group id="LanUsr">
<option label="ENUM_LAN_ES" value="es-ES"/>
<option label="ENUM_LAN_EN" value="en-GB"/>
<option label="ENUM_LAN_FR" value="fr-FR"/>
</group>
Paso 2: Utilice variables para vincular los datos de la pantalla con el servidor
Las variables son el puente entre lo que el usuario ve en la pantalla y lo que su query, maintain o servicio necesita en el servidor.
Usos habituales:
- pasar el valor de un criterio a una cláusula
where - pasar un identificador seleccionado a una operación de actualización o de borrado
- pasar un valor fijo o derivado a un servicio o a un maintain
Si la pantalla es la capa de interfaz, las variables son las tuberías con nombre que llevan los valores hasta los descriptores del backend.
Paso 3: Obtenga datos con queries
Las queries de base de datos se definen en global/Queries.xml. En AWE, una query es una definición de obtención de datos en el servidor que utilizan componentes como grids, selects, suggests y gráficos.
No confunda el descriptor query de AWE con SQL escrito a mano. AWE traduce el modelo XML por usted.
Ejemplo básico de query
<query id="CheckAdeudoId">
<field id="Id" transform="NUMBER" pattern="###" />
<field id="Id_File" />
<table id="Adeudo" />
<where>
<and>
<filter left-field="Id_File" condition="eq" right-variable="varIdFile" trim="true" />
</and>
</where>
<variable type="STRING" id="varIdFile" name="idFile" />
</query>
Este ejemplo muestra el patrón habitual:
- definir los campos que se van a obtener
- definir la tabla de origen
- añadir una cláusula
where - vincular una o más variables
select y select-multiple
Cuando una query rellena un criterio de tipo select, los campos devueltos deben seguir el contrato de nombres esperado:
value: el valor que se envíalabel: el texto que se muestra al usuario
<criteria label="PARAMETER_SELECT" id="select" variable="select" component="select"
initial-load="query" target-action="FillSelect" optional="true"/>
<query id="FillSelect">
<table id="MyTable"/>
<field id="field1" alias="value" />
<field id="field2" alias="label" />
<where>
<and>
...
</and>
</where>
</query>
Si un criterio se carga desde una query durante la creación de la pantalla, asegúrese de que la query no dependa de variables que solo existen cuando la pantalla actual ya se ha renderizado.
suggest y suggest-multiple
Los componentes suggest utilizan el mismo contrato de campos label/value, pero obtienen los valores bajo demanda mientras el usuario escribe.
<criteria label="PARAMETER_SUGGEST" id="suggest" variable="suggest" component="suggest"
server-action="data" target-action="FillSuggest"/>
<query id="FillSuggest">
<table id="MyTable"/>
<field id="field1" alias="value" />
<field id="field2" alias="label" />
<where>
<and>
<filter left-field="field2" condition="like" right-variable="suggest" ignorecase="true" />
</and>
</where>
<variable id="suggest" type="STRINGB" name="suggest"/>
</query>
Paso 4: Persista los cambios con maintains
Los maintains definen las operaciones de escritura en global/Maintain.xml: inserciones, actualizaciones, borrados y flujos de escritura por lotes.
Ejemplo de inserción
<target name="ProNew">
<insert audit="HISAwePro">
<table id="AwePro" />
<field id="IdePro" sequence="ProKey" variable="IdePro" />
<field id="Acr" variable="Acr" />
<field id="Nam" variable="Nam" />
<field id="IdeThm" variable="IdeThm" />
<field id="ScrIni" variable="ScrIni" />
<field id="Res" variable="Res" />
<field id="Act" variable="Act" />
<variable id="IdePro" type="INTEGER" />
<variable id="Acr" type="STRINGN" name="Acr" />
<variable id="Nam" type="STRINGN" name="Nam" />
<variable id="IdeThm" type="INTEGER" name="IdeThm" />
<variable id="ScrIni" type="STRING" name="ScrIni" />
<variable id="Res" type="STRING" name="Res" />
<variable id="Act" type="INTEGER" name="Act" />
</insert>
</target>
El campo IdePro toma su valor de la secuencia ProKey de la tabla AweKey, por lo que su variable no tiene name: recibe el valor generado en lugar de leerlo de la pantalla.
Ejemplo de actualización
<target name="ProUpd">
<update audit="HISAwePro">
<table id="AwePro" />
<field id="IdePro" variable="IdePro" />
<field id="Acr" variable="Acr" />
<field id="Nam" variable="Nam" />
<field id="IdeThm" variable="IdeThm" />
<field id="ScrIni" variable="ScrIni" />
<field id="Res" variable="Res" />
<field id="Act" variable="Act" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
<variable id="Acr" type="STRINGN" name="Acr" />
<variable id="Nam" type="STRINGN" name="Nam" />
<variable id="IdeThm" type="INTEGER" name="IdeThm" />
<variable id="ScrIni" type="STRING" name="ScrIni" />
<variable id="Res" type="STRING" name="Res" />
<variable id="Act" type="INTEGER" name="Act" />
</update>
</target>
Ejemplo de borrado
<target name="ProDel">
<delete multiple="true" audit="HISAweModPro">
<table id="AweModPro" />
<field id="IdePro" variable="IdePro" audit="true" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
</delete>
<commit/>
<delete multiple="true" audit="HISAweScrRes">
<table id="AweScrRes" />
<field id="IdePro" variable="IdePro" audit="true" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
</delete>
</target>
Este ejemplo también muestra dos puntos importantes:
multiple="true"significa que la variable puede representar una lista de valores.<commit/>permite separar explícitamente las fases de escritura cuando es necesario.
Operaciones múltiples de grid
Cuando un grid editable puede mezclar inserciones, actualizaciones y borrados en un mismo lote, utilice un target de maintain de tipo multiple.
<target name="ScrAccUpd">
<multiple audit="HISAweScrRes" grid="GrdScrAccLst">
<table id="AweScrRes" />
<field id="IdeAweScrRes" variable="IdeAweScrRes" sequence="ScrResKey" key="true" />
<field id="IdePro" variable="IdePro" />
<field id="IdeOpe" variable="IdeOpe" />
<field id="IdeMod" variable="IdeMod" />
<field id="Opt" variable="Opt" />
<field id="AccMod" variable="AccMod" />
<field id="Act" variable="Act" />
<variable id="IdeAweScrRes" type="INTEGER" name="IdeAweScrRes" />
<variable id="IdeOpe" type="INTEGER" name="IdeOpe"/>
<variable id="IdePro" type="INTEGER" name="IdePro"/>
<variable id="IdeMod" type="INTEGER" name="IdeMod"/>
<variable id="Opt" type="STRING" name="Opt" />
<variable id="AccMod" type="STRING" name="AccMod" />
<variable id="Act" type="INTEGER" name="Act" />
</multiple>
</target>
Este patrón se apoya en el contexto del grid para indicar a AWE qué operación ejecutar en cada fila.
Temas avanzados
Las secciones siguientes son útiles, pero no son la primera parada en la mayoría de las pantallas.
Envío de correo electrónico
Las definiciones de correo electrónico se encuentran en Email.xml y con frecuencia se lanzan desde un target de maintain.
<email id="TransfersSNCEEmaRep">
<from value="FromValue" label="FromValue" />
<to label="RepEmaDst" value="RepEmaDst" />
<subject label="RepTit" value="RepTit" />
<body label="RepMsg" type="html" value="RepMsg"/>
<body label="RepMsg" type="text" value="RepMsg"/>
<variable type="STRING" id="FromValue" property="sch.report.email"/>
<variable type="STRING" id="RepMsg" name="RepMsg"/>
<variable type="STRING" id="RepTit" name="RepTit"/>
</email>
<target name="SndRep">
<send-email id="SndRep" />
</target>
Conexión con colas
Las integraciones con colas se definen en Queues.xml y suelen utilizarse cuando AWE debe intercambiar datos con una infraestructura de mensajería externa.
<queues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://aweframework.gitlab.io/awe/docs/schemas/queues.xsd">
<queue id="TstGrdQue">
<request-message destination="AweReq" type="MAP" selector="grid">
</request-message>
<response-message destination="AweRes" type="MAP">
<message-parameter id="OutFld1" type="STRING" name="MapKey1" list="true" />
<message-parameter id="OutFld2" type="STRING" name="MapKey2" list="true" />
<message-parameter id="OutFld3" type="STRING" name="MapKey3" list="true" />
<message-parameter id="OutFld4" type="STRING" name="MapKey4" list="true" />
</response-message>
</queue>
</queues>
Obtención o escritura de datos respaldada por servicios
Los servicios pueden respaldar queries o maintains cuando el XML de base de datos por sí solo no es suficiente.
Desde una query:
<query id="GetFechasCancelacionesSup" service="GetFilteredDates">
<field id="label" alias="label" transform="DATE" function="TRUNCDATE" />
<field id="value" alias="value" transform="DATE" function="TRUNCDATE" />
<variable id="Dias" type="INTEGER" name="Dias" value="10" />
</query>
Desde un maintain:
<target name="checkYearHolidays">
<serve service="checkYearHolidays"/>
</target>
Si necesita implementar el propio servicio, continúe con awe-107.
Qué hacer a continuación
- Utilice awe-107 cuando la obtención o la persistencia de datos deba invocar lógica Java.
- Utilice awe-106 cuando las pantallas deban reaccionar dinámicamente a valores o a resultados del servidor.
- Utilice la referencia de la API para consultar todos los descriptores cuando el camino básico de los datos ya esté claro.