La asignación de clave primaria compuesta requiere el uso de la etiqueta <Composite-id> en el archivo de configuración de mapeo. Esta etiqueta se refiere a especificar una clase como la clave primaria compuesta correspondiente. Su atributo de nombre debe especificar el valor de la propiedad definido en el archivo de clase y agregar el Sub-Label <Key-Property> a la etiqueta.
Nota: Si desea utilizar el mapeo compuesto, debe colocar la clave primaria compuesta en una clase, es decir, los atributos de la clave primaria compuesta y otros atributos se dividen en dos clases, y la clase de clave primaria compuesta implementa la interfaz serializable, que pertenece a Java.io.
La clave principal de la relación de mapeo de la clave primaria compuesta está compuesta de múltiples columnas, que corresponde a la tabla de datos bastante simple, como se muestra en la figura a continuación:
1. Archivos de clase
Aquí tomamos la tabla en la figura anterior como ejemplo. En la tabla, dos campos y duraciones se combinan para formar la clave principal de la tabla. Por lo tanto, las nuevas clases divididas se denominan FiscalyearPeriod y FiscalyearPeriodpk respectivamente. Entre ellos, la clase FiscalyearPeriod encapsula los atributos clave principales de la tabla, la clase FiscalyearPeriod encapsula otros atributos y la clase FiscalyearPeriod.
1.1 fiscalyearperiod.java
La clase encapsula las propiedades básicas y encapsula la clase FiscalyEarPerioDPK como atributos en la clase, y configura la asignación correspondiente en el archivo de configuración, de la siguiente manera:
paquete com.src.Hibernate; import java.sql.date; clase pública FiscalyearPeriod {// Tiempo Key primaria privada fiscalyearPeriodpk fiscalyearPeriodpk; public fiscalyearPeriodpk getFiscalyearPeriodpk () {return fiscalyearPeriodpk; } public void setfiscalyearPeriodpk (fiscalyearPeriodpk fiscalyearPeriodpk) {this.fiscalyearPeriodpk = fiscalyearPeriodpk; } // Fecha de inicio Fecha privada begindate; Fecha pública getBegindate () {return begindate; } public void setBegindate (date begindate) {this.begindate = beginDate; } // Fecha de finalización Fecha privada End Date; Fecha pública getenddate () {return enddate; } public void setendDate (date enddate) {this.enddate = endDate; } // Tiempo de etapa de cadena privada Periods; public String getPerioDsts () {return PeriodSts; } public void setPeriodsts (string periodSts) {this.periodsts = periodsts; }} 1.2 fiscalyearperiodpk.java
Encapsula el atributo clave principal. Esta clase está separada de la clase FiscalyearPeriod. Contiene los atributos de clave primarios básicos y necesita implementar la interfaz serializable. Esta clase debe asignarse a la etiqueta <Composite-id> en el archivo de configuración para especificar la clase. El código es el siguiente:
paquete com.src.Hibernate; import java.io.serializable; clase pública fiscalyearperiodpk implementa serializable {// año private int fiscalyear; public int getfiscalyear () {return fiscalyear; } public void setfiscalyear (int fiscalyear) {this.fiscalyear = fiscalyear; } // duración privada int fiscalPeriod; public int getFiscalPeriod () {return fiscalPeriod; } public void setFiscalPeriod (int fiscalPeriod) {this.fiscalPeriod = fiscalPeriod; }} 2. Archivo de configuración
Aquí hay una pregunta ¿Cuál de las dos clases necesita agregar archivos de mapeo? Debido a que se usa la etiqueta <Composite-id>, solo necesita agregar una asignación para la clase FiscalyEarPeriod, agregue la etiqueta de clave primaria compuesta correspondiente al archivo de asignación y agregar los atributos de clave primarios correspondientes a la etiqueta, de la siguiente manera:
<? Xml versión = "1.0"?> < table = "t_fiscal_year_period_pk"> <compuesto-id name = "fiscalyearpk"> <key-property name = "fiscalyear"> </ key-property> <keypreperty name = "fiscalperiod"> </key-property> type = "Date"/> <Property Name = "EndDate" type = "date"/> <Property name = "periodSts"/> </class> </hibernate-mapping>
El archivo anterior se genera para generar la tabla de base de datos correspondiente, y la instrucción SQL generada es la siguiente:
Tabla de caída si existe T_FISCAL_YEAR_PERIOD_PK Crear tabla T_FISCAL_YEAR_PERIOD_PK (Fiscalyear Integer no NULL, FiscalPeriod Integer no NULL, FECHA BEGADA, FECHA DE DICIÓN, PERIODSTS VARCHAR (255), Clave primaria (fiscalia, fiscalperiod))))
La estructura de la tabla correspondiente es la siguiente:
3. Operación de datos
Después de configurar el archivo de asignación correspondiente, la operación de datos correspondiente se vuelve muy simple. Primero, comience con la escritura de datos. Al escribir datos en la base de datos, se escribirán dos clases en la base de datos al mismo tiempo. Por lo tanto, ambas clases deben convertirse en estado transitorio. Por lo tanto, al guardar, primero debe guardar el objeto FiscalyearPeriod a la base de datos primero, y luego asociará automáticamente los atributos compuestos y guardará la información en la base de datos.
3.1 Operación de escritura
El método de operación de escritura es el mismo que el método de escritura anterior. Debe definir dos objetos y luego guardar la información del objeto correspondiente en la base de datos. El código es el siguiente:
public void testSave1 () {// Declarar la sesión de la sesión del objeto de sesión = null; Pruebe {// Obtenga la sesión del objeto de sesión = HibernateUtils.getSession (); // Abra la sesión Session.BeGinTransaction (); // Cree el objeto compuesto fiscalyearPeriodpk fiscalyearPeriodpk = new FiscalyEarPeriodpk (); fiscalyearPeriodpk.setfiscalperiod (2014); fiscalyearperiodpk.setfiscalyearyear (2012); // Crear el objeto fiscalyearPerioD fiscalyearPeriod = new FiscalyEarPerioD (); fiscalyearPeriod.setfiscalyearPeriodpk (fiscalyearPeriodpk); session.save (fiscalyearPeriod); // Enviar sesión Session Session.GetTransaction (). Commit (); } catch (Exception e) {E.PrintStackTrace (); session.getTransaction (). Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }}Ejecutar el método de prueba correspondiente, y la instrucción SQL generada es la siguiente:
Hibernate: insert into t_fiscal_year_period_pk (beginDate, endDate, periodSts, fiscalYear, fiscalPeriod) values (?, ?, ?, ?, ?) La vista de la base de datos correspondiente:
3.2 Operación de carga
El método de carga correspondiente será diferente de antes, porque la clave principal en la tabla es una propiedad compuesta, por lo que se debe crear una clase. Al cargar datos, debe crear un objeto clave principal. En este momento, la clave principal es un objeto, y debe asignar valores a las propiedades del objeto para obtener el objeto. El código es el siguiente:
public void testLoad1 () {// Declarar la sesión del objeto de sesión = nulo; Pruebe {// Obtenga la sesión del objeto de sesión = HibernateUtils.getSession (); // Abra la sesión Session.BeGinTransaction (); // Cree el objeto compuesto fiscalyearPeriodpk fiscalyearPeriodpk = new FiscalyEarPeriodpk (); fiscalyearPeriodpk.setfiscalperiod (2014); fiscalyearperiodpk.setfiscalyear (2012); FiscalyearPerioD fiscalyearPeriod = (fiscalyearPeriod) session.load (fiscalyearPeriod.class, fiscalyearPeriodpk); System.out.println ("Fecha de inicio:"+fiscalyearperiod.getBegindate ()); // Enviar sesión Session.getTransaction (). Commit (); } catch (Exception e) {E.PrintStackTrace (); session.getTransaction (). Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }}El resultado es el siguiente:
Hibernado: seleccione fiscalyear0_.fiscalyear como fiscalyear0_0_, fiscalyear0_.fiscalPeriod como fiscalpe2_0_0_, fiscalyear0_.begindate as beginDate0_0_, fiscalyear0_.enddate como end date0_0_, fiscal t_fiscal_year_period_pk fiscalyear0_ donde fiscalyear0_.fiscalyear =? y fiscalyear0_.fiscalPeriod =? Fecha de inicio: 2013-10-12
4. Ejemplos completos
Una tabla de departamento de una empresa más grande (Hibernate_Dept_Compositepk) consiste en campos como el área (área), el nombre del departamento (nombre), el número de personas en el departamento (empacada) y el tiempo de establecimiento (cumpleaños). Usamos el área y el nombre del departamento como la clave principal conjunta:
4.1 Clase objetivo: Departamento.Java
Departamento de clase pública { /** Resumen El atributo de asociación de clave principal y escríbelo en una clase por separado* /// área de cadena privada; // nombre de cadena privada; / ** Preparación del objeto de clase de clave principal como una variable miembro*/ Departamento de Departamento de Privado de Departamento; privado int cumpleaños de cita privada; // public String getArea () {// área de retorno; //} // // public void setArea (área de cadena) {// this.area = área; //} // // public string getName () {// return name; //} // // public void setName (nombre de cadena) {// this.name = name; //} public int getempCount () {return empCount; } public void setempcount (int } Fecha pública GetBirthday () {regreso de cumpleaños; } public void setBirthday (cumpleaños de fecha) {this.birthday = cumpleaños; } Public departampk getDePartmentPk () {return departmentpk; } public void setDepartmentPk (Departamento de departamento de Departamento) {this.departmentpk = departmentpk; }} 4.2 Clase clave principal: Departamento de departamento. Java
El departamento de clase pública implementa serializable {private static final long serialversionUid = -288002855915204255l; área de cuerda privada; nombre de cadena privada; /** * Sobrescribir el método hashcode (juzgado en función del área y el nombre) *///@anular public int hashcode () {final int prime = 31; int resultado = 1; resultado = prime * resultado + ((área == nulo)? 0: área.hashcode ()); resultado = prime * resultado + ((name == null)? 0: name.hashcode ()); resultado de retorno; } / ** * sobrescribir iguales (juzgado según el área y el nombre) * / @Override public boolean iguales (object obj) {if (this == obj) return true; if (obj == null) return false; if (getClass ()! = obj.getClass ()) return false; Departamento finalpk otro = (departampk) obj; if (área == null) {if (other.area! = null) return false; } else if (! área.equals (other.area)) return false; if (name == null) {if (other.name! = null) return false; } else if (! name.equals (other.name)) return false; devolver verdadero; } public String getArea () {área de retorno; } public void setArea (área de cadena) {this.area = área; } public String getName () {nombre de retorno; } public void setName (nombre de cadena) {this.name = name; }} 4.3 Departamento de mapeo de archivos.hbm.xml
<? xml versión = "1.0"?> < name = "com.yangfei.hibernate.compositepk.entity.department" table = "hibernate_dept_compositepk"> <!-Key primaria de unión-> <!-Nombre se refiere a atributos de objetos de clave primaria-> <compuesto-id name = "departamentpk"> <!-aquí es la propiedad de asociación principal principal-> <key-property name = "área" /"name" /"name" /> < /compuesto-id> <!-Otras propiedades-> <propiedad name = "empcount" longitud = "4" /> <propiedad name = "birthday" type = "date" /> < /class> < /hibernate mapping>
4.4 Archivo de configuración de Hibernate hibernate.cfg.xml
<? xml versión = '1.0' encoding = 'utf-8'?> < Herramientas. -> <Hibernate-Configuration> <Session-Factory> <Property Name = "Dialect"> org.hibernate.dialect.oracle9dialect </propine> <Property name = "Connection.url"> jdbc: oracle: delgada:@127.0.0.1: 1521: orcl10 </propiedad> <name de propiedad = "connection.username"> scott </scott </scott name = "Connect.Password"> YF123 </Property> <Property Name = "Connect.Driver_class"> Oracle.jdbc.driver.oracledRiver </propietS> <Property Name = "Hibernate.show_sql"> True </Property> <Mapping Recursce = "Com/Yangfei/HiBernate/Compositepk/Entity/departamento. </session-factory> </hibernate-configuration>
4.5 Clase de prueba: departamtest.java
Public Class DepartmentTest extiende TestCase { / *** Test Insert Dates* / public void save () {session session = hibernateUtils.getSession (); Transacción t = session.begintransaction (); Pruebe {Departamento de departamento = nuevo departamento (); / ** Generar objeto de clave primaria*/ departampk Deptpk = new DepartmentPk (); Deptpk.SetArea ("Beijing"); Deptpk.SetName ("Departamento de I + D"); Dept.SetDePartmentPk (Deptpk); Dept.SetEmpCount (100); Dept.SetBirthday (nueva fecha ()); session.save (departamento); t.commit (); } Catch (HibernateException e) {E.PrintStackTrace (); T.Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }} / *** Test Load Data* / public void Load () {Session Session = HibernateUtils.getSession (); Transacción t = session.begintransaction (); Pruebe { / ** Genere el objeto de clave primaria* / departampk de departpk = new DepartmentPk (); Deptpk.SetArea ("Beijing"); Deptpk.SetName ("Departamento de I + D"); Departamento departamento = (Departamento) Session.Load (Departamento.Class, Deptpk); System.out.println (departamento de getDepartmentPk (). GetArea ()+","+deTp.GetDePARTMentPk (). GetName ()+","+dePT.GetEmpCount ()+","+deTp.getBirthday ()); } Catch (HibernateException e) {E.PrintStackTrace (); T.Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }} / *** Test de datos de modificación* / public void Update () {Session Session = HibernateUtils.getSession (); Transacción t = session.begintransaction (); Pruebe { / ** Genere el objeto de clave primaria* / departampk de departpk = new DepartmentPk (); Deptpk.SetArea ("Beijing"); Deptpk.SetName ("Departamento de I + D"); Departamento emp = (departamento) Session.Load (Departamento.Class, Deptpk); System.out.println (emp.getDepartmentPk (). GetArea ()+","+emp.getDepartmentPk (). GetName ()+","+emp.getEmpCount ()+","+emp.getBirthday ()); EMP.SetEmpCount (100); Session.SaveOrupdate (EMP); / ** Generar objeto de clave primaria*/ departampk Deptpk2 = new DepartmentPk (); Deptpk2.SetArea ("Beijing"); Deptpk2.SetName ("Departamento de I + D"); Departamento departamento = (Departamento) Session.Load (Departamento.Class, Deptpk2); System.out.println (departamento de getDepartmentPk (). GetArea ()+","+deTp.GetDePARTMentPk (). GetName ()+","+dePT.GetEmpCount ()+","+deTp.getBirthday ()); t.commit (); } Catch (HibernateException e) {E.PrintStackTrace (); T.Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }} / *** Test Eliminar datos* / public void delete () {session session = hibernateUtils.getSession (); Transacción t = session.begintransaction (); Pruebe { / ** Genere el objeto de clave primaria* / departampk de departpk = new DepartmentPk (); Deptpk.SetArea ("Beijing"); Deptpk.SetName ("Departamento de I + D"); Departamento departamento = (Departamento) Session.Load (Departamento.Class, Deptpk); session.delete (departamento); t.commit (); } Catch (HibernateException e) {E.PrintStackTrace (); T.Rollback (); } finalmente {hibernateUtils.clossessession (sesión); }}}