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”):

hibernate一对一关联_xmlhibernate一对一关联_一对一_02
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);
SQL
hibernate一对一关联_xmlhibernate一对一关联_一对一_02
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(){}
    

}
Person.java
hibernate一对一关联_xmlhibernate一对一关联_一对一_02
<?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>
View Code

注意在多对一里面也要加上cascade="all"这种条件,当然可能值不是all

关于address的话就是普通的持久化类和映射文件

 

双向(前面与单向相同,附表采用one-to-one配置):

hibernate一对一关联_xmlhibernate一对一关联_一对一_02
<?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>
Address.hbm.xml
hibernate一对一关联_xmlhibernate一对一关联_一对一_02
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;
    }

}
View Code
hibernate一对一关联_xmlhibernate一对一关联_一对一_02
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);
    }

}
Test

注意:在one-to-one中写上property-ref=“” 属性为另一持久化了类的相关联的属性名