0
点赞
收藏
分享

微信扫一扫

Hibernate多对一自身关联


说明:一个部门有若干个子部门,子部门还可以有子部门,本文通过这个演示myeclipse如何实现这种树形关系的持久化。 

开发工具:myeclipse 7.0 GA 
数 据 库:mysql-5.0.41 
操作系统:windows xp professional 中文版 

步骤: 
1、建立mysql5数据库testdb,脚本下面已经给出。 
2、配置myeclipse的数据库服务器,并建立名称为mysql的数据库链接。 
3、建议myeclipse的web工程,名称为hibernateRel,并加入hibernate支持。 
4、在myeclipse的数据库视图中链接数据库并通过表生成实体POJO和配置文件,中间不生成DAO。 
5、检查配置文件的正确性,然后测试类进行测试。 


一、建立数据库的脚本: 

drop table if exists part; 
  

-- alter table part drop foreign key fk_part; 
  

create table part( 
  
id bigint not null primary key, 
  
name varchar(20), 
  
father_id bigint 
  
); 
  

alter table part add index fk_part (father_id), 
  
add constraint fk_part foreign key (father_id) references part(id);



表关系的逻辑图: 

Java代码  


    1. +-----------+  
    2. | Part      |  
    3. +-----------+  
    4. | id        |<---------|<PK>  
    5. | name      |          |  
    6. | father_id |----------|<FK>  
    7. +-----------+



    特别注意:因为有外键约束,需要事务支持,在安装数据库的时候,需要配置mysql数据库服务器的参数。数据库的引擎应该用InnoDB,关闭了自动提交模式,也就是SET AUTOCOMMIT=0。 


      


    二、通过myeclipse生成实体和配置文件: 



    Part.java 
    
    public class Part implements java.io.Serializable {
    
     // Fields
    
     private Long id;
     private String name;
     private Part part; //父Part
     private Set parts = new HashSet(0); //子Part
    
     // Constructors
    
     /** default constructor */
     public Part() {
     }
    
     /** minimal constructor */
     public Part(Long id) {
     this.id = id;
     }
    
     public Part(String name) {
     this.name = name;
     } 
    
     /** full constructor */
     public Part(Long id, Part part, String name, Set parts) {
     this.id = id;
     this.part = part;
     this.name = name;
     this.parts = parts;
     }
    
     // Property accessors
    
     public Long getId() {
     return this.id;
     }
    
     public void setId(Long id) {
     this.id = id;
     }
    
     public Part getPart() {
     return this.part;
     }
    
     public void setPart(Part part) {
     this.part = part;
     }
    
     public String getName() {
     return this.name;
     }
    
     public void setName(String name) {
     this.name = name;
     }
    
     public Set getParts() {
     return this.parts;
     }
    
     public void setParts(Set parts) {
     this.parts = parts;
     }
    
    }


    Part.hbm.xml 
    
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "[url]http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd[/url]">
    <!-- 
     Mapping file autogenerated by MyEclipse Persistence Tools
    -->
    <hibernate-mapping>
     <class name="org.lavasoft.Part" table="part">
     <id name="id" type="java.lang.Long">
     <column name="id" />
     <generator class="increment" />
     </id>
     <property name="name" type="java.lang.String">
     <column name="name" length="20" />
     </property>
     <many-to-one name="part" class="org.lavasoft.Part" fetch="select">
     <column name="father_id" />
     </many-to-one>
     <set name="parts" cascade="save-update" inverse="true">
     <key>
     <column name="father_id" />
     </key>
     <one-to-many class="org.lavasoft.Part" />
     </set>
     </class>
    </hibernate-mapping>

    三、写测试类进行测试: 

    Test.java 
     
      
    package org.lavasoft;
    
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    public class Test {
    
     /**
     * @param args
     */
     public static void main(String[] args) {
     // TODO Auto-generated method stub
    
     Part p1=new Part("p1");
     Part p11=new Part("p11");
     Part p12=new Part("p12");
    
     p1.getParts().add(p11);
     p1.getParts().add(p12);
     p11.setPart(p1);
     p12.setPart(p1);
    
     Configuration config = new Configuration().configure();
     SessionFactory factory = config.buildSessionFactory();
     Session session = factory.openSession();
     Transaction tx = session.beginTransaction();
    
     try{
     session.save(p1);
     tx.commit();
     }catch(HibernateException e){
     e.printStackTrace();
     tx.rollback();
     }finally{
     session.close();
     } 
     }
    }

    四、运行测试类Test,控制台打印信息: 

    ------------------------------------------ 

    Hibernate: select max(id) from part 
      
    Hibernate: insert into part (name, father_id, id) values (?, ?, ?) 
      
    Hibernate: insert into part (name, father_id, id) values (?, ?, ?) 
      
    Hibernate: insert into part (name, father_id, id) values (?, ?, ?)




    查看数据库: 


    D:\mysql-5.0.41-win32\bin>mysql -uroot -123456
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 13
    Server version: 5.0.41-community MySQL Community Edition (GPL)
    
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
    
    mysql> use testdb;
    Database changed
    
    mysql> describe part;
    +-----------+-------------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-----------+-------------+------+-----+---------+-------+
    | id | bigint(20) | NO | PRI | | |
    | name | varchar(20) | YES | | NULL | |
    | father_id | bigint(20) | YES | MUL | NULL | |
    +-----------+-------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from part;
    +----+------+-----------+
    | id | name | father_id |
    +----+------+-----------+
    | 1 | p1 | NULL |
    | 2 | p12 | 1 |
    | 3 | p11 | 1 |
    +----+------+-----------+
    3 rows in set (0.00 sec)
    
    mysql>

    测试结果表明,保存父机关的时候,可以级联保存父机关下的子机关。 


    总结:这个表建立好后,由myeclipse生成的POJO不需要做任何改动,生成的mapping也需要添加一个cascade="save-update"。然后就直接写测试类进行测试。 

    举报

    相关推荐

    0 条评论