Hibernate关联关系之多对一

本文以组和用户为例,讲述hibernate中多对一关联关系的映射原理以及应用。

1.原理

在对象模型中,关联关系是有方向的。多对一顾名思义,维护关系的是多的一方。也就是本例中的用户的一方。此处我们只说单向关联。原理图如下:
这里写图片描述
对象模型上可以看出,由多的一方也就是User的一方来维护关系,而此时,对于Group对象来说,根本不知道User对象的存在;从关系模型上可以看出,在多的一方也就是user表中,加入了一个字段groupid,来引用一的一方。

2.基于xml的映射配置

我们来看代码,先建立Group类:

public class Group {

    private int id;

    private String name;

    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;
    }
}

Group类的映射文件:

<hibernate-mapping>
    <class name="Group" table="t_group">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
   </class>
</hibernate-mapping>

再来看User类的代码:

public class User {

    private int id;

    private String name;

    //User对象持有Group对象的引用,从对象模型上看,该属性必须存在
    private Group group;

    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 Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}

User对象的映射文件:

<hibernate-mapping>
    <class name="User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>

        <!--该标签用来维护关联关系,column属性指定了关联字段的名称-->
        <many-to-one name="group" column="groupid"/>
    </class>
</hibernate-mapping>

下面我们来测试一下:

@Test
public void testSave1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();

            Group group = new Group();
            group.setName("第一组");

            User user1 = new User();
            user1.setName("张三");
            user1.setGroup(group);

            User user2 = new User();
            user2.setName("李四");
            user2.setGroup(group);

            session.save(user1);
            session.save(user2);            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }

运行之后发现报错了,报了TransientObjectException,是因为在保存用户的时候,组并不存在。那在保存用户的时候先保存组就可以了。

3.基于JPA的映射配置

先看Group类的代码:

@Entity
@Table(name="t_group")
public class Group {

    private int id;

    private String name;

    @Id
    @GeneratedValue
    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;
    }
}

User类的代码:

@Entity
@Table(name="t_user")
public class User {

    private int id;

    private String name;

    private Group group;

    @Id
    @GeneratedValue
    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;
    }

    //默认会生成字段名,规则是:属性名_id
    //用JoinColumn来自定义外键的名称  
    @ManyToOne
    @JoinColumn("group_id")
    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}

下来测试一下:

public void testSave2() {
    Session session = null;
    try {
        session = HibernateUtils4Xml.getSession();
        session.beginTransaction();

        Group group = new Group();
        group.setName("Jpa组");
        session.save(group);

        User user1 = new User();
        user1.setName("张三");
        user1.setGroup(group);

        User user2 = new User();
        user2.setName("李四");
        user2.setGroup(group);

        session.save(user1);
        session.save(user2);

        session.getTransaction().commit();
    }catch(Exception e) {
        e.printStackTrace();
        session.getTransaction().rollback();
    }finally {
        HibernateUtils4Xml.closeSession(session);
    }
}

可以保存成功!发出的sql语句如下:
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (group_id, name) values (?, ?)
Hibernate: insert into t_user (group_id, name) values (?, ?)

ok, 以上就是hibernate多对一的讲解,源代码请看:https://github.com/maodou95838/hibernate_many2one,谢谢大家。

猜你喜欢

转载自blog.csdn.net/maodou95838/article/details/52831579