今天先总结一对一主键关联,举得例子是学生和座位,一个人对应一个座位,一个座位对应一个人,分别用User 和 Seat 来代替。
一 安装好mysql数据库
通过cmd进入mysql,新建一个数据库,在其中创建两表:
id char ( 32 ) not null primary key ,
name varchar ( 100 ) not null default ''
)
create table seat (
id char ( 32 ) not null primary key ,
place varchar ( 100 ) not null default ''
)
二 在Eclipse中新建project,建好目录,在WEB-INF/lib中加入hibernate所必需的包:hibernate3.2.5.jar、cglib-asm.jar、dom4j.jar、odmg.jar、commons-collections.jar、commons-beanutils.jar、commons-lang.jar、commons-logging.jar、jta.jar、log4j.jar; 加入mysql jdbc驱动包 。刷新项目,在项目properties中把buildpath设置好。
在JavaSource中的model包中,加入两实体类User.java User.hbm.xml Seat.java Seat.hbm.xml ;加入一个测试文件,TestHibernate.java;再在JavaSource中再加入hibernate.cfg.xml文件。
目录结构大体如下:
hibernate.cfg.xml:
<! DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd" >
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
< hibernate-configuration >
< session-factory >
< property name ="connection.username" > root </ property >
< property name ="connection.password" > 1 </ property >
< property name ="connection.url" >
jdbc:mysql://localhost/mybase
</ property >
< property name ="dialect" >
org.hibernate.dialect.MySQLDialect
</ property >
< property name ="connection.driver_class" >
com.mysql.jdbc.Driver
</ property >
< property name ="connection.pool.size" >
20
</ property >
< property name ="hibernate.show_sql" >
true
</ property >
< property name ="hibernate.jdbc.fetch_size" > 50 </ property >
< property name ="hibernate.jdbc.batch_size" > 25 </ property >
< mapping resource ="com/mp/persistence/model/User.hbm.xml" />
< mapping resource ="com/mp/persistence/model/Seat.hbm.xml" />
</ session-factory >
</ hibernate-configuration >
User和Seat是一对一主键关联,那么在User.java 里必须包含一个Seat对象,Seat.java 里包含一个User对象。
User.java
package com.mp.persistence.model;
public class User
{
private String id;
private String name;
private Seat seat;
public Seat getSeat()
{
return seat;
}
public void setSeat(Seat seat)
{
this.seat = seat;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
Seat.java:
package com.mp.persistence.model;
public class Seat
{
private String id;
private String place;
private User user;
public String getId()
{
return id;
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public void setId(String id)
{
this.id = id;
}
public String getPlace()
{
return place;
}
public void setPlace(String place)
{
this.place = place;
}
}
映射文件和实体文件对应,user实体类里有一个seat对象,所以user的xml中需要加入一个seat;同理seat当中要加入一个user;
其中<one-to-one>标签里的name就是实体类对应的关联类的名称,例如User.java中的private Seat seat;
则在user.hbm.xml里写<one-to-one name="seat" class="com.mp.persistence.model.Seat" />
这种关联标签,就是展现当前表与其他表字段的关联关系,如果是一对一,则当前表里肯定有一个字段和另一个表的一字段关联,且是双向的,所以两个表的映射文件里都需要加上one-to-one标签,这样两边的试题对象在代码里都可以get到关联的对象;
User.hbm.xml:
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="com.mp.persistence.model.User" table ="user" >
< id name ="id" column ="id" type ="java.lang.String" >
< generator class ="uuid" />
</ id >
< property name ="name" column ="name" type ="java.lang.String" />
< one-to-one name ="seat" class ="com.mp.persistence.model.Seat" cascade ="all" />
</ class >
</ hibernate-mapping >
可以使用cascade="all"
将一个关联关系(无论是对值对象的关联,或者对一个集合的关联)标记为父/子关系的关联。 这样对父对象进行save/update/delete操作就会导致子对象也进行save/update/delete操作。 默认值是cascade="none"
,即任何操作都不会被级联(cascaded)。
Seat.hbm.xml:
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="com.mp.persistence.model.Seat" table ="seat" >
< id name ="id" column ="id" type ="java.lang.String" >
< generator class ="foreign" >
< param name ="property" > user </ param >
</ generator >
</ id >
< property name ="place" column ="place" type ="java.lang.String" />
< one-to-one name ="user" class ="com.mp.persistence.model.User" constrained ="true" />
</ class >
</ hibernate-mapping >
使用foreign表示与外键共享主键,也就是与User实体共享主键,而constrained设定为true,表示的主键必须与user中对应资料的主键相同。
写测试代码TestHibernate.java:
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* 类功能描述:测试hibernate映射关系
*
* @author <a href="mailto:likunwangyi@163.com">likun </a>
* @version $Id: codetemplates.xml,v 1.1 2007/12/07 02:35:38 likun Exp $
* Create: 2008-1-3 下午01:00:21
*/
public class TestHibernate
{
public static void main(String[] args)
{
// 获得hibernate.cfg.xml配置信息
Configuration config = new Configuration().configure();
// 根据 config 建立 SessionFactory
// SessionFactory 将用于建立 Session
SessionFactory sessionFactory = config.buildSessionFactory();
User user = new User();
user.setName("roy");
Seat seat = new Seat();
seat.setPlace("三排一列");
user.setSeat(seat);
seat.setUser(user);
// 开启Session,相当于开启JDBC的Connection
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 保存实体类至数据库中
session.save(user);
tx.commit();
session.close();
sessionFactory.close();
System.out.println("操作成功!");
}
}
右键选择Run as /Java Application ,控制台显示:
Hibernate: insert into seat (place, id) values (?, ?)
操作成功!
切换到cmd界面,执行查询语句,可以看到插入数据后的结果: