Hibernate关系映射总结(一)

来源:互联网 发布:01科比季后赛数据 编辑:程序博客网 时间:2024/05/14 12:41

       为了能更直观得在cmd里查看结果,我使用了mysql数据库;为了更容易测试及更好的理解,项目里只加入了hibernate所需要的包,而没有使用spring框架,这样显得更清爽些~

     今天先总结一对一主键关联,举得例子是学生和座位,一个人对应一个座位,一个座位对应一个人,分别用User 和 Seat 来代替。

一 安装好mysql数据库

通过cmd进入mysql,新建一个数据库,在其中创建两表:

create table user (
    id 
char(32not null primary key ,
    name 
varchar(100not null default ''
)

create table seat (
    id 
char(32not null primary key ,
    place 
varchar(100not 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:

<?xml version='1.0' encoding='UTF-8'?>
<!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到关联的对象;

如果是一对多单向关联,就是当前表里有一个字段的值在另一个表里的字段里重复出现,因为是单向引用关系,所以多方表是被动的,一方来引用它,它可以不理一方表,它的hbm.xml里配置文件里可以不加映射标签,而一方的xml文件里需要加入<set>标签,代表我这里引用了你那多条记录,这种情况下,一可以通过象User.getSeat( )这种方式得到多方的集合,而多方得不到一方;如果想让刚才的引用反过来,多方能够得到一方,则在多方的xml里加入<many-to-one>
如果是多对多关联,则一般使用中间表来关联,根据是单向关联还是双向关联,在两个实体类的xml文件里,加入象如下的关联标签:
<set ……>
         <many-to many……./>
</set>
这章blog先只写一对一的关系,其他类型的关系映射会在后面的blog里一一列出。

User.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>
<!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:

<?xml version="1.0" encoding="utf-8"?>
<!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:

package com.mp.persistence.model;

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 user (name, id) values (?, ?)
Hibernate: insert into seat (place, id) values (?, ?)
操作成功!

切换到cmd界面,执行查询语句,可以看到插入数据后的结果: