您的位置:首页 > 其它

Hibernate单边的一对多关系

2015-08-18 15:08 330 查看
单边的一对多关系是指一方有集合属性,包含多个多方,而多方没有一方的引用。

例如用户和邮箱就是典型的单边的一对多关系,一个用户可以有多个邮箱,但一个邮箱,肯定只属于某个用户。

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="connection.pool_size">1</property>
        <!-- DB schema will be updated if needed -->
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <mapping resource="org/hibernate/tutorial/domain/Email.hbm.xml"/>
        <mapping resource="org/hibernate/tutorial/domain/Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>


/**
 * Created by kyle on 2015/8/15.
 */

package org.hibernate.tutorial.domain;

import java.util.HashSet;
import java.util.Set;

public class Person
{
    private Integer id;
    private String name;
    private Set<Email> emails = new HashSet<>();

    public Set<Email> getEmails()
    {
        return emails;
    }

    public void setEmails(Set<Email> emails)
    {
        this.emails = emails;
    }

    public Integer getId()
    {
        return id;
    }

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

    public String getName()
    {
        return name;
    }

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

}


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.tutorial.domain">
    <class name="Person" table="tb_person">
        <id name="id" column="person_id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="emails" cascade="all" lazy="false"><!-- 代码中是Set集合,所以这里用<set>,如果代码中是List集合,则用<bag> -->
            <key column="kyle_person2emails"></key> <!-- 外键名,勿与表中已存在的列名重复!添加到Email实体类对应的表中! -->
            <one-to-many class="org.hibernate.tutorial.domain.Email"/><!-- 书上说这里可以不用再指定class,因为代码中已经明确是org.hibernate.tutorial.domain.Email,但是验证还是不行,不可省略class属性 -->
        </set>
    </class>
</hibernate-mapping>


/**
 * Created by kyle on 2015/8/15.
 */

package org.hibernate.tutorial.domain;

public class Email
{
    private Integer id;
    private String title;

    public Integer getId()
    {
        return id;
    }

    private void setId(Integer id)
    {
        this.id = id;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }
}


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.tutorial.domain">
    <class name="org.hibernate.tutorial.domain.Email" table="tb_email">
        <id name="id" column="email_id">
            <generator class="native"/> <!-- 如果设置为native报错,而设置为increment正常,则需要检查数据库中对应的表是否设置了主键自增长 -->
        </id>
        <property name="title"/> <!-- 与列名相同,无须显式说明 -->
    </class>
</hibernate-mapping>


/**
 * Created by kyle on 15-8-18.
 */

import main.java.org.hibernate.tutorial.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.tutorial.domain.Email;
import org.hibernate.tutorial.domain.Person;

import java.util.List;
import java.util.Set;

public class HibernateTest
{
    public static void main(String[] args)
    {
        Person person = new Person();
        person.setName("Jane");

        Email email = new Email();
        email.setTitle("Hello");
        person.getEmails().add(email);

        email = new Email();
        email.setTitle("World");
        person.getEmails().add(email);

        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();

        // 保存 Person 对象,会自动级联保存 Email 对象
        session.persist(person);

        List list = session.createQuery(" select p from Person p where p.name = 'Jane'").list();
        for(Person tp : (List<Person>)list)
        {
            Set set = tp.getEmails();
            for(Email te: (Set<Email>)set)
            {
                System.out.println("ID: " + te.getId() + " ,Title: " + te.getTitle());
            }
        }
        session.delete(person); // 删除之前插入到tb_person中的数据,但会先删除tb_email表中的部分。
        session.getTransaction().commit(); // 其实在此之前任何数据库改动,都只存在于session中,数据库本身其实没有变化,这点要注意下!!
        session.close();

    }
}






此例中,如果是要配置为单边的多对一,则更简单,只需要在Email.hbm.xml中配置

<many-to-one name = "owner" column="kyle_email2person" cascade="all" lazy="false"/>
,Person.hbm.xml就按照普通POJO配置即可,无需<set>那部分。实体类也要相应修改,删除Person.java中的emails集合,并在Email.java中添加Person类型的属性及gettet、setter方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: