最近做的一个工程要用到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框架一对一关联测试案例详解** 在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够用Java对象来处理数据。本篇我们将深入探讨Hibernate中的一对一...
`hibernate_course2.zip`可能是一个包含更多关于Hibernate教程的压缩包,里面可能有相关的代码示例、讲解文档或视频课程,可以帮助你更深入地理解和实践一对一外键关系。 总之,理解并熟练掌握Hibernate中的一对一...
Hibernate支持多种关系映射,包括一对一、一对多、多对一和多对多。这涉及到外键的处理和关联映射。 8. **事务管理** Hibernate提供了基于编程和声明式两种方式的事务管理,以确保数据的一致性。 9. **Hibernate...
本示例将深入讲解如何在Hibernate中实现一对一的关联,并提供数据库备份文件作为实践基础。 首先,一对一关联可以通过在实体类中使用`@OneToOne`注解来实现。这个注解用于定义两个实体之间的关系,可以指定目标实体...
**标题:“Hibernate一对一”** **描述:** 这篇文章主要探讨了Hibernate框架中的一对一关系映射,这是一种在数据库设计中常见的关联方式。作者通过在博客中分享,详细讲解了如何在Java应用程序中使用Hibernate实现...
本项目“hibernate一对多项目”旨在演示如何在JavaWeb应用中使用Hibernate处理一对多的关系映射。这里我们将深入探讨 Hibernate 的一对多关系、配置以及在实际项目中的应用。 首先,一对多关系在数据库中很常见,...
"hibernate一对一映射"是Hibernate中的一个重要概念,它用于表示两个实体类之间一对一的关系。这种关系意味着在一个实体类中,每个实例都唯一对应另一个实体类的单个实例。 一对一映射有以下几种实现方式: 1. **...
通过这个“Hibernate一对一实例”,初学者可以动手实践,了解如何在实际项目中应用一对一映射。记住,理论结合实践是最好的学习方法,因此,不仅要理解这些概念,还要尝试编写代码并运行,以加深理解和记忆。
在这个实例中,我们将深入探讨Hibernate一对一主键映射的概念、配置以及如何通过源代码和测试程序进行实践。 1. **一对一关系理解**: 一对一关系指的是一个实体类中的记录对应另一个实体类中的唯一一条记录。例如...
在本教程中,我们将深入探讨Hibernate中的一个关键概念——关系映射,特别是“一对一”双向外键关联。这种关联类型在数据库设计中很常见,尤其是在处理具有紧密耦合的实体时。Hibernate作为Java中广泛使用的对象关系...
本文将详细讲解“Hibernate Annotation 中的共享主键一对一双向关联”。 首先,我们需要理解什么是共享主键(Shared Primary Key)。在一对一的关联关系中,如果两个实体共享同一个主键,那么这种关联被称为共享...
**标题:Hibernate一对一外键映射** 在关系型数据库中,一对一(One-to-One)关联是一种常见的关系,它表示两个实体之间存在着唯一的关系。Hibernate,作为Java领域中的一个流行的ORM(对象关系映射)框架,提供了...
【标题】:“Hibernate一对一实例子”深入解析 在Java企业级开发中,数据持久化是一个不可或缺的部分,而Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了这一过程。本篇将深入探讨 Hibernate 中的一...
在提供的压缩包`TestHiberOnetoOne`中,可能包含了使用Eclipse创建的Hibernate一对一映射关系的项目源码。你可以通过运行这个项目来更直观地理解一对一映射的工作原理,包括实体类的定义、配置文件的编写以及如何在...
**标题:“Hibernate双向一对多经典实例”** 在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够用面向对象的方式处理数据。本实例将聚焦于Hibernate中的一对多关系...
描述提到这是一个已经成功运行的项目,目的是为了便于学习者更好地理解和实践Hibernate双向一对多的关系映射。通过实际的项目案例,学习者可以直观地看到配置、实体定义、DAO操作以及Service层的实现,从而加深对这...
本文将深入探讨Hibernate中的一对多和多对一映射关系,并通过一个实际的demo演示它们在增删查改操作中的应用。 首先,我们要理解什么是数据库的关联关系。在数据库设计中,我们经常遇到一种情况,即一个实体可能与...
通过“Hibernate Reference官方文档实践日记一”,我们可以期待作者详细分享了他们对这些概念的理解,以及在实际应用中遇到的问题和解决方法。这样的文章对于初学者和有经验的开发者来说都是宝贵的资源,可以帮助...
当涉及多表操作时,Hibernate支持多种关联关系的映射,如一对一、一对多、多对多等。这要求在数据库设计阶段就考虑到实体之间的关联性,并在映射文件中明确表示出来。同时,配置文件中的设置也需要调整,以适应更...
在本文中,我们将详细介绍Hibernate一对一唯一外键关联映射的概念、配置方法和实践应用。 一对一唯一外键关联映射的概念 在Hibernate中,一对一唯一外键关联映射是指两个实体之间的关联关系,其中一个实体作为外键...