O mapeamento de chave primária composta requer o uso da tag <composite-id> no arquivo de configuração de mapeamento. Esta tag refere -se à especificação de uma classe como a chave primária do composto correspondente. O atributo de nome precisa especificar o valor da propriedade definido no arquivo de classe e adicionar o sub-label <Key-Property> à tag.
Nota: Se você deseja usar mapeamento composto, deve colocar a chave primária composta em uma classe, ou seja, os atributos principais compostos e outros atributos são divididos em duas classes, e a classe primária composta implementa a interface serializável, que pertence a Java.io.
A chave primária da relação de mapeamento da chave primária composta é composta por várias colunas, o que corresponde à tabela de dados bastante simples, como mostrado na figura abaixo:
1. Arquivos de classe
Aqui pegamos a tabela na figura acima como exemplo. Na tabela, dois campos e durações se combinam para formar a chave primária da tabela. Portanto, as novas classes divididas são denominadas fiscais e fiscalyearperiodpk, respectivamente. Entre eles, a classe fiscalyearperiod encapsula os principais atributos da tabela, a classe fiscalyearperiod encapsula outros atributos e a classe fiscalyearperiod.
1.1 Fiscalyearperiod.java
A classe encapsula as propriedades básicas e encapsula a classe fiscalyearperiodpk como atributos na classe e configura o mapeamento correspondente no arquivo de configuração, como segue:
pacote com.src.hibernate; importar java.sql.date; classe pública fiscalyearperiod {// Time Primary Key Private FiscalYearPeriodpk FiscalyearPeriodpk; public fiscalyearperiodpk getFiscalyearPeriodpk () {return fiscalyearperiodpk; } public void setFiscalYearPeriodpk (fiscalyearperiodpk fiscalyearperiodpk) {this.fiscalyearperiodpk = fiscalyearperiodpk; } // A data de início da data privada é iniciada; public date getBegindate () {return begindate; } public void setBegindate (data begindate) {this.begindate = begindate; } // Data de término Data privada ENDDATE; public data getEnddate () {return enddate; } public void setenddate (data enddate) {this.enddate = enddate; } // Período de sequência privada da hora do palco; public string getPeriodsts () {retorno periódicos; } public void SetPeriodsts (String periodsts) {this.periodsts = periodsts; }} 1.2 FiscalyearPeriodpk.java
Encapsular o atributo de chave primária. Esta classe é separada da classe fiscalyearperiod. Ele contém os atributos principais básicos da chave e precisa implementar a interface serializável. Esta classe deve ser mapeada para a tag <composite-id> no arquivo de configuração para especificar a classe. O código é o seguinte:
pacote com.src.hibernate; importar java.io.serializable; classe pública fiscalyearperiodpk implementa serializável {// ano privado int fiscalyear; public int getFiscalYear () {return fiscalyear; } public void setFiscalYear (int fiscalyear) {this.fiscalyear = fiscalyear; } // duração privada int fiscalperiod; public int getFiscalPeriod () {return fiscalperiod; } public void setFiscalPeriod (int fiscalperiod) {this.fiscalPeriod = fiscalperiod; }} 2. Arquivo de configuração
Aqui está uma pergunta qual das duas classes precisa adicionar arquivos de mapeamento? Como a etiqueta <d-id> é usada, você só precisa adicionar um mapeamento para a classe FiscalYearperiod, adicione a etiqueta de chave primária composta correspondente ao arquivo de mapeamento e adicione os atributos de chave primária correspondentes à tag, como segue:
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate tabela = "t_fiscal_year_period_pk"> <composite-id name = "fiscalyearpk"> <key-property name = "fiscalyear"> </key -property> <key-property name = "fiscalperiod"> </key-property> </compósito-id> type = "date"/> <propriedade name = "enddate" type = "date"/> <names name = "periodsts"/> </class> </hibernate-mapping>
O arquivo acima é gerado para gerar a tabela de banco de dados correspondente, e a instrução SQL gerada é a seguinte:
Solte a tabela se existe t_fiscal_year_period_pk Crie tabela t_fiscal_year_period_pk (número inteiro fiscal não nulo, fiscalperiod inteiro não nulo, data de início, data de final, periódicos vare (255), chave primária (fiscalyear, fiscaleri,
A estrutura da tabela correspondente é a seguinte:
3. Operação de dados
Após a configuração do arquivo de mapeamento correspondente, a operação de dados correspondente se torna muito simples. Primeiro, comece com os dados de gravação. Ao escrever dados no banco de dados, duas classes serão gravadas no banco de dados ao mesmo tempo. Portanto, ambas as classes devem ser convertidas em estado transitório. Portanto, ao salvar, você precisa primeiro salvar o objeto FiscalYearPeriod no banco de dados primeiro e, em seguida, ele associará automaticamente os atributos compostos e salvará as informações no banco de dados.
3.1 Operação de gravação
O método de operação de gravação é o mesmo que o método de gravação anterior. Você precisa definir dois objetos e salvar as informações do objeto correspondentes no banco de dados. O código é o seguinte:
public void testSave1 () {// Declare a sessão da sessão sessão de objeto = null; tente {// obtenha o objeto sessão session = hibernateUtils.getSession (); // Abra a sessão session.begintransaction (); // Crie o objeto composto fiscalyearperiodpk fiscalyearperiodpk = new fiscalYearPeriodpk (); fiscalyearperiodpk.setFiscalPeriod (2014); FiscalYearPeriodpk.setFiscalYearyear (2012); // crie o objeto fiscalyearperiod fiscalyearperiod = new fiscalyearperiod (); fiscalyearperiod.setFiscalyearPeriodpk (fiscalyearperiodpk); session.Save (FiscalYearperiod); // Envie sessão session session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}Execute o método de teste correspondente e a instrução SQL gerada é a seguinte:
Hibernate: insert into t_fiscal_year_period_pk (beginDate, endDate, periodSts, fiscalYear, fiscalPeriod) values (?, ?, ?, ?, ?) A exibição de banco de dados correspondente:
3.2 Operação de carregamento
O método de carregamento correspondente será diferente de antes, porque a chave primária da tabela é uma propriedade composta, portanto, uma classe precisa ser criada. Ao carregar dados, você precisa criar um objeto de chave primária. No momento, a chave primária é um objeto e você precisa atribuir valores às propriedades do objeto para obter o objeto. O código é o seguinte:
public void testLoad1 () {// Declare a sessão da sessão sessão de objeto = null; tente {// obtenha o objeto sessão session = hibernateUtils.getSession (); // Abra a sessão session.begintransaction (); // Crie o objeto composto fiscalyearperiodpk fiscalyearperiodpk = new fiscalYearPeriodpk (); fiscalyearperiodpk.setFiscalPeriod (2014); FiscalYearPeriodpk.setFiscalYear (2012); Fiscalyearperiod fiscalyearperiod = (fiscalyearperiod) session.load (fiscalyearperiod.class, fiscalyearperiodpk); System.out.println ("Data de início:"+fiscalyearperiod.getBegindate ()); // envia sessão session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}O resultado é o seguinte:
Hibernato: selecione fiscalyear0_.fiscalYear como fiscalyear0_0_, fiscalyear0_.fiscalperiod como fiscalpe2_0_0_, fiscalyear0_.begindate como BEGINDATE0_0_, fiscisfis. periodsts0_0_ de t_fiscal_year_period_pk fiscalyear0_ onde fiscalyear0_.fiscalyear =? e fiscalyear0_.fiscalperiod =? Data de início: 2013-10-12
4. Exemplos abrangentes
Uma tabela de departamento de uma empresa maior (Hibernate_Dept_ComposePepk) consiste em campos como a área (área), nome do departamento (nome), número de pessoas no departamento (Empcount) e tempo de estabelecimento (aniversário). Usamos a área e o nome do departamento como a chave primária conjunta:
4.1 Classe de destino: departamento.java
Departamento de classe pública { /** Resumo O atributo principal da associação chave e escreva -o em uma classe separadamente* /// área de sequência privada; // nome de string privado; / ** Preparando o objeto de classe chave primária como uma variável de membro*/ departamento privado departamentopk; private int empcount; aniversário privado; // public string getarea () {// área de retorno; //} // // public void setarea (área de string) {// this.area = área; //} // // public String getName () {// Return Name; //} // // public void setName (nome da string) {// this.name = name; //} public int getEmpCount () {return EmpCount; } public void setempCount (int empCount) {this.empCount = empacount; } public data getBirthday () {return Birthday; } public void setbirthday (data de aniversário) {this.birthday = aniversário; } public DepartmentPK getDepartmentpk () {return DepartmentPK; } public void setDepartmentpk (departamentopk departamentopk) {this.departmentpk = departamentopk; }} 4.2 Classe Primária Chave: departamentopk.java
Public Class DepartmentPK implementa serializável {private estático final serialversionuid = -288002855915204255L; área de cordas privadas; nome de string privado; /** * Substituir o método HashCode (julgado com base na área e nome) *///@substituir public int hashCode () {final int prime = 31; int resultado = 1; resultado = prime * resultado + ((área == null)? 0: are.hashcode ()); resultado = prime * resultado + ((nome == null)? 0: name.hashcode ()); resultado de retorno; } / ** * Substitua é igual (julgado com base na área e nome) * / @Override public boolean é igual (object obj) {if (this == obj) retorna true; if (obj == null) retorna false; if (getClass ()! = obj.getclass ()) retornar false; Departamento final de outros = (departamentopk) obj; if (área == null) {if (outros.area! = null) retorna false; } else if (! Area.equals (outros.area)) retornar false; if (nome == null) {if (outro.name! = null) retorna false; } else if (! name.equals (outro.name)) retornar false; retornar true; } public string getarea () {Return Area; } public void setarea (área da string) {this.area = área; } public string getName () {return name; } public void setName (nome da string) {this.name = name; }} 4.3 Mapping File Department.hbm.xml
<? Xml versão = "1.0"?> <! name = "com.yangfei.hibernate.comPostepk.entity.Department" table = "hibernate_dept_composepkk"> <!-union key primário-> <!-nome refere-se aos principais atributos do objeto-chave "TEY-TECK-ETET-ETET-ETYTE" NOMET-ETEMPOPT (NOME) <! /> < /composto-id> <!-Outras propriedades-> <propriedade name = "empacount" length = "4" /> <names name = "aniversário" type = "date" /> < /class> < /hibernate-mapping>
4.4 Arquivo de configuração de hibernato hibernate.cfg.xml
<? xml versão = '1.0' Encoding = 'utf-8'?> <! Ferramentas. -> <Hibernate-configuration> <Session-Factory> <propriedade name = "dialect"> org.hibernate.dialect.oracle9Dialect </Property> <propriedades name = "Connection.url"> jdbc: oracle: thin:@127.0.1: 1521: scopt </propriedade </propriedades> <nome da propriedade </propriedades: " name = "Connection.Password"> yf123 </propriedade> <propriedade name = "Connection.driver_class"> oracle.jdbc.driver.oracledriver </propriedade> <names name = "hibernate.show_sql"> true </silper </session-factory> </hibernate-configuration>
4.5 Classe de teste: departamentoTest.java
classe pública departamentoTest estende o teste { / *** Teste Dados* / public void save () {sessão session = hibernateUtils.getSession (); Transação t = session.begIntransaction (); tente {Departamento Departamento = New Department (); / ** Gere objeto de chave primária*/ departamentopk Deptpk = new DepartmentPk (); Deptpk.setarea ("Pequim"); Deptpk.setName ("Departamento de R&D"); Dept.setDepartmentPK (Deptpk); Dept.setempcount (100); Dept.setBirthday (new Date ()); session.Save (Departamento); t.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } finalmente {hibernateutils.closhessession (sessão); }} / *** Dados de carga de teste* / public void load () {sessão session = hibernateUtils.getSession (); Transação t = session.begIntransaction (); tente { / ** gerar objeto de chave primária* / departamentopk Deptpk = new DepartmentPk (); Deptpk.setarea ("Pequim"); Deptpk.setName ("Departamento de R&D"); Departamento de departamento = (departamento) session.load (departamento.class, deptpk); System.out.println (Dept.getDepartmentpk (). Getarea ()+","+Dept.getDepartmentpk (). GetName ()+","+Dept.getempcount ()+","+Dept.getBirthday ()); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } finalmente {hibernateutils.closhessession (sessão); }} / *** Dados de modificação de teste* / public void update () {sessão session = hibernateUtils.getSession (); Transação t = session.begIntransaction (); tente { / ** gerar objeto de chave primária* / departamentopk Deptpk = new DepartmentPk (); Deptpk.setarea ("Pequim"); Deptpk.setName ("Departamento de R&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); / ** Gere o objeto de chave primária*/ departamentopk deptpk2 = new DepartmentPK (); Deptpk2.setarea ("Pequim"); Deptpk2.SetName ("Departamento de R&D"); Departamento de departamento = (departamento) session.load (departamento.class, deptpk2); System.out.println (Dept.getDepartmentpk (). Getarea ()+","+Dept.getDepartmentpk (). GetName ()+","+Dept.getempcount ()+","+Dept.getBirthday ()); t.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } finalmente {hibernateutils.closhessession (sessão); }} / *** Teste Excluir dados* / public void delete () {sessão session = hibernateUtils.getSession (); Transação t = session.begIntransaction (); tente { / ** gerar objeto de chave primária* / departamentopk Deptpk = new DepartmentPk (); Deptpk.setarea ("Pequim"); Deptpk.setName ("Departamento de R&D"); Departamento de departamento = (departamento) session.load (departamento.class, deptpk); session.Delete (Departamento); t.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } finalmente {hibernateutils.closhessession (sessão); }}}