Hiberante(六) OneToOne_xml 单向和双向关联
程序员文章站
2022-04-22 16:10:57
...
OneToOne 单向(随便在那一方加关联)
实体类:
Person.java
public class Person {
private int id;
private String name;
private IDCard idcard;
省略get,set
}
IDCard.java
public class IDCard {
private int id;
private String no;
省略get,set
}
hbm文件
person.hbm.xml
<hibernate-mapping package="org.th.model">
<class name="Person" table="t_person" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
</class>
</hibernate-mapping>
IDCard.hbm.xml
<hibernate-mapping package="org.th.model">
<class name="IDCard" table="t_idcard" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="no"></property>
<!-- oneToOne和oneToMany类似,只需要加一个unique="true" 表示一一对应 -->
<many-to-one name="person" column="pid" unique="true"></many-to-one>
</class>
</hibernate-mapping>
OneToOne 双向关联(与上面的区别在于)
public class IDCard {
private int id;
private String no;
private Person person;//加一个person属性
省略get,set
}
<hibernate-mapping package="org.th.model">
<class name="Person" table="t_person" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<!--name是属性名称,property-ref表示由对方的属性来维护关系 -->
<one-to-one name="idcard" property-ref="person" ></one-to-one>
</class>
</hibernate-mapping>
测试方法:
@Test
public void testAdd01() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Person person = new Person();
person.setName("老张");
session.save(person);
IDCard idcard = new IDCard();
idcard.setNo("999");
idcard.setPerson(person);
session.save(idcard);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
@Test
public void testAdd02() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Person person = (Person) session.load(Person.class, 1);
// ConstraintViolationException: Duplicate entry '1' for key 2
// Many-to-one 当使用了unique=true,就会保证每一个person只能对应一个idcard
IDCard idcard = new IDCard();
idcard.setNo("111");
idcard.setPerson(person); //此时的person已经对应了idcard
session.save(idcard);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
/**
*
* @Title: testAdd03
* @Description: oneToOne 双向关联
* @param
* @return void 返回类型
* @throws
*/
@Test
public void testAdd03() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
@Test
public void testAdd03() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
/*
* 此时,由于使用的是IDCard来维护关系(外键在哪一端就由哪一段来维护)
* 通过p.setIdCard就无效,所以关系不会更新
*/
IDCard id = new IDCard();
id.setNo("123");
session.save(id);
Person p = new Person();
p.setName("zzz");
p.setIdcard(id);
session.save(p);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally {
HibernateUtil.close(session);
}
}
@Test
public void testAdd04() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Person p = new Person();
p.setName("zzzzz");
session.save(p);
IDCard id = new IDCard();
id.setNo("12322");
id.setPerson(p);
session.save(id);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally {
HibernateUtil.close(session);
}
}
@Test public void testLoad01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Person p = (Person) session.load(Person.class, 4); // 只要取出的是没有维护关系的这一方,会自动将关联对象取出,会发出1条sql // 由于person端没有维护关系,所以不会进行延迟加载,所以1条就搞定了 System.out.println(p.getName() + "," + p.getIdcard().getNo()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testLoad02() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); // 特别注意:如果没有双向,此时会发出2条,一条去idCard,一条延迟加载取person // 有双向关联,此时会发出三条SQL语句 IDCard id = (IDCard) session.load(IDCard.class, 4); // 此时没有使用idCard的Person,会延迟加载,目前只是发出1条SQL System.out.println(id.getNo());
// 要去取person同时也会取出这个person的idCard,这里就不会使用join来取出,所以会发出2条sql System.out.println(id.getPerson().getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } /** * 最佳实践就是,One2One的时候最好不要使用双向关联,如果使用双向关联,尽可能在没有维护关系的一边取数据 * hibernate会自动完成join,仅仅只会发一条sql,如果使用维护关系端取数据,在通过延迟加载取关联对象时 * 会同时再去取person的idCard关联,所以会发3条 */
上一篇: 前端开发软件
下一篇: 前端工程师的进阶之路