📄 quickstart.po
字号:
" }\n" "\n" " public char getSex() {\n" " return sex;\n" " }\n" "\n" " public void setSex(char sex) {\n" " this.sex = sex;\n" " }\n" "\n" " public float getWeight() {\n" " return weight;\n" " }\n" "\n" " public void setWeight(float weight) {\n" " this.weight = weight;\n" " }\n" "\n" "}]]>"#: index.docbook:262msgid "appended paragraph 38"msgstr "Hibernate no está restringido en su uso de tipos de propiedad, todos los tipos y tipos primitivos del JDK de Java (como <literal>String</literal>, <literal>char</literal> y <literal>Date</literal>) pueden ser mapeados, incluyendo clases del framework de colecciones de Java. Puedes mapearlos como valores, colecciones de valores, o asociaciones a otras entidades. El <literal>id</literal> es una propiedad especial que representa el identificador de base de datos (clave primaria) de la clase. Es altamente recomendado para entidades como un <literal>Cat</literal>. Hibernate puede usar identificadores sólo internamente, pero perderíamos algo de la flexibilidad en nuestra arquitectura de aplicación."#: index.docbook:275msgid "appended paragraph 39"msgstr "No tiene que implementarse ninguna interface especial para las clases persistentes ni tienes que subclasear de una clase persistente raíz en especial. Hibernate tampoco requiere ningún procesamiento en tiempo de construcción, como manipulación del byte-code. Se basa solamente en reflección de Java y aumentación de clases en tiempo de ejecución (a través de CGLIB). De modo que, sin ninguna dependencia de la clase POJO en Hibernate, podemos mapearla a una tabla de base de datos."#: index.docbook:288msgid "appended paragraph 40"msgstr "Mapeando el gato"#: index.docbook:290msgid "appended paragraph 41"msgstr "El fichero de mapeo <literal>Cat.hbm.xml</literal> contiene los metadatos requeridos para el mapeo objeto/relacional. Los metadatos incluyen la declaración de clases persistentes y el mapeo de propiedades (a columnas y relaciones de claves foráneas a otras entidades) a tablas de base de datos."#: index.docbook:298msgid "appended paragraph 42"msgstr "" "<![CDATA[<?xml version=\"1.0\"?>\n" "<!DOCTYPE hibernate-mapping PUBLIC\n" " \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" " \"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\">\n" "\n" "<hibernate-mapping>\n" "\n" " <class name=\"org.hibernate.examples.quickstart.Cat\" table=\"CAT\">\n" "\n" " <!-- A 32 hex character is our surrogate key. It's automatically\n" " generated by Hibernate with the UUID pattern. -->\n" " <id name=\"id\" type=\"string\" unsaved-value=\"null\" >\n" " <column name=\"CAT_ID\" sql-type=\"char(32)\" not-null=\"true\"/>\n" " <generator class=\"uuid.hex\"/>\n" " </id>\n" "\n" " <!-- A cat has to have a name, but it shouldn' be too long. -->\n" " <property name=\"name\">\n" " <column name=\"NAME\" length=\"16\" not-null=\"true\"/>\n" " </property>\n" "\n" " <property name=\"sex\"/>\n" "\n" " <property name=\"weight\"/>\n" "\n" " </class>\n" "\n" "</hibernate-mapping>]]>"#: index.docbook:300msgid "appended paragraph 43"msgstr "Cada clase persistente debe tener un atributo identificador (realmente, sólo las clases que representen entidades, no las clases dependientes de tipo-valor, que son mapeadas como componentes de una entidad). Esta propiedad es usada para distinguir los objetos persistentes: Dos gatos son iguales si <literal>catA.getId().equals(catB.getId())</literal> es verdadero. Este concepto se llama <emphasis>identidad de base de datos (database identity)</emphasis>. Hibernate viene empaquetado con varios generadores de identificador para diferentes escenarios (incluyendo generadores nativos para secuencias de base de datos, tablas de identificadores alto/bajo, e identificadores asignados por aplicación). Usamos el generador UUID (recomendado sólo para pruebas, pues deben preferirse las claves enteras delegadas generadas por la base de datos) y también especificamos la columna <literal>CAT_ID</literal> de la tabla <literal>CAT</literal> para el valor identificador generado por Hibernate (como una clave primaria de la tabla)."#: index.docbook:317msgid "appended paragraph 44"msgstr "Todas las demás propiedades de <literal>Cat</literal> son mapeadas a la misma tabla. En el caso de la propiedad <literal>name</literal>, la hemos mapeado con una declaración explícita de columna de base de datos. Esto es especialmente útil cuando el esquema de base de datos es generado automáticamente (como sentencias DDL de SQL) desde la declaración de mapeo con la herramienta <emphasis>SchemaExport</emphasis> de Hibernate. Todas las demás propiedades son mapeadas usando la configuración por defecto de Hibernate, que es lo que necesitas la mayoría del tiempo. La tabla <literal>CAT</literal> en la base de datos se ve así como:"#: index.docbook:329msgid "appended paragraph 45"msgstr "" "<![CDATA[ Columna | Tipo | Modificadores\n" "--------+-----------------------+-----------\n" " cat_id | character(32) | not null\n" " name | character varying(16) | not null\n" " sex | character(1) |\n" " weight | real |\n" "Indexes: cat_pkey primary key btree (cat_id)]]>"#: index.docbook:331msgid "appended paragraph 46"msgstr "Ahora debes crear esta tabla manualmente en tu base de datos, y luego leer el <xref linkend=\"toolsetguide\"/> si quieres automatizar este paso con la herramienta <literal>hbm2ddl</literal>. Esta herramienta puede crear un DDL SQL completo, incluyendo definición de tablas, restricciones personalizadas de tipo de columnas, restricciones de unicidad e índices."#: index.docbook:342msgid "appended paragraph 47"msgstr "Jugando con gatos"#: index.docbook:344msgid "appended paragraph 48"msgstr "Ahora estamos listos para comenzar la <literal>Session</literal> de Hibernate. Es el <emphasis>manejador de persistencia</emphasis> que usamos para almacenar y traer <literal>Cat</literal>s hacia y desde la base de datos. Pero primero, tenemos que obtener una <literal>Session</literal> (unidad de trabajo de Hibernate) de la <literal>SessionFactory</literal>:"#: index.docbook:352msgid "appended paragraph 49"msgstr "" "<![CDATA[SessionFactory sessionFactory =\n" " new Configuration().configure().buildSessionFactory();]]>"#: index.docbook:354msgid "appended paragraph 50"msgstr "La llamada a <literal>configure()</literal> carga el fichero de configuración <literal>hibernate.cfg.xml</literal> e inicializa la instancia de <literal>Configuration</literal>. Puedes establecer otras propiedades (e incluso cambiar los metadatos de mapeo) accediendo a la <literal>Configuration</literal> <emphasis>antes</emphasis> que construyas la <literal>SessionFactory</literal> (que es inmutable). ¿Dónde creamos la <literal>SessionFactory</literal> y cómo accedemos a ella en nuestra aplicación?"#: index.docbook:365msgid "appended paragraph 51"msgstr "Una <literal>SessionFactory</literal> usualmente se construye una vez, por ejemplo, al arrancar con un servlet <emphasis>load-on-startup</emphasis>. Esto significa también que no debes mantenerla en una variable de instancia en tus servlets, sino en alguna otro sitio. Además, necesitamos algún tipo de <emphasis>Singleton</emphasis>, de modo que podamos acceder a la <literal>SessionFactory</literal> fácilmente en el código de aplicación. El siguiente enfoque mostrado resuelve ambos problemas: configuración de arranque y fácil acceso a una <literal>SessionFactory</literal>."#: index.docbook:377msgid "appended paragraph 52"msgstr "Implementamos una clase de ayuda <literal>HibernateUtil</literal>:"#: index.docbook:381msgid "appended paragraph 53"msgstr "" "<![CDATA[import org.hibernate.*;\n" "import org.hibernate.cfg.*;\n" "\n" "public class HibernateUtil {\n" "\n" " private static Logger log = LoggerFactory.getLogger(HibernateUtil.class);\n" "\n" " private static final SessionFactory sessionFactory;\n" "\n" " static {\n" " try {\n" " // Create the SessionFactory\n" " sessionFactory = new Configuration().configure().buildSessionFactory();\n" " } catch (Throwable ex) {\n" " // Make sure you log the exception, as it might be swallowed\n" " log.error(\"Initial SessionFactory creation failed.\", ex);\n" " throw new ExceptionInInitializerError(ex);\n" " }\n" " }\n" "\n" " public static final ThreadLocal session = new ThreadLocal();\n" "\n" " public static Session currentSession() {\n" " Session s = (Session) session.get();\n" " // Open a new Session, if this Thread has none yet\n" " if (s == null) {\n" " s = sessionFactory.openSession();\n" " session.set(s);\n" " }\n" " return s;\n" " }\n" "\n" " public static void closeSession() {\n" " Session s = (Session) session.get();\n" " if (s != null)\n" " s.close();\n" " session.set(null);\n" " }\n" "}]]>"#: index.docbook:383msgid "appended paragraph 54"msgstr "Esta clase no sólo cuida de la <literal>SessionFactory</literal> con su inicializador static, sino que además tiene una variable <literal>ThreadLocal</literal> que tiene la <literal>Session</literal> para la hebra actual. Asegúrate de entender el concepto Java de una variable local a una hebra antes de intentar usar esta ayuda. Una clase <literal>HibernateUtil</literal> más compleja y potente puede encontrarse en <literal>CaveatEmptor</literal>, http://caveatemptor.hibernate.org/"#: index.docbook:393msgid "appended paragraph 55"msgstr "Una <literal>SessionFactory</literal> es segura entre hebras, muchas hebras pueden acceder a ella concurrentemente y pedirle <literal>Session</literal>s. Una <literal>Session</literal> no es un objeto seguro entre hebras que representa una sola unidad-de-trabajo con la base de datos. Las <literal>Session</literal>s se abren desde una <literal>SessionFactory</literal> y son cerradas cuando todo el trabajo está completo. Un ejemplo en el método <literal>process()</literal> de tu servlet podría parecerse a esto (sin manejo de excepciones):"#: index.docbook:404msgid "appended paragraph 56"msgstr "" "<![CDATA[Session session = HibernateUtil.currentSession();\n" "Transaction tx = session.beginTransaction();\n" "\n" "Cat princess = new Cat();\n" "princess.setName(\"Princess\");\n" "princess.setSex('F');\n" "princess.setWeight(7.4f);\n" "\n" "session.save(princess);\n" "\n" "tx.commit();\n" "HibernateUtil.closeSession();]]>"#: index.docbook:406msgid "appended paragraph 57"msgstr "En una <literal>Session</literal>, cada operación de base de datos ocurre dentro de una transacción que aísla las operaciones de base de datos (incluso operaciones de sólo lectura). Usamos la API de <literal>Transaction</literal> de Hibernate para abstraer de la estrategia de transacciones subyacente (en nuestro caso, transacciones JDBC). Esto permite que nuestro código sea desplegado con transacciones manejadas por contenedor (usando JTA) sin cambio alguno."#: index.docbook:416msgid "appended paragraph 58"msgstr "Observa que puedes llamar <literal>HibernateUtil.currentSession();</literal> tantas veces como quieras, siempre obtendrás la <literal>Session</literal> actual de esta hebra. Tienes que asegurarte que la <literal>Session</literal> sea cerrada después que se complete tu unidad-de-trabajo, ya sea en código de tu servlet o en un filtro de servlet antes que la respuesta HTTP sea enviada. El bonito efecto colateral de la segunda opción es la fácil inicialización perezosa: la <literal>Session</literal> todavía está abierta cuando se dibuja la vista, de modo que Hibernate puede cargar objetos no inicializados mientras navegas tu actual grafo de objetos."#: index.docbook:428msgid "appended paragraph 59"msgstr "Hibernate tiene varios métodos que pueden ser usados para traer objetos desde la base de datos. La forma más flexible es usando el Lenguaje de Consulta de Hibernate (Hibernate Query Language o HQL), que es una extensión orientada a objetos de SQL fácil de aprender:"#: index.docbook:436msgid "appended paragraph 60"msgstr "" "<![CDATA[Transaction tx = session.beginTransaction();\n" "\n" "Query query = session.createQuery(\"select c from Cat as c where c.sex = :sex\");\n" "query.setCharacter(\"sex\", 'F');\n" "for (Iterator it = query.iterate(); it.hasNext();) {\n" " Cat cat = (Cat) it.next();\n" " out.println(\"Female Cat: \" + cat.getName() );\n" "}\n" "\n" "tx.commit();]]>"#: index.docbook:438msgid "appended paragraph 61"msgstr "Hibernate también ofrece una API <emphasis>consulta por criterios</emphasis> orientada a objetos que puede ser usada para formular consultas de tipo seguro. Por supuesto, Hibernate usa <literal>PreparedStatement</literal>s y ligado de parámetros para toda la comunicación SQL con la base de datos. También puedes usar la funcionalidad de consulta SQL directa de Hibernate u obtener una conexión plana de JDBC de una <literal>Session</literal> en casos raros."#: index.docbook:451msgid "appended paragraph 62"msgstr "Finalmente"#: index.docbook:453msgid "appended paragraph 63"msgstr "Rasguñamos solamente la superficie de Hibernate en este pequeño tutorial. Por favor, observa que no incluimos ningún código específico de servlet en nuestros ejemplos. Tienes que crear un servlet por tí mismo e insertar el código de Hibernate como lo veas ubicado."#: index.docbook:461msgid "appended paragraph 64"msgstr "Ten en mente que Hibernate, como capa de acceso a datos, está firmemente integrado dentro de tu aplicación. Usualmente, todas las otras capas dependen del mecanismo de persistencia. Asegúrate de entender las implicaciones de este diseño."#: index.docbook:468msgid "appended paragraph 65"msgstr "Para un ejemplo de aplicación más compleja, ver http://caveatemptor.hibernate.org/ y echa una mirada a los otros tutoriales con links en http://www.hibernate.org/Documentation"msgid "ROLES_OF_TRANSLATORS"msgstr "<!--TRANS:ROLES_OF_TRANSLATORS-->"msgid "CREDIT_FOR_TRANSLATORS"msgstr "<!--TRANS:CREDIT_FOR_TRANSLATORS-->"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -