您的位置:首页 > 其它

Hibernate实体关系映射:单向主键一对一关联

2015-12-12 16:38 633 查看
主键单向一对一关联:

1、被控方的主键参照主控方的主键来生成

2、对应数据库表关系为被控方的主键同时参照引用主控方的主键

3、保存被控方对象,需要先保存主控方(不然怎么从native产生主键值,被控方更是获取不到了)

主控方People

public class People  implements java.io.Serializable {

// Fields

private long id;
private String name;
private long age;
private String sex;

// Constructors

/** default constructor */
public People() {
}

// Property accessors

public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public long getAge() {
return this.age;
}

public void setAge(long age) {
this.age = age;
}

public String getSex() {
return this.sex;
}

public void setSex(String sex) {
this.sex = sex;
}

}


People的hbm.xml文件:只是普通的映射文件

<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>
</class>
</hibernate-mapping>


从控方IdCard的实体类:

public class IdCard  implements java.io.Serializable {

// Fields

private long id;
private People people;  <span style="color:#ff0000;">//这里加上主控方People类型的属性</span>
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;
}


IdCard的hbm.xml文件:负责维护关系

<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">      <!--<span style="color:#ff0000;">从控方的主键生成策略是 foreign 的方式,这里的param属性是它自己对应的属性名</span>-->
<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>  </span>
<span style="font-size:14px;"><span style="white-space:pre">	</span><!--<span style="color:#ff0000;">这里需要one-to-one进行映射,后面的constrained 后面详解,主要影响save、delete的先后顺序而已,详情看这里</span>-->
</class>
</hibernate-mapping>


二、测试增删改查
(1)查询

//从控方idcard查询操作
public void testidcard(){

Session session=null;
try{
session=HibernateUtil.getSession();
IdCard idcard=(IdCard)session.get(IdCard.class, new Long("48"));  
</pre><pre name="code" class="java">                                             //获取IdCard中Id是48的对象,并进而通过一对一的映射关系获取其对应的people的值
System.out.println(idcard.getId()+" "+idcard.getNumcode());
System.out.println(idcard.getPeople().getId()+" "+idcard.getPeople().getName()+" "+idcard.getPeople().getAge());

}catch (Exception e) {

e.printStackTrace();

}finally{
HibernateUtil.closeSession();
}
}


输出效果:

Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=?
48 3203203201
Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=?
48 张三 20


注:如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。

发放

(2)添加

public void testSaveIdCard(){

Session session=null;
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();

People people=new People();
people.setName("张三");
people.setAge(20);
people.setSex("M");    //主控方的对象

//session.save(people);

IdCard idcard=new IdCard();
idcard.setNumcode("3203203201");
idcard.setPeople(people);
session.save(idcard);   //constrained为true,则在插入从控方对象前,需要创建一个主控方People的对象,并set给从控方的IdCard对象;保存时只需要保存从控方的对象就行,一次保存2个对象。

session.getTransaction().commit();

}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();

}finally{
HibernateUtil.closeSession();
}
}


运行结果:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into SXBBKF.J_PEOPLE (NAME, AGE, SEX, ID) values (?, ?, ?, ?)
Hibernate: insert into SXBBKF.J_IDCARD (NUMCODE, ID) values (?, ?)


(3)删除

①删从控方

//删除 从控方 idcard
public void testRemoveIdCard(){

Session session=null;
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();

/*People people=new People();
people.setName("张三");
people.setAge(20);
people.setSex("M");*/

//session.save(people);

IdCard idcard=(IdCard)session.get(IdCard.class, new Long("48"));

session.delete(idcard);

session.getTransaction().commit();

}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();

}finally{
HibernateUtil.closeSession();
}
}


运行结果:

Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=?
Hibernate: delete from SXBBKF.J_IDCARD where ID=?


显然,它只删除了从控方的对象,并没有自动关联删除主控方的对象

②删主控方

//删除 主控方 people
public void testRemovepeople(){

Session session=null;
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();
People people=(People)session.get(People.class, new Long("49"));

session.delete(people);

session.getTransaction().commit();

}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();

}finally{
HibernateUtil.closeSession();
}
}


运行结果:
Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=?
Hibernate: delete from SXBBKF.J_PEOPLE where ID=?
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

Caused by: java.sql.BatchUpdateException: ORA-02292: 违反完整约束条件 (SXBBKF.FK28F66C40613448E8) - 已找到子记录


很显然,直接删除主控方,被控方没有了外键约束关系,这是潍坊约束条件的,所以无法这样删除

③手动先删被控方,再删主控方

public void removeAll(){
testRemoveIdCard();
testRemovepeople();
}


就是上面两个方法调用一起意思

运行结果:

Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=?
Hibernate: delete from SXBBKF.J_IDCARD where ID=?
Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=?
Hibernate: delete from SXBBKF.J_PEOPLE where ID=?


这样必须四条语句了呀,没有疑问的

四、修改

//修改 从控方 idcard
public void testModifyIdCard(){

Session session=null;
try{
session=HibernateUtil.getSession();
session.getTransaction().begin();

IdCard idcard=(IdCard)session.get(IdCard.class, new Long("47"));

idcard.setNumcode("3203203201010101");
session.update(idcard);      //取出记录,重新赋值后update一下就行,没有关联约束关系

session.getTransaction().commit();

}catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();

}finally{
HibernateUtil.closeSession();
}
}


运行结果:

Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=?
Hibernate: update SXBBKF.J_IDCARD set NUMCODE=? where ID=?


综上,单向主键一对一映射关系:从控方的实体类和hbm文件需要负责维护关系,主控方不用;constrained属性会影响save操作和删除操作:save是先主控后从控,delete是先从控后主控。

另:这篇博文用相反的思路,可以参考:/article/1356673.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: