多对一单向关联映射

来源:互联网 发布:sysbench windows 编辑:程序博客网 时间:2024/05/16 09:59

一.  多对一单向关联映射

 

多对一关联采用User Group来进行演示

 

一个User对象属于一个Group,采用单向关联,是User称为主控方,

也即可以通过User对象来获得其所属的Group对象。

UserGroup实体的代码如下:

Group.java

package com.tyy.hibernate;

 

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;

    }

 

}

 

 

User.java

package com.tyy.hibernate;

 

public class User {

 

    private int id;

 

    private String name;

 

    private Group group; //User中包含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为主控方的目的,故在User中必须包含Group对象的引用。

如果是双向关联,则也必须在Group中包含User对象的引用。这在下一节中将给于描述。

 

下一部分主要介绍映射文件的编写,这也是最主要的部分

 

Group.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

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

 

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

       <id name="id" column="id">

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

       </id>

       <property name="name" column="name"></property>

      

    </class>

   

</hibernate-mapping>

 

 

User.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

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

 

    <class name="User" table="t_user">

       <id name="id" column="id">

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

       </id>

       <property name="name" column="name"></property>

      

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

      

    </class>

   

</hibernate-mapping>

 

注:Group.hbm.xml与普通的映射文件没有任何区别,对其所有的字段与数据库表都进行了映射,如果没有指定其对应的column属性,则默认与其类属性一直,如果其类属性与数据库中关键字重复,则必须指定其column属性,以改变其在数据库表中对应的字段名

 

多对一关联会在其主控方中添加一个新的字段,也即会改变其原先的表结构

 

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

 

<many-to-one>标签指定了多对一关联的主控方,也即可以得到其相关联对象的实例

name=”group”      User.hbm.xml中的 private Group group;  相对应

 

column=”groupid”指定了 数据库表中新增加的字段,其字段代表了相关联对象所对应表的主键

 

mysql> desc t_user;

+---------+--------------+------+-----+---------+----------------+

| Field   | Type         | Null | Key | Default | Extra          |

+---------+--------------+------+-----+---------+----------------+

| id      | int(11)      | NO   | PRI | NULL    | auto_increment |

| name    | varchar(255) | YES  |     | NULL    |                |

| groupid | int(11)      | YES  | MUL | NULL    |                |

+---------+--------------+------+-----+---------+----------------+

3 rows in set (0.05 sec)

 

 

mysql> desc t_group;

+-------+--------------+------+-----+---------+----------------+

| Field | Type         | Null | Key | Default | Extra          |

+-------+--------------+------+-----+---------+----------------+

| id    | int(11)      | NO   | PRI | NULL    | auto_increment |

| name  | varchar(255) | YES  |     | NULL    |                |

+-------+--------------+------+-----+---------+----------------+

2 rows in set (0.02 sec)

 

cascade = “save-update”   级联

如果保存或更新当前对象,则其相关联的对象将先执行相应的保存和更新操作

cascade 有一下三种:

none 默认情况下是这样的

delete   在删除的情况下执行

save-update

all  包含所有的,即deletesave-update

 

测试代码如下:

package com.tyy.hibernate;

                                  

import junit.framework.TestCase;

 

import org.hibernate.Session;

 

public class ManyToOneTest extends TestCase {

 

                                   public void testSave1() {

                                          Session session = null;

                                         

                                          try {

                                                 session = HibernateUtils.getSessioin();

                                                 session.beginTransaction();

                                                

                                                 Group group = new Group();

                                                 group.setName("科大");

//                                               此处如果不保存gruop,则会出现TransientObjectException异常

//                                               如果在<many-to-one>标签中设置cascade属性也可以正常保存,

//                                               且会先保存其引用的属性

//                                               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 {

                                                 HibernateUtils.closeSession(session);

                                          }

                                         

                                   }

                                  

}

 

如果不配置级联,则在保存user1 user2之前,应该先保存group对象。

 

否则会抛出TransientObjectException异常

 

 

 

 

 

 

 

 

 

 

 

 

 

二.   一对多关联(双向))(参照d:/workspace/hibernate/user_article_one2many项目)

 

说明:论坛系统中的用户和已发帖子之间的一对多双向关联

用户可以查看自己发的所有帖子,而通过帖子也可以看到是由哪个用户发的。

当添加一个帖子时,也相应的增加一条该用户的信息。此处并没有在t_user表中添加一个表示发表帖子数量的属性,而是继续向t_user表中添加一条发帖人的记录,该记录的username可以重复. 所以应该在Article端设置cascade=”save-updae”

当删除一个用户时,其所发表的所有帖子不会消失;删除一个帖子时,其发帖人也不会被删除。

 

测试过程:

1.       编写Hibernate配置文件hibernte.cfg.xml,放在/src目录下

 

<!DOCTYPE hibernate-configuration PUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

    <session-factory>

       <property name="hibernate.connection.url">

           jdbc:mysql://localhost/user_article_one2many

       </property>

       <property name="hibernate.connection.driver_class">

           com.mysql.jdbc.Driver

       </property>

       <property name="hibernate.connection.username">root</property>

       <property name="hibernate.connection.password">passwd</property>

       <property name="hibernate.dialect">

           org.hibernate.dialect.MySQLDialect

       </property>

       <property name="hibernate.show_sql">true</property>

       <!-- 

           <property name="hibernate.hbm2ddl.auto">update</property>

       -->

 

       <mapping resource="com/tyy/pojo/Article.hbm.xml"/>

       <mapping resource="com/tyy/pojo/User.hbm.xml"/>

 

    </session-factory>

</hibernate-configuration>

 

 

2.       定义两个实体类,并且放在com.tyy.pojo包中

 

 

User.java

package com.tyy.pojo;

 

import java.util.Set;

 

public class User {

 

    private int id;

   

//  private String userid;

   

    private String username;

   

    private String password;

   

    private Set<Article> articles;

 

//  setter and getter method………

 

 

 

Article.java

 

package com.tyy.pojo;

 

public class Article {

 

    private int id;

   

    private String title;

   

    private String content;

   

    private User user;

 

//  setter and getter method………

 

 

 

3.       定义实体映射文件User.hbm.xmlArticle.hbm.xml,也放在com.tyy.pojo包中

 

User.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.tyy.pojo">

 

    <class name="User" table="t_user">

 

       <id name="id">

           <generator class="native" />

       </id>

 

       <property name="username"></property>

       <property name="password"></property>

       <set name="articles" inverse="true" table="t_article" >

           <key column="userid"></key>

           <one-to-many class="Article" />

       </set>

 

 

    </class>

 

</hibernate-mapping>

 

 

Article.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.tyy.pojo">

 

    <class name="Article" table="t_article">

       <id name="id">

           <generator class="native" />

       </id>

       <property name="title"></property>

       <property name="content"></property>

      

       <many-to-one name="user" column="userid" class="User"  cascade="all" not-null="true"></many-to-one>

    </class>

   

</hibernate-mapping>

 

4.       User.hbm.xmlArticle.hbm.xml添加到hibernte.cfg.xml

    <mapping resource="com/tyy/pojo/Article.hbm.xml"/>

    <mapping resource="com/tyy/pojo/User.hbm.xml"/>

 

5.       编写hbm2ddl工具类,将实体类生成数据库。放入com.tyy.util包中

 

DBExport.java

package com.tyy.util;

 

import org.hibernate.cfg.Configuration;

import org.hibernate.tool.hbm2ddl.SchemaExport;

 

public class DBExport {

 

    public static void main(String[] args) {

      

       Configuration config = new Configuration().configure();

      

       SchemaExport export = new SchemaExport(config);

      

       export.create(true, true);

 

    }

 

}

 

 

6.       编写一个用于打开Session和关闭Session的工具类,放入com.tyy.util包中

 

HibernteUtils.java

package com.tyy.util;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class HibernateUtils {

 

                                   private static SessionFactory factory;

 

                                   static {

                                          Configuration config = new Configuration().configure();

                                          factory = config.buildSessionFactory();

                                   }

 

                                   public static Session getSession() {

                                          Session session = null;

                                          try {

                                                 session = factory.openSession();

                                          } catch (Exception e) {

                                                 e.printStackTrace();

                                          }

                                          return session;

                                   }

 

                                   public static void closeSession(Session session) {

                                          if (session != null) {

                                                 if (session.isOpen()) {

                                                        session.close();

                                                 }

                                          }

                                   }

 

}

 

 

 

7.       编写测试类

 

新建一个source folder,名为test,用于测试,在其下建一个包为com.tyy.pojo

 

One2ManyTest.java

 

package com.tyy.pojo;

 

import java.util.HashSet;

import java.util.Set;

 

import junit.framework.TestCase;

 

import org.hibernate.Session;

 

import com.tyy.util.HibernateUtils;

 

public class One2ManyTest extends TestCase {

 

                                   /**

                                    * 当发表帖子时,会将帖子保存到t_article中,同时也自动将其发帖人也保存到t_user表中

                                    */

                                   public void testSave() {

                                          Session session = null;

                                          System.out.println("before of try");

                                          try {

                                                 session = HibernateUtils.getSession();

                                                

                                                 session.beginTransaction();

                                                

                                                 User user = new User();

                                                 user.setUsername("root");

                                                 user.setPassword("passwd");

                                                

                                                 Article article1 = new Article();

                                                 article1.setTitle("留言标题");

                                                 article1.setContent("留言内容");

                                                

//                                               user.getArticles().add(article1);

                                                

                                                 article1.setUser(user);

                                                

                                                 Article article2 = new Article();

                                                 article2.setTitle("留言标题2");

                                                 article2.setContent("留言内容2");

                                                

                                                 article2.setUser(user);

                                                

                                                 Set<Article> articles = new HashSet<Article>();

                                                 articles.add(article1);

                                                 articles.add(article2);

                                                 user.setArticles(articles);

                                                

//                                               Set<Article> articles = new HashSet<Article>();

//                                              

//                                               articles.add(article1);

//                                               articles.add(article2);

                                                

//                                               user.setArticles(articles);

                                                

//                                               session.save(user);

                                                 session.save(article1);

                                                 session.save(article2);

                                                

                                                

//                                               session.save(user);

                                                

                                                 session.getTransaction().commit();

                                          } catch(Exception e) {

                                                 e.printStackTrace();

                                                 session.getTransaction().rollback();

                                          } finally {

                                                 HibernateUtils.closeSession(session);

                                          }

                                   }

                                  

                                   public void testSave2() {

                                          Session session = null;

                                          try {

                                                 session = HibernateUtils.getSession();

                                                 session.beginTransaction();

 

                                                 Article article = new Article();

                                                 article.setTitle("帖子标题3");

                                                 article.setContent("帖子内容3");

                                                

                                                 User user = new User();

                                                 user.setUsername("scott");

                                                 user.setPassword("tiger");

                                                

                                                 Set<Article> articles = new HashSet<Article>();

                                                 articles.add(article);

                                                 user.setArticles(articles);

                                                

                                                 article.setUser(user);

                                                

                                                 session.save(article);

                                                

                                                 session.getTransaction().commit();

                                          } catch(Exception e) {

                                                 e.printStackTrace();

                                                 session.getTransaction().rollback();

                                          } finally {

                                                 HibernateUtils.closeSession(session);

                                          }

                                   }

}

原创粉丝点击