Hibernate入门4_多对一关联映射

来源:互联网 发布:知乎 红楼梦 情榜 编辑:程序博客网 时间:2024/06/05 07:11

*关联映射:多对一:many-to-one:用户要持有组的引用

一对多:one-to-many

一对一:ont-to-one

多对多:many-to-many

 

hibernate多对一关联映射:

 

*关联映射的本质:将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用.

 

*<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one>

中的column属性定义的,如果忽略了这个属性那么默认的外键与User类的group属性一致

 

*<many-to-one>标签的定义示例:<many-to-one name="group" column="groupid"/> :在多的一端加入一个外键,参考一的一端,加载多的一端,一的一端自动加载进来.groupid参考groupid.所以要先有groupid,然后Usergroupid去引用.

 

Persistent状态不能引用Transistent状态:

如果先存User, Group仍为Transistent状态,Usergroupid不能去引用groupid.

所以先要把Group变为persistent状态.

 

*实体类:在User中持有组的引用

User

    private int id;

    private String name;

private Group group;

Group

private int id;

private String name;

 

*Group:映射文件:

<hibernate-mapping package="com.guojie.hibernate">

    <!-- 当默认字段与数据库关键字一样是,表名或者字段名必须重命名 -->

    <class name="Group" table="t_group">

       <id name="id">

           <generator class="native"></generator>

       </id>

       <property name="name"/>

    </class>  

</hibernate-mapping>

*User:映射文件:

<hibernate-mapping>

    <class name="com.guojie.hibernate.User" table="t_user">

       <id name="id">

           <generator class="native"></generator>

       </id>

       <property name="name"/>

       <!-- User属于多的一段,Group属于一的一端 这里必须要重命名groupmysql的关键字 -->

       <!-- 在多的一端自动加入groupid字段 参考至一端的主键 -->

       <!-- cascade配置级联关系:参数有:all nono save-update delete -->

       <!-- 此例设置删除有问题,guojie1删除的时候 组也删除了 但是还有guojie2引用 ,设置成all的话,测试中删除的时候也有问题,但是测试中如果只有save-update就正确

       <many-to-one name="group" column="groupid" cascade="all"></many-to-one>

不配cascade 查找多的一端,一的一端也自动加载进来,是通过外键实现的 多的一端的外键参考至一的一端的主键 -->

       <many-to-one name="group" column="groupid" ></many-to-one>

    </class>  

</hibernate-mapping>

 

*先要有组,再把用户放进组里

public void testSave1() {

       Session session = null;

       Transaction tx = null;

       try {

           session = HibernateUtils.getSession();

           tx = session.beginTransaction();

 

           Group group = new Group();

           group.setName("zjfc");

           session.save(group);

 

           User user1 = new User();

           user1.setName("guojie1");

           user1.setGroup(group);

 

           User user2 = new User();

           user2.setName("guojie2");

           user2.setGroup(group);

          

           //不能成功保存,抛出TransientObjectException:

           //因为groupTransient状态,id没有分配值

           //persistent状态不能引用Transient状态的对象,存groupid的时候抛异常,所以先要把Group存了

           //nativesave()了数据库中就记录了,但看不到,可以回滚,与uuid不同!!!

           //如果前面保存出错(像没先保存Group),则从Userid3开始(前面的两个user对象没保存成功).

           session.save(user1);

           session.save(user2);

 

           tx.commit();

 

       } catch (Exception e) {

           e.printStackTrace();

           tx.rollback();

       } finally {

           HibernateUtils.closeSession(session);

       }

}

 

/**<many-to-one name="group" column="groupid"cascade="all"> </many-to-one>

     * 设置了级联关系(cascade属性)testSave1()中不先保存Group也能执行了

     * cascade:先保存了group 是解决TransientObjectException的手段

     * 但一般介意采用先保存Group,再保存User.

     */

    public void testSave3() {

       Session session = null;

       Transaction tx = null;

       try {

           session = HibernateUtils.getSession();

           tx = session.beginTransaction();

 

           Group group = new Group();

           group.setName("zjfc");

 

           User user1 = new User();

           user1.setName("guojie1");

           user1.setGroup(group);

 

           User user2 = new User();

           user2.setName("guojie2");

           user2.setGroup(group);

          

           session.save(user1);

           session.save(user2);

 

           tx.commit();

 

       } catch (Exception e) {

           e.printStackTrace();

           tx.rollback();

       } finally {

           HibernateUtils.closeSession(session);

       }

}

 

加载:

public void testLoad1() {

       Session session = null;

       Transaction tx = null;

       try {

           session = HibernateUtils.getSession();

           tx = session.beginTransaction();

          

           User user = (User)session.load(User.class, 3);

           //加载多的一端:User ,一的一端自动加载进来(通过外键:User中的groupid加载的),与级联cascade没有关系

           System.out.println(user.getName()+" "+user.getGroup().getName());

 

           tx.commit();

 

       } catch (Exception e) {

           e.printStackTrace();

           tx.rollback();

       } finally {

           HibernateUtils.closeSession(session);

       }

}

*<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one>

中的column属性定义的,如果忽略了这个属性那么默认的外键User类的Group属性一致

原创粉丝点击