|
最近做的一个工程要用到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();
- }
-
- }
复制代码
to be continued
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>
复制代码
要把Author.hbm.xml,Topic.hbm.xml这两个hbm文件写进,否则会找不到类的。
2)、新建Test类,用于测试。
测试插入作者如图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,与期望相符。
图1

图2

[ Last edited by hjack on 2005-8-17 at 13:56 ]
[ 本帖最后由 hjack 于 2006-9-5 21:56 编辑 ] |
|