首页 > 代码库 > Hibernate One-to-Many Mappings 一对多关系映射

Hibernate One-to-Many Mappings 一对多关系映射

Hibernate One-to-Many Mappings 一对多关系映射


关键点:一对多关系使用 Set 实现,

例子:一个员工可以有多个学证书。


Hibernate框架的使用步骤:
1、创建Hibernate的配置文件(hibernate.cfg.xml)
2、创建持久化类,即其实例需要保存到数据库中的类(Employee.java)
3、创建对象-关系映射文件(Employee.hbm.xml)

4、通过Hibernate API编写访问数据库的代码



创建Hibernate的配置文件(hibernate.cfg.xml)

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

		<!-- Assume testone is the database name -->
		<property name="hibernate.connection.url">jdbc:mysql://localhost/testOne2Many</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.show_sql">true</property>
		
		<!-- List of XML mapping files -->
		<mapping resource="resource/Employee.hbm.xml" />

	</session-factory>
</hibernate-configuration>



2、创建持久化类,即其实例需要保存到数据库中的类(Employee.java)


Employee.java文件:

package com.jiangge.hblearn;

import java.util.Set;

public class Employee
{
	private int id;
	private String firstName;
	private String lastName;
	private int salary;
	private Set certificates;

	public Employee()
	{
	}

	public Employee(String fname, String lname, int salary)
	{
		this.firstName = fname;
		this.lastName = lname;
		this.salary = salary;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public String getFirstName()
	{
		return firstName;
	}

	public void setFirstName(String first_name)
	{
		this.firstName = first_name;
	}

	public String getLastName()
	{
		return lastName;
	}

	public void setLastName(String last_name)
	{
		this.lastName = last_name;
	}

	public int getSalary()
	{
		return salary;
	}

	public void setSalary(int salary)
	{
		this.salary = salary;
	}

	public Set getCertificates()
	{
		return certificates;
	}

	public void setCertificates(Set certificates)
	{
		this.certificates = certificates;
	}
}



Certificate.java文件:

package com.jiangge.hblearn;

public class Certificate
{
	private int id;
	private String name;

	public Certificate()
	{
	}

	public Certificate(String name)
	{
		this.name = name;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public boolean equals(Object obj)
	{
		if (obj == null)
			return false;
		if (!this.getClass().equals(obj.getClass()))
			return false;

		Certificate obj2 = (Certificate) obj;
		if ((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
		{
			return true;
		}
		return false;
	}

	public int hashCode()
	{
		int tmp = 0;
		tmp = (id + name).hashCode();
		return tmp;
	}
}



创建MySQL数据库对应的表:

mysql> create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);
Query OK, 0 rows affected

mysql> create table CERTIFICATE (
   id INT NOT NULL auto_increment,
   certificate_name VARCHAR(30) default NULL,
   employee_id INT default NULL,
   PRIMARY KEY (id)
);
Query OK, 0 rows affected

mysql> 



创建对象-关系映射文件(Empoyee.hbm.xml)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 
The <set> element sets the relationship between Certificate and Employee classes.

We used the cascade attribute in the <set> element to tell Hibernate to persist the Certificate objects at the same time as the Employee objects.
The name attribute is set to the defined Set variable in the parent class, in our case it is certificates.
For each set variable, we need to define a separate set element in the mapping file.

The <key> element is the column in the CERTIFICATE table that holds the foreign key to the parent object ie. table EMPLOYEE.

The <one-to-many> element indicates that one Employee object relates to many Certificate objects.

 -->
<hibernate-mapping>
	<class name="com.jiangge.hblearn.Employee" table="EMPLOYEE">
		<meta attribute="class-description">This class contains the employee detail.</meta>
		<id name="id" type="int" column="id">
			<generator class="native" />
		</id>
		<set name="certificates" cascade="all">
			<key column="employee_id" />
			<one-to-many class="com.jiangge.hblearn.Certificate" />
		</set>
		<property name="firstName" column="first_name" type="string" />
		<property name="lastName" column="last_name" type="string" />
		<property name="salary" column="salary" type="int" />
	</class>

	<class name="com.jiangge.hblearn.Certificate" table="CERTIFICATE">
		<meta attribute="class-description"> This class contains the certificate records.</meta>
		<id name="id" type="int" column="id">
			<generator class="native" />
		</id>
		<property name="name" column="certificate_name" type="string" />
	</class>

</hibernate-mapping>




通过Hibernate API编写访问数据库的代码

package test;

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.jiangge.hblearn.Certificate;
import com.jiangge.hblearn.Employee;

/**
 * 测试类:一对多关系。一个员工可以有多个文凭证书
 * CRUD操作
 * @author jiangge
 *
 */
public class ManageEmployee
{
	private static SessionFactory factory;

	public static void main(String[] args)
	{
		try
		{
			factory = new Configuration().configure().buildSessionFactory();
		} 
		catch (Throwable ex)
		{
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
		ManageEmployee ME = new ManageEmployee();
		/* Let us have a set of certificates for the first employee */
		HashSet set1 = new HashSet();
		set1.add(new Certificate("MCA"));
		set1.add(new Certificate("MBA"));
		set1.add(new Certificate("PMP"));

		/* Add employee records in the database */
		Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

		/* Another set of certificates for the second employee */
		HashSet set2 = new HashSet();
		set2.add(new Certificate("BCA"));
		set2.add(new Certificate("BA"));

		/* Add another employee record in the database */
		Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

		/* List down all the employees */
		ME.listEmployees();

		/* Update employee's salary records */
		ME.updateEmployee(empID1, 5000);

		/* Delete an employee from the database */
		ME.deleteEmployee(empID2);

		/* List down all the employees */
		ME.listEmployees();

	}

	/* Method to add an employee record in the database */
	public Integer addEmployee(String fname, String lname, int salary, Set cert)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		Integer employeeID = null;
		try
		{
			tx = session.beginTransaction();
			Employee employee = new Employee(fname, lname, salary);
			employee.setCertificates(cert);
			employeeID = (Integer) session.save(employee);
			tx.commit();
		} 
		catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
		finally
		{
			session.close();
		}
		return employeeID;
	}

	/* Method to list all the employees detail */
	public void listEmployees()
	{
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			List employees = session.createQuery("FROM Employee").list();
			for (Iterator iterator1 = employees.iterator(); iterator1.hasNext();)
			{
				Employee employee = (Employee) iterator1.next();
				System.out.print("First Name: " + employee.getFirstName());
				System.out.print("  Last Name: " + employee.getLastName());
				System.out.println("  Salary: " + employee.getSalary());
				Set certificates = employee.getCertificates();
				for (Iterator iterator2 = certificates.iterator(); iterator2.hasNext();)
				{
					Certificate certName = (Certificate) iterator2.next();
					System.out.println("Certificate: " + certName.getName());
				}
			}
			tx.commit();
		}
		catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} 
		finally
		{
			session.close();
		}
	}

	/* Method to update salary for an employee */
	public void updateEmployee(Integer EmployeeID, int salary)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			Employee employee = (Employee) session.get(Employee.class, EmployeeID);
			employee.setSalary(salary);
			session.update(employee);
			tx.commit();
		} 
		catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} 
		finally
		{
			session.close();
		}
	}

	/* Method to delete an employee from the records */
	public void deleteEmployee(Integer EmployeeID)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			Employee employee = (Employee) session.get(Employee.class, EmployeeID);
			session.delete(employee);
			tx.commit();
		}
		catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
		finally
		{
			session.close();
		}
	}
}



运行结果:

数据库中:




IDE控制台:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into EMPLOYEE (first_name, last_name, salary) values (?, ?, ?)
Hibernate: insert into CERTIFICATE (certificate_name) values (?)
Hibernate: insert into CERTIFICATE (certificate_name) values (?)
Hibernate: insert into CERTIFICATE (certificate_name) values (?)
Hibernate: update CERTIFICATE set employee_id=? where id=?
Hibernate: update CERTIFICATE set employee_id=? where id=?
Hibernate: update CERTIFICATE set employee_id=? where id=?
Hibernate: insert into EMPLOYEE (first_name, last_name, salary) values (?, ?, ?)
Hibernate: insert into CERTIFICATE (certificate_name) values (?)
Hibernate: insert into CERTIFICATE (certificate_name) values (?)
Hibernate: update CERTIFICATE set employee_id=? where id=?
Hibernate: update CERTIFICATE set employee_id=? where id=?
Hibernate: select employee0_.id as id0_, employee0_.first_name as first2_0_, employee0_.last_name as last3_0_, employee0_.salary as salary0_ from EMPLOYEE employee0_
First Name: Manoj  Last Name: Kumar  Salary: 4000
Hibernate: select certificat0_.employee_id as employee3_1_, certificat0_.id as id1_, certificat0_.id as id1_0_, certificat0_.certificate_name as certific2_1_0_ from CERTIFICATE certificat0_ where certificat0_.employee_id=?
Certificate: MBA
Certificate: MCA
Certificate: PMP
First Name: Dilip  Last Name: Kumar  Salary: 3000
Hibernate: select certificat0_.employee_id as employee3_1_, certificat0_.id as id1_, certificat0_.id as id1_0_, certificat0_.certificate_name as certific2_1_0_ from CERTIFICATE certificat0_ where certificat0_.employee_id=?
Certificate: BA
Certificate: BCA
Hibernate: select employee0_.id as id0_0_, employee0_.first_name as first2_0_0_, employee0_.last_name as last3_0_0_, employee0_.salary as salary0_0_ from EMPLOYEE employee0_ where employee0_.id=?
Hibernate: update EMPLOYEE set first_name=?, last_name=?, salary=? where id=?
Hibernate: select employee0_.id as id0_0_, employee0_.first_name as first2_0_0_, employee0_.last_name as last3_0_0_, employee0_.salary as salary0_0_ from EMPLOYEE employee0_ where employee0_.id=?
Hibernate: select certificat0_.employee_id as employee3_1_, certificat0_.id as id1_, certificat0_.id as id1_0_, certificat0_.certificate_name as certific2_1_0_ from CERTIFICATE certificat0_ where certificat0_.employee_id=?
Hibernate: update CERTIFICATE set employee_id=null where employee_id=?
Hibernate: delete from CERTIFICATE where id=?
Hibernate: delete from CERTIFICATE where id=?
Hibernate: delete from EMPLOYEE where id=?
Hibernate: select employee0_.id as id0_, employee0_.first_name as first2_0_, employee0_.last_name as last3_0_, employee0_.salary as salary0_ from EMPLOYEE employee0_
First Name: Manoj  Last Name: Kumar  Salary: 5000
Hibernate: select certificat0_.employee_id as employee3_1_, certificat0_.id as id1_, certificat0_.id as id1_0_, certificat0_.certificate_name as certific2_1_0_ from CERTIFICATE certificat0_ where certificat0_.employee_id=?
Certificate: MBA
Certificate: MCA
Certificate: PMP


参考文献:

英文:http://www.tutorialspoint.com/hibernate/hibernate_one_to_many_mapping.htm