`
classtwo5367
  • 浏览: 37574 次
  • 性别: Icon_minigender_1
  • 来自: Cork
最近访客 更多访客>>
社区版块
存档分类
最新评论

Hibernate 一对一实践

阅读更多
最近做的一个工程要用到hibernate的一对一关联,比如论坛的一个主题对应一个作者。
  hibernate的一对一关系有两种形式,一种是共享主键方式,另一种是惟一外键方式,因为这里用到的是在主题表里与作者表之间的对应关系,所以介绍的是惟一外键方式的一以一关联。
  由于网上很多教程都说得不清楚,给出的实例不能正确运行,所以写下这份笔记,以便以后查询,并与大家分享,如有不对的地方请指正。
  本测试使用mysql数据库,eclipse2.1平台,使用tanghan插件生成hbm文件。
  1、新建数据库表如下:
  
CREATE TABLE `author` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(50) default NULL,
   PRIMARY KEY (`id`)
   );
   CREATE TABLE `topic` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(50) default NULL,
   `user_id` int(11) default NULL,
   PRIMARY KEY (`id`)
   );

  2、用tanghan建立数据库连接,并对这两个表生成相应的hbm文件(也可以手工编写这些文件)。
  Topic.hbm.xml文件如下:
  
<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
   <hibernate-mapping>
   <class name="model.Topic" table="topic">
   <id column="id" length="11" name="id" type="integer">
   <generator class="native"/>
   </id>
   <property column="name" length="50" name="name" type="string"/>
   <property column="user_id" length="11" name="user_id" type="integer"/>
   </class>
   </hibernate-mapping>

  
  Author.hbm.xml文件如下:
  
<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
   <hibernate-mapping>
   <class name="model.Author" table="author">
   <id column="id" length="11" name="id" type="integer">
   <generator class="native"/>
   </id>
   <property column="name" length="50" name="name" type="string"/>
   </class>
   </hibernate-mapping>

  
  Author.java文件如下:
  
package model;
  
   import java.io.Serializable;
   import org.apache.commons.lang.builder.EqualsBuilder;
   import org.apache.commons.lang.builder.HashCodeBuilder;
   import org.apache.commons.lang.builder.ToStringBuilder;
  
   /** @author Hibernate CodeGenerator */
   public class Author implements Serializable {
  
   /** identifier field */
   private int id;
  
   /** nullable persistent field */
   private String name;
  
   /** full constructor */
   public Author(java.lang.String name) {
   this.name = name;
   }
  
   /** default constructor */
   public Author() {
   }
  
   public int getId() {
   return this.id;
   }
  
   public void setId(int id) {
   this.id = id;
   }
  
   public java.lang.String getName() {
   return this.name;
   }
  
   public void setName(java.lang.String name) {
   this.name = name;
   }
  
   public String toString() {
   return new ToStringBuilder(this)
   .append("id", getId())
   .toString();
   }
  
   public boolean equals(Object other) {
   if ( !(other instanceof Author) ) return false;
   Author castOther = (Author) other;
   return new EqualsBuilder()
   .append(this.getId(), castOther.getId())
   .isEquals();
   }
  
   public int hashCode() {
   return new HashCodeBuilder()
   .append(getId())
   .toHashCode();
   }
  
   }

  
  Topic.java文件如下:
  
package model;
  
   import java.io.Serializable;
   import org.apache.commons.lang.builder.EqualsBuilder;
   import org.apache.commons.lang.builder.HashCodeBuilder;
   import org.apache.commons.lang.builder.ToStringBuilder;
  
   /** @author Hibernate CodeGenerator */
   public class Topic implements Serializable {
  
   /** identifier field */
   private int id;
  
   /** nullable persistent field */
   private String name;
  
   /** nullable persistent field */
   private int user_id;
  
   /** full constructor */
   public Topic(java.lang.String name, int user_id) {
   this.name = name;
   this.user_id = user_id;
   }
  
   /** default constructor */
   public Topic() {
   }
  
   public int getId() {
   return this.id;
   }
  
   public void setId(int id) {
   this.id = id;
   }
  
   public java.lang.String getName() {
   return this.name;
   }
  
   public void setName(java.lang.String name) {
   this.name = name;
   }
  
   public int getUser_id() {
   return this.user_id;
   }
  
   public void setUser_id(int user_id) {
   this.user_id = user_id;
   }
  
   public String toString() {
   return new ToStringBuilder(this)
   .append("id", getId())
   .toString();
   }
  
   public boolean equals(Object other) {
   if ( !(other instanceof Topic) ) return false;
   Topic castOther = (Topic) other;
   return new EqualsBuilder()
   .append(this.getId(), castOther.getId())
   .isEquals();
   }
  
   public int hashCode() {
   return new HashCodeBuilder()
   .append(getId())
   .toHashCode();
   }
  
   }

  3、修改Topic.java文件。
  找到 private int user_id;
  修改成private Author author;
  找到 构造函数public Topic(java.lang.String name, int user_id),把参数int user_id改为Author author, 把函数里的this.user_id = user_id; 改为this.author = author;
  找到以下两个函数
  
public int getUser_id() {
   return this.user_id;
   }
  
   public void setUser_id(int user_id) {
   this.user_id = user_id;
   }

  修改为
  
public Author getAuthor() {
   return author;
   }
  
   public void setAuthor(Author author) {
   this.author = author;
   }

  然后保存。以上文件保存在model包里。
  4、修改Topic.hbm.xml文件。
  删除下面这行
  
<property column="user_id" length="11" name="user_id" type="integer"/>

  在</class>前添回<many-to-one>项如下
  
<many-to-one name="author" class="model.Author" column="user_id" unique="true"/>

  通过以上操作就建立了Topic表与Author表之间的单向一对一关系,因为本工程中只需要从主题表去了解作者的信息,所以只需要单向的一对一就可以完成了。
  5、建立测试用例。
  1)、新建test包,在test包内建立HibernateUtil类。
  
/*
   * 创建日期 2005-8-4
   *
   * TODO 要更改此生成的文件的模板,请转至
   * 窗口 - 首选项 - Java - 代码样式 - 代码模板
   */
   package test;
  
   /**
   * @author hjack<br>
   *
   * TODO 要更改此生成的类型注释的模板,请转至
   * 窗口 - 首选项 - Java - 代码样式 - 代码模板
   */
  
  
   import net.sf.hibernate.HibernateException;
   import net.sf.hibernate.Session;
   import net.sf.hibernate.SessionFactory;
   import net.sf.hibernate.cfg.Configuration;
  
   public class HibernateUtil {
  
   private static final SessionFactory sessionFactory;
   private static Configuration cfg = null;
  
   static {
   try {
   cfg = new Configuration();
   sessionFactory =cfg.configure().buildSessionFactory();
   } catch (HibernateException ex) {
   throw new RuntimeException(
   "Exception building SessionFactory: " + ex.getMessage(),
   ex);
   }
   }
  
   public static final ThreadLocal session = new ThreadLocal();
  
   public static Session currentSession() throws HibernateException {
   Session s = (Session) session.get();
   // Open a new Session, if this Thread has none yet
   if (s == null) {
   s = sessionFactory.openSession();
   session.set(s);
   }
   return s;
   }
  
   public static void closeSession() throws HibernateException {
   Session s = (Session) session.get();
   session.set(null);
   if (s != null)
   s.close();
   }
   }

  
  hibernate.cfg.xml文件内容如下:
  
<!DOCTYPE hibernate-configuration PUBLIC
   "-//Hibernate/Hibernate Configuration DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
   <hibernate-configuration>
   <session-factory>
   <!--<property name="connection.datasource">java:comp/env/jdbc/mysql</property>-->
   <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
   <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
   <property name="connection.url">jdbc:mysql://localhost/testhibernate</property>
   <property name="connection.username">root</property>
   <property name="connection.password"></property>
   <property name="show_sql">true</property>
   <!--mapping files-->
   <mapping resource="model/Author.hbm.xml"></mapping>
   <mapping resource="model/Topic.hbm.xml"></mapping>
   </session-factory>
   </hibernate-configuration>

  2)、新建Test类,用于测试。
  
/*
   * 创建日期 2005-8-10
   *
   * 更改所生成文件模板为
   * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
   */
   package test;
  
   import model.Author;
   import model.Topic;
   import net.sf.hibernate.HibernateException;
   import net.sf.hibernate.Session;
   import net.sf.hibernate.Transaction;
  
   /**
   * @author hjack
   * 更改所生成类型注释的模板为
   * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
   */
   public class Test {
  
   Session sess;
   Transaction tx;
  
   public void insertTopic(Topic topic,int userID) throws HibernateException{
   try{
   sess = HibernateUtil.currentSession();
   tx = sess.beginTransaction();
   //新建一个author对象,并把作者id置入该对象里。
   Author author = new Author();
   author.setId(userID);
   //新建一个topic对象,设置用户名和把author对象set进去。
   topic.setAuthor(author);
   //因为只是插入一个话题,并不必在author表中插入一条记录,所以只需save(topic)
   sess.save(topic);
   tx.commit();
   }catch(HibernateException e){
   System.out.println(e.toString());
   }finally{
   if(tx!=null){
   tx.rollback();
   }
   HibernateUtil.closeSession();
   }
   }
  
   public void insertAuthor(Author author) throws HibernateException{
   try{
   sess = HibernateUtil.currentSession();
   tx = sess.beginTransaction();
   sess.save(author);
   tx.commit();
   }catch(HibernateException e){
   System.out.println(e.toString());
   }finally{
   if(tx!=null){
   tx.rollback();
   }
   HibernateUtil.closeSession();
   }
   }
  
  
   public Topic query(int id) throws HibernateException{
   Topic topic = null;
   try{
   sess = HibernateUtil.currentSession();
   topic=(Topic)sess.load(Topic.class,new Integer(id));
   }catch(HibernateException e){
   e.printStackTrace();
   }finally{
   HibernateUtil.closeSession();
   }
   return topic;
   }
  
   public static void main(String[] args) {
  
   Test app = new Test();
   try {
   /*测试插入作者
   Author author = new Author();
   author.setName("jack");
   app.insertAuthor(author);
   */
   /*测试插入主题
   Topic topic = new Topic();
   topic.setName("helloworld.");
   app.insertTopic(topic,1);
   */
   /*测试查询主题
   Topic topic = app.query(1);
   System.out.println(topic.getAuthor().getName());
   */
   } catch (Exception e) {
   // TODO 自动生成 catch 块
   e.printStackTrace();
   }
  
   }
   }

  测试插入作者如图1所示,测试插入主题如图2所示,测试查询主题结果如下:
  Hibernate: select topic0_.id as id1_, topic0_.name as name1_, topic0_.user_id as user_id1_, author1_.id as id0_, author1_.name as name0_ from topic topic0_ left outer join author author1_ on topic0_.user_id=author1_.id where topic0_.id=?
  jack
  生成的sql语句用到了join,查询结果为jack,与期望相符。
分享到:
评论

相关推荐

    hibernate学习笔记

    hibernate一对一主键关联映射(单向关联Person----&gt;IdCard) 8 hibernate一对一主键关联映射(双向关联Person&lt;----&gt;IdCard) 9 hibernate一对一唯一外键关联映射(单向关联Person----&gt;IdCard) 10 hibernate一对一...

    Hibernate+中文文档

    7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多...

    HibernateAPI中文版.chm

    7.2.2. 一对一(one to one) 7.2.3. 一对多(one to many) 7.3. 使用连接表的单向关联(Unidirectional associations with join tables) 7.3.1. 一对多(one to many) 7.3.2. 多对一(many to one) 7.3.3. ...

    hibernate3.2中文文档(chm格式)

    7.2.2. 一对一(one to one) 7.2.3. 一对多(one to many) 7.3. 使用连接表的单向关联(Unidirectional associations with join tables) 7.3.1. 一对多(one to many) 7.3.2. 多对一(many to one) 7.3.3. ...

    Hibernate实战第二版

    《图灵程序设计丛书·Hibernate实战(第2版)》通过一个应用将数百个例子融合起来,不仅深入剖析了Hibernate 3.2和Java Persistence丰富的编程模型。还深刻阐述了数据库设计、ORM和优化等方面的基本原则、策略和最佳...

    Hibernate实战

    《Hibernate实战》(第2版)通过一个应用将数百个例子融合起来,不仅深入剖析了Hibernate3.2和JavaPersistence丰富的编程模型。还深刻阐述了数据库设计、ORM和优化等方面的基本原则、策略和最佳实践。书中处处闪烁着...

    hibernate 教程

    一对一 5.1.12. 组件(component), 动态组件(dynamic-component) 5.1.13. 子类(subclass) 5.1.14. 连接的子类(joined-subclass) 5.1.15. map, set, list, bag 5.1.16. 引用(import) 5.2. ...

    Hibernate中文详细学习文档

    7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多...

    最全Hibernate 参考文档

    7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多...

    新SSH(Spring+SpringMVC+Hibernate)框架结构的java web案例实践

    随着struts的安全问题的暴露,原由Struts2+spring+hibernate构成的SSH2已经被越来越多的开发者所弃用,反而,由Spring+SpringMVC+Hibernate构成的SSH框架...这里提供了一个案例代码,希望对大家搭建环境有借鉴意义。

    Hibernate 中文 html 帮助文档

    7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多...

    Hibernate3开发.pdf

    包括:集合映射、一对一、一对多、多对多 第六章:性能提升和二级缓存 包括:抓取策略、集合的性能、二级缓存、查询缓存、管理缓存 第七章:基本实现原理 包括:分增删改查的操作说明Hibernate基本的实现原理 第...

    Hibernate教程

    8.2.2. 一对一(one to one) 8.2.3. 一对多(one to many) 8.3. 使用连接表的单向关联(Unidirectional associations with join tables) 8.3.1. 一对多(one to many) 8.3.2. 多对一(many to one) 8.3.3. 一...

    基于Struts2+Hibernate5的教务管理系统项目实训

    本项目只是简单模拟教务管理系统的基本功能,通过熟悉的教务管理系统开发来综合训练Struts2和 Hibernate5框架技术的整合应用,并进一步提高项目实践能力。 项目实现的功能包括学生管理部分,教师管理部分和管理员管理...

    Hibernate实战(第2版 中文高清版)

     7.1.2 一对一的外键关联   7.1.3 用联结表映射   7.2 多值的实体关联   7.2.1 一对多关联   7.2.2 多对多关联   7.2.3 把列添加到联结表   7.2.4 映射map   7.3 多态关联   7.3.1 多态的多对一...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    7.2.2. 一对一(one to one) 7.2.3. 一对多(one to many) 7.3. 使用连接表的单向关联(Unidirectional associations with join tables) 7.3.1. 一对多(one to many) 7.3.2. 多对一(many to one) 7.3.3. ...

    Hibernate实战.pdf 第2版 中文完整版

    《Hibernate实战》(第2版)通过一个应用将数百个例子融合起来,不仅深入剖析了Hibernate3.2和JavaPersistence丰富的编程模型。还深刻阐述了数据库设计、ORM和优化等方面的基本原则、策略和最佳实践。书中处处闪烁着...

    hibernate

    一对一 5.1.12. 组件(component), 动态组件(dynamic-component) 5.1.13. 子类(subclass) 5.1.14. 连接的子类(joined-subclass) 5.1.15. map, set, list, bag 5.1.16. 引用(import) 5.2. ...

    Hibernate实战(第二版-人民邮电出版社)

    书中通过一个应用将数百个例子融合起来,不仅深入剖析了Hibernate 3.2和Java Persistence丰富的编程模型,还深刻阐述了数据库设计、对象/关系映射(ORM)和优化等方面的基本原则、策略和最佳实践。书中处处闪烁着...

Global site tag (gtag.js) - Google Analytics