这是上篇:Hibernate实体关系映射:单向主键一对一关联
现在探讨下下篇双向主键一对一关联
被控方和单向主键一对一映射一样,主控方需要在实体类和hbm.xml文件添加关联
实体类:
IdCard实体类:
<span style="font-size:14px;">public class IdCard implements java.io.Serializable {
// Fields
private long id;
private People people;
private String numcode;
// Constructors
/** default constructor */
public IdCard() {
}
// Property accessors
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public People getPeople() {
return this.people;
}
public void setPeople(People people) {
this.people = people;
}
public String getNumcode() {
return this.numcode;
}
public void setNumcode(String numcode) {
this.numcode = numcode;
}
}</span>
People实体类:
<span style="font-size:14px;">public class People implements java.io.Serializable {
// Fields
private long id;
private String name;
private long age;
private String sex;
private IdCard idCard; //新增了被控方的对象,用于关联
// Constructors
/** default constructor */
public People() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getAge() {
return age;
}
public void setAge(long age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public IdCard getIdCard() {
return idCard;
}
public void setIdCard(IdCard idCard) {
this.idCard = idCard;
}
}</span>
映射文件:
IdCard的hbm.xml文件:
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.sjr.bean.IdCard" table="J_IDCARD" schema="SXBBKF">
<id name="id" type="long">
<column name="ID" precision="10" scale="0" />
<generator class="foreign">
<param name="property">people</param>
</generator>
</id>
<property name="numcode" type="string">
<column name="NUMCODE" length="20" />
</property>
<one-to-one name="people" class="com.sjr.bean.People" constrained="true"></one-to-one>
<!-- 这里的constrained 可以约束数据库表间外键关系 -->
</class>
</hibernate-mapping></span>
People的hbm.xml文件:
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.sjr.bean.People" table="J_PEOPLE" schema="SXBBKF">
<id name="id" type="long">
<column name="ID" precision="10" scale="0" />
<generator class="native">
</generator>
</id>
<property name="name" type="string">
<column name="NAME" length="20" />
</property>
<property name="age" type="long">
<column name="AGE" precision="10" scale="0" />
</property>
<property name="sex" type="string">
<column name="SEX" length="2" />
</property>
<one-to-one name="idCard" class="com.sjr.bean.IdCard" cascade="delete"></one-to-one>
<!-- 这里的cascade属性用于指示主控方的什么操作会级联作用到被控方上 all,non,save-update,delete -->
</class>
</hibernate-mapping></span>
比之前多一句<one-to-one>的配置即可,关系的维护依旧由被控方IdCard承担。
下面进行基本操作:
查询:
<span style="font-size:14px;">public void testPeopleSelect(){
//主控方 单向一对一映射
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();
People people=(People)session.get(People.class, new Long(67));
System.out.println(people.getId()+" "+people.getAge()+" "+people.getName());
//主控方插入后,在主控方读取时候进行判断
if(people.getIdCard()!=null){
System.out.println(people.getIdCard().getId()+" "+people.getIdCard().getNumcode());
}
}catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}</span>
结果:
<span style="font-size:14px;">Hibernate: select people0_.ID as ID1_1_, people0_.NAME as NAME1_1_, people0_.AGE as AGE1_1_, people0_.SEX as SEX1_1_, idcard1_.ID as ID0_0_, idcard1_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_PEOPLE people0_ left outer join SXBBKF.J_IDCARD idcard1_ on people 0_.ID=idcard1_.ID where people0_.ID=?
67 19 李四一 </span>
因为cascade=“delete”,所以插入主控方对象时,被控方不一定有对象,因此在输出被控方前进行一下判断
查询OK
增加:
<span style="font-size:14px;">public void testPeopleAdd(){
People people =new People();
people.setAge(18);
people.setName("李四一 ");
people.setSex("男");
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();
session.save(people);
session.getTransaction().commit();
}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}</span>
结果:
<span style="font-size:14px;">Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into SXBBKF.J_PEOPLE (NAME, AGE, SEX, ID) values (?, ?, ?, ?)</span>
插入操作,只针对People这个主控方类插入对象即可(因为cascade为delete)
修改:
<span style="font-size:14px;">public void testPeopleModify(){
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();
People people=(People)session.load(People.class, new Long(67));
people.setAge(19);
session.save(people);
session.getTransaction().commit();
}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}</span>
结果:
<span style="font-size:14px;">Hibernate: select people0_.ID as ID1_1_, people0_.NAME as NAME1_1_, people0_.AGE as AGE1_1_, people0_.SEX as SEX1_1_, idcard1_.ID as ID0_0_, idcard1_.NUMC ODE as NUMCODE0_0_ from SXBBKF.J_PEOPLE people0_ left outer join SXBBKF.J_IDCARD idcard1_ on people0_.ID=idcard1_.ID where people0_.ID=?</span>
修改起来也很简单,主键ID没变,只需要正常修改即可。(这里是左外链接,还有其他的可能性)
删除:
<span style="font-size:14px;">public void testRemove(){
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();
People people =(People)session.get(People.class, new Long(53));
session.delete(people);
session.getTransaction().commit();
}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}</span>
删除结果:
<span style="font-size:14px;">Hibernate: select people0_.ID as ID1_1_, people0_.NAME as NAME1_1_, people0_.AGE as AGE1_1_, people0_.SEX as SEX1_1_, idcard1_.ID as ID0_0_, idcard1_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_PEOPLE people0_ left outer join SXBBKF.J_IDCARD idcard1_ on people 0_.ID=idcard1_.ID where people0_.ID=?
Hibernate: delete from SXBBKF.J_IDCARD where ID=?
Hibernate: delete from SXBBKF.J_PEOPLE where ID=?</span>
综述:
对于cascade=“delete”的情况,主控方只有删除时候会级联,其他操作正常处理
被控方和之前一样,插入、删除时候要多步骤