天天看点

myeclipse试用小记----Hibernate多对一自身关联(3)

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

开发工具:myeclipse 5.5.1 GA

数 据 库:mysql-5.0.37

操作系统:windows xp professional 中文版

步骤:

1、建立mysql5数据库testdb,脚本下面已经给出。

2、配置myeclipse的数据库服务器,并建立名称为mysql5的数据库链接。

3、建议myeclipse的web工程,名称为dx_d2yzs,并加入hibernate支持,选择hibernate3.1,最高就支持到3.1。

4、在myeclipse的数据库视图中链接数据库并通过表生成实体PO和配置文件,中间不生成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);

表关系的逻辑图:

+-----------+

| Part      |

| id        |<---------|<PK>

| name      |          |

| father_id |----------|<FK>

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

my.ini

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

#[WinMySQLAdmin]

#Server=D:/mysql-5.0.37-win32/bin/mysqld.exe

[mysqld]

# set basedir to your installation path

#basedir=D:/mysql-5.0.37-win32

# set datadir to the location of your data directory

port = 3306

key_buffer = 16K

max_allowed_packet = 1M

table_cache = 4

sort_buffer_size = 64K

read_buffer_size = 256K

read_rnd_buffer_size = 256K

net_buffer_length = 2K

thread_stack = 64K

datadir=data

default-character-set=gbk

init_connect='SET AUTOCOMMIT=0'

default-table-type=InnoDB

init_connect='set completion_type=1'

[client]

二、通过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.part = part;

        this.parts = parts;

    // Property accessors

    public Long getId() {

        return this.id;

    public void setId(Long id) {

    public Part getPart() {

        return this.part;

    public void setPart(Part part) {

    public String getName() {

        return this.name;

    public void setName(String name) {

    public Set getParts() {

        return this.parts;

    public void setParts(Set parts) {

}

Part.hbm.xml

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

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

<!--

    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>

三、写测试类进行测试:

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

        //if(HibernateSessionFactory.getSession()==null) System.out.println("null");

        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);

        Session session = HibernateSessionFactory.getSession();

        Transaction tx=session.beginTransaction();

        try {

            session.save(p1);

            tx.commit();

        } catch (HibernateException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

            tx.rollback();

        }finally{

            session.close();

        }      

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

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

Hibernate: select max(id) from part

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

查看数据库:

D:\mysql-5.0.37-win32\bin>mysql -uroot -pleizhimin

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 13

Server version: 5.0.37-community MySQL Community Edition (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use testdb;

Database changed

mysql> show tables;

+------------------+

| Tables_in_testdb |

| card             |

| customers        |

| orders           |

| part             |

| person           |

| t_user           |

| user             |

7 rows in set (0.02 sec)

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 |

mysql>

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

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

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/30183,如需转载请自行联系原作者