hibernate一对一主键关联
一对一主键关联指的是两个表通过主键形成的一对一映射。
数据表要求:A表的主键也是B表的主键同时B表的主键也是A表的外键
sql:
create table people( id int primary key auto_increment, name varchar(100) not null, sex varchar(100) not null, age int ) create table idcard( id int primary key, idcard_code varchar(50) not null, FOREIGN KEY(id) REFERENCES people(id) )
单向主键关联映射:
package com.demo.hibernate.beans; public class IDcard { private int id; private String idcard_code; private People people; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getIdcard_code() { return idcard_code; } public void setIdcard_code(String idcardCode) { idcard_code = idcardCode; } public People getPeople() { return people; } public void setPeople(People people) { this.people = people; } public IDcard(int id, String idcardCode, People people) { super(); this.id = id; idcard_code = idcardCode; this.people = people; } public IDcard(){} }
package com.demo.hibernate.beans; public class People { private int id; private String name; private String sex; private int age; //private IDcard idcard; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } /*public IDcard getIdcard() { return idcard; } public void setIdcard(IDcard idcard) { this.idcard = idcard; }*/ public People(int id, String name, String sex, int age) { super(); this.id = id; this.name = name; this.sex = sex; this.age = age; } public People(){} }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.demo.hibernate.beans.User" table="USER"> <id name="id" type="int"> <column name="id"></column><!-- 注意column要放在前面 --> <generator class="foreign"> <param name="property">people</param> </generator> </id> <property name="idcard_code" type="string" column="IDCARD_CODE"/> <one-to-one name="prople" class="com.demo.hibernate.beans.People" property-ref="IDcard" cascade="all"></one-to-one><!--这里要选定好级联操作cascade属性不然可能不会级联持久化类的另一个表--> </class> </hibernate-mapping>
test:
import com.demo.hibernate.beans.IDcard; import com.demo.hibernate.beans.People; import com.demo.hibernate.dao.IDcardDAO; import com.demo.hibernate.dao.PeopleDAO; public class IDcardService { public static void main(String[] args){ PeopleDAO pdao=new PeopleDAO(); IDcardDAO iddao=new IDcardDAO(); IDcard idcard=new IDcard(); idcard.setIdcard_code("362421199610126814"); People people=new People(); people.setName("guo"); people.setAge(21); people.setSex("男"); idcard.setPeople(people); iddao.addIDcard(idcard); } }
结果:
双向多对一:
前面单向的配置不变,在原来的People基础上加上对应的IDcard对象以及修改People.hbm.xml
People.java---->把前面的注释去掉
People.hbm.xml---->
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.demo.hibernate.beans.People" table="PEOPLE"> <id name="id" type="int"> <column name="id"></column><!-- 注意column要放在前面 --> <generator class="native"></generator> </id> <property name="name" type="string" column="NAME"/> <property name="sex" type="string" column="SEX"/> <property name="age" type="int" column="AGE"/> <one-to-one name="idcard" class="com.demo.hibernate.beans.IDcard" property-ref="people" cascade="all"></one-to-one> </class> </hibernate-mapping>
Test:
public static void main(String[] args){ PeopleDAO dao=new PeopleDAO(); People people=new People(); people.setName("guon"); people.setAge(28); people.setSex("女"); IDcard card=new IDcard(); card.setIdcard_code("362421199610116734"); people.setIdcard(card); card.setPeople(people); dao.addPeople(people); }
注意双向与单向的test页面有区别的,在于People和IDcard对象里面都含有对方的对象,必须全部添加进入,否则会报错误,错误是关于主键的类型与策略不符合。
结果:
一对一外键关联:
单向(特殊的many-to-one,在many-to-one上加上unique=“true”):
create table person( id int primary key auto_increment, name varchar(100), age int, addressid int unique ) create table address( id int primary key auto_increment, detail varchar(100) ) alter table person add constraint fk_per_add foreign key (addressid) references address (id);
package com.entity; public class Person { private int id; private String name; private int age; private Address address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Person(){} }
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.entity.Person" table="PERSON"> <id name="id" type="int"> <column name="id"></column> <generator class="identity"></generator> </id> <property name="name" type="string"> <column name="NAME"></column> </property> <property name="age" type="int"> <column name="AGE"></column> </property> <many-to-one name="address" class="com.entity.Address" unique="true" cascade="all"> <column name="addressid"></column> </many-to-one> </class> </hibernate-mapping>
注意在多对一里面也要加上cascade="all"这种条件,当然可能值不是all
关于address的话就是普通的持久化类和映射文件
双向(前面与单向相同,附表采用one-to-one配置):
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.entity.Address" table="ADDRESS"> <id name="id" type="int"> <column name="id"></column> <generator class="identity"></generator> </id> <property name="detail" type="string"> <column name="detail"></column> </property> <one-to-one name="person" class="com.entity.Person" cascade="all" property-ref="address"> </one-to-one> </class> </hibernate-mapping>
package com.entity; public class Address { private int id; private String detail; private Person person; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public Address(){} public void setPerson(Person person) { this.person = person; } public Person getPerson() { return person; } }
package com.server; import com.dao.AddressDAO; import com.entity.Address; import com.entity.Person; public class Test { public static void main(String[] args){ AddressDAO addressdao=new AddressDAO(); Address address=new Address(); address.setDetail("江西生物科技职业学院!"); Person p=new Person(); p.setName("guozhen"); p.setAge(21); p.setAddress(address); address.setPerson(p); addressdao.addAddress(address); } }
注意:在one-to-one中写上property-ref=“” 属性为另一持久化了类的相关联的属性名