hibernate 学习之第六篇

news/2025/2/24 7:54:38

基于主键的一对一关联

Person类和IdCard,一对一映射。
person的属性为:id,name,idCard
IdCard的属性为:id,usefulLife,person

由于身份证和人是一对一的,身份证的id和人的id可以相同。可以使得idcard的id的产生与person保持一致。主从对象通过主键关联起来。

类Person:

public class Person {
private int id;
private String name;
private IdCard idCard;
    public int getId() {
        return id;
    }

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

    public IdCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IdCard idCard) {
        this.idCard = idCard;
    }

    public String getName() {
        return name;
    }

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

}

 

类IdCard:

public class IdCard {
private int id;
private Date usefulLife;
private Person person;
    public int getId() {
        return id;
    }

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

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Date getUsefulLife() {
        return usefulLife;
    }

    public void setUsefulLife(Date usefulLife) {
        this.usefulLife = usefulLife;
    }

}

 

映射文件person.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 package="hibernatetest01">
    <class name="Person" table="t_person">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="name"></property>
       <one-to-one name="idCard"/>   //person和idcard是一对一映射
    </class>
</hibernate-mapping>

 

映射文件idcard.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 package="hibernatetest01">
    <class name="IdCard" table="t_idcard">
        <id name="id" >
            <generator class="foreign">    
                <param name="property">person</param>
            </generator>
        </id>
        <property name="usefulLife"></property>
       <one-to-one name="person"  constrained="true"/> //加上约束,保证了person必须有idcard与之对应,未加时,保存person可以没有idcard
    </class>
</hibernate-mapping>

 

注: 采用外键产生方式,该类有一个属性参数,需要在配置文件中指定给他,他需要知道利用什么来产生idcard的主键。在此指定person,与下面的 <one-to-one name="person"/>对应。

测试类:

public class Main {
    public static void main(String[] args){
    add();
    }

    static Person add(){
        IdCard idCard = new IdCard();
        idCard.setUsefulLife(new Date());
        Person  p = new Person();
        p.setName("jianchen");
        p.setIdCard(idCard);
        idCard.setPerson(p);
        Session s = null;
        Transaction tx = null;
        s = HibernateUtil.getSession();
        tx = s.beginTransaction();
        s.save(p);
         s.save(idCard);
        tx.commit();
       return p;
    }
}

 


一对一主键关联关系的检索:

 static void query(int id){
     Session s = HibernateUtil.getSession();
     Transaction tx = s.beginTransaction();
     Person p = (Person)s.get(Person.class, id);
     System.out.println(p.getIdCard().getUsefulLife());
     tx.commit();
    }

 


在主函数中调用query(1),person和idcard是主从关系。对主类进行查询,会把从类也查询出来,体现在查询使用左外连接,一次性的查询。

Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?
2009-02-04 15:51:20.0

 

就是把打印的那句话注释掉,同样会一次性的查出主从类 。查询语句如下:

 

Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?

 

如果是查询从类,

static void query(int id){
     Session s = HibernateUtil.getSession();
     Transaction tx = s.beginTransaction();
     IdCard idCard =(IdCard) s.get(IdCard.class, id);
     System.out.println(idCard.getPerson().getName());
     tx.commit();
    }
 


对从类进行查询只会查询出从类的信息,主类被懒加载。从查询语句上看,以上代码执行了两次查询。

Hibernate: select idcard0_.id as id2_0_, idcard0_.usefulLife as usefulLife2_0_ from t_idcard idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id1_1_, person0_.name as name1_1_, idcard1_.id as id2_0_, idcard1_.usefulLife as usefulLife2_0_ from t_person person0_ left outer join t_idcard idcard1_ on person0_.id=idcard1_.id where person0_.id=?
jianchen
 

把后面的打印语句删掉,就只会执行上面的一次查询。

Hibernate: select idcard0_.id as id2_0_, idcard0_.usefulLife as usefulLife2_0_ from t_idcard idcard0_ where idcard0_.id=?

 


使用lazy属性:
修改映射文件:

<hibernate-mapping package="hibernatetest01">
    <class name="IdCard" table="t_idcard">
        <id name="id" >
            <generator class="foreign">    
                <param name="property">person</param>
            </generator>
        </id>
        <property name="usefulLife"></property>
       <one-to-one name="person"  constrained="true" lazy="false"/> //加上约束,保证了person必须有idcard与之对应,未加时,保存person可以没有idcard
    </class>
</hibernate-mapping>

 

分析:
lazy=”false“表明对person不进行懒加载。这样就会导致在查询从类时也会把主类进行加载。
lazy在hibernate 3.0之前只有两个值:true ,false
3.0后lazy有三个值:true,false,proxy。其中proxy是默认的方式,采用代理实现懒加载。


在以上基础上进行进一步的修改:
 <one-to-one name="person"  constrained="true" lazy="true" fetch="select" />
虽然配置为懒加载,但由于设置了抓取为select ,就是说在抓取idcard时,也会抓取person。这也会导致在加载从对象时即时的加载主对象。

由此可见,hibernate中的属性配置是互相制约和影响的。hibernate的难点也在此。

基于外键的一对一关联

可以描述为多对一,加uniquer=“ture”,就变为一对一关联了
对象模型不需要改变,对映射文件进行修改。
person.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 package="hibernatetest01">
    <class name="Person" table="t_person">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="name"></property>
       <one-to-one name="idCard" property-ref="person"/>   //person通过idcard的属性person来查找属于自己的idcard
    </class>
</hibernate-mapping>
 


注:  property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。

idcard.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 package="hibernatetest01">
    <class name="IdCard" table="t_idcard">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="usefulLife"></property>
       <many-to-one name="person"  column="person_id" unique="true"/>
    </class>
</hibernate-mapping>

 

表结构为:


从这个表结构上看,person和idcard是一对多的关系,因为idcard表有一个外键指向person表。但是在idcard的映射文件中,把外键强制设定为唯一,这样就构成了一对一映射。
  <many-to-one name="person"  column="person_id" unique="true"/>


http://www.niftyadmin.cn/n/2864068.html

相关文章

hibernat学习之第七篇

多对多关联关系的映射 在操作和性能方面都不太理想&#xff0c;所以多对多的映射使用较少&#xff0c;实际使用中最好转换成一对多的对象模型&#xff1b;hibernate会为我们创建中间关联表&#xff0c;转换成两个一对多。 核心配置&#xff1a; <set name"ss" t…

Redis——基于主从复制实现高可用(redis-sentinel)

一.sentinel哨兵模式介绍 Sentinel(哨兵)是用于监控redis集群中Master状态的工具&#xff0c;是Redis 的高可用性解决方案&#xff0c;sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel是redis高可用的解决方案&#xff0c;sentinel系统可以监视一个或者多个redis …

hibernate学习之第八篇

组件映射 关联的属性是个复杂类型的持久化类&#xff0c;但不是实体即&#xff1a;数据库中没有表与该属性对应&#xff0c;但该类的属性要持久保存的。 对于单表的对象细分&#xff0c;在hibernate中可借助Component节点的定义完成。 何谓Component&#xff1f;从名字上来看&…

hibernate学习之第九篇

hibernate中的集合类型 引入&#xff1a; Hibernate可以持久化以下java集合的实例, 包括java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, 和任何持久实体或值的数组。类型为java.util.Collection或者java.util.List的属性还可以使用…

Redis——集群方案之redis cluster的搭建部署

一.redis的集群之redis cluster的概念 对于Redis集群方案有好多种&#xff0c;基本常用的就是twemproxy&#xff0c;codis&#xff0c;redis cluster这三种解决方案。 本文介绍redis cluster。 上篇博文实现redis的高可用&#xff0c;针对的主要是master宕机的情况&#xff…

hibernate学习之第十篇

级联和关系维护 Cascade 用来说明当对主对象进行某种操作时&#xff0c;是否对其关联的从对象也作类似的操作&#xff0c;常用的cascade&#xff1a;none,all,save-update,delete,lock,refresh,evict,replicate,persist,merge,delete-orphan(one-to-many).一般对many-to-many&…

Redis——基于lamp架构做mysql的缓存服务器和配置gearman实现数据同步

一.前言 对一个关系型数据库进行调优以获得高查询性能可能会比较困难。如果对数据模型优化和对查询调优不起作用&#xff0c;DBA就可以使用缓存系统&#xff0c;比如Redis&#xff0c;它是一个可以提供内存和永久数据存储的键值数据存储系统。 由于Redis能够将数据快速读写至…

hibernate学习之第十一篇(1)

hibernate的继承映射 《一》一张表映射一棵继承树 使用discriminator&#xff08;鉴别标志&#xff09; 类Worker和Farmer都继承自Person 类Person的源代码如下&#xff1a; package hibernate.extend; public class Person { private int id; private String name; private…