第二十一部分_Hibernate級聯關係詳解

接下來咱們開始介紹Hibernate的數據類型,由於咱們如今暫時只關注Hibernate這塊,所以咱們此次只創建一個Java Project,命名爲hibernate2。java

加入hibernate JAR包:mysql

選擇hibernate2項目,點擊MyEclipse->Add Hibernate Capabilities, Hibernate Specification與風中頁老師的相同,爲Hibernate3.2,點擊next,繼續next,去掉Specify database connection details前面的√接着next,去掉Create SessionFactory class?前面的√點擊Finish。sql

把上一個hibernate項目的hibernate.cfg.xml文件拷貝過來,覆蓋掉當前src下面的hibernate.cfg.xml文件,修改mapping信息:數據庫

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
    	<property name="show_sql">true</property> <!-- 屬性之間沒有上下關係,放在哪裏都行 -->
    	
    	<property name="connection.url">jdbc:mysql://localhost:3306/myhibernate2</property>
    	<property name="connection.username">root</property>
    	<property name="connection.password">root</property>
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	
    	<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
   
   		<mapping resource="Customers.hbm.xml"/> <!-- 將主配置文件包含對象-關係映射文件,之因此映射是由於hibernate啓動時只會加載主配置文件 -->
   
    </session-factory>

</hibernate-configuration>

添加MySql驅動,從hibernate項目拷貝mysql-connector-java-5.1.34-bin.jar到hibernate根目錄下。session

建立表:(bigint即long類型;bit即boolean類型;timestamp也是一個日期類型的,比date精度更高,能夠精確到毫秒;blob即二進制大型物件)app

mysql> create table CUSTOMERS(
    -> ID bigint not null primary key,
    -> NAME varchar(15) not null,
    -> EMAIL varchar(128) not null,
    -> PASSWORD varchar(8) not null,
    -> PHONE int,
    -> ADDRESS varchar(255),
    -> SEX char(1),
    -> IS_MARRIED bit,
    -> DESCRIPTION text,
    -> IMAGE blob,
    -> BIRTHDAY date,
    -> REGISTERED_TIME timestamp
    -> );

新建com.test.bean包,在該包下面新建一個類Customer.java:函數

package com.test.bean;

import java.sql.Date;
import java.sql.Timestamp;

public class Customer
{
	private Long id;
	
	private String name;
	
	private String email;
	
	private String password;
	
	private int phone; // or Integer
	
	private String address;
	
	private char sex;
	
	private boolean married;
	
	private String description;
	
	private byte[] image;
	
	private Date birthday;
	
	private Timestamp registeredTime;

	public Long getId()
	{
		return id;
	}

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

	public String getName()
	{
		return name;
	}

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

	public String getEmail()
	{
		return email;
	}

	public void setEmail(String email)
	{
		this.email = email;
	}

	public String getPassword()
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

	public int getPhone()
	{
		return phone;
	}

	public void setPhone(int phone)
	{
		this.phone = phone;
	}

	public String getAddress()
	{
		return address;
	}

	public void setAddress(String address)
	{
		this.address = address;
	}

	public char getSex()
	{
		return sex;
	}

	public void setSex(char sex)
	{
		this.sex = sex;
	}

	public boolean isMarried()
	{
		return married;
	}

	public void setMarried(boolean married)
	{
		this.married = married;
	}

	public String getDescription()
	{
		return description;
	}

	public void setDescription(String description)
	{
		this.description = description;
	}

	public byte[] getImage()
	{
		return image;
	}

	public void setImage(byte[] image)
	{
		this.image = image;
	}

	public Date getBirthday()
	{
		return birthday;
	}

	public void setBirthday(Date birthday)
	{
		this.birthday = birthday;
	}

	public Timestamp getRegisteredTime()
	{
		return registeredTime;
	}

	public void setRegisteredTime(Timestamp registeredTime)
	{
		this.registeredTime = registeredTime;
	}
	
	
}

在src下面新建一個Customers.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.test.bean.Customer" table="customers"> <!-- 將類與表相關聯,使得類中的屬性和表中的字段關聯起來 -->
		
		<id name="id" column="id" type="long"> <!-- 類中id屬性和映射到表中的id字段,類型爲int/integer皆可 -->
			<generator class="increment"> <!-- 主鍵id的生成方式爲自增 -->
			</generator>
		</id>
	
		<property name="name" column="name" type="string" not-null="true"></property> <!-- 若是不寫字段名,則默認與類中的屬性名相同 ;hibernate層和數據庫層均可以對非空進行檢查-->
		<property name="email" column="email" type="string" not-null="true"></property>
		<property name="password" column="password" type="string" not-null="true"></property>
		<property name="phone" column="phone" type="int"></property>
		<property name="address" column="address" type="string" ></property>
		<property name="sex" column="sex" type="character" ></property>
		<property name="married" column="is_married" type="boolean" ></property>
		<property name="description" column="description" type="text"></property>
		<property name="image" column="image" type="binary" ></property>
		<property name="birthday" column="birthday" type="date" ></property>
		<property name="registeredTime" column="registered_time" type="timestamp"></property>

	</class>

</hibernate-mapping>

在com.test.bean包下面,建立測試類HibernateTest.java同時放置一個photo.gif文件:fetch

package com.test.bean;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.sql.Date;
import java.util.Iterator;
import java.util.List;

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

public class HibernateTest
{
	public static SessionFactory sessionFactory;

	static
	{
		try
		{
			Configuration config = new Configuration().configure();

			sessionFactory = config.buildSessionFactory();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	public void findAllCustomers(PrintStream out) throws Exception
	{
		// Ask for a session using the JDBC information we've configured
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			List customers = session.createQuery("from Customer as c order by c.name asc").list();
			for (Iterator it = customers.iterator(); it.hasNext();)
			{
				printCustomer(out, (Customer) it.next());
			}

			// We're done; make our changes permanent
			tx.commit();

		}
		catch (Exception e)
		{
			if (tx != null)
			{
				// Something went wrong; discard all partial changes
				tx.rollback();
			}
			throw e;
		}
		finally
		{
			// No matter what, close the session
			session.close();
		}
	}

	public static void saveCustomer(Customer customer) throws Exception
	{

		// Ask for a session using the JDBC information we've configured
		Session session = sessionFactory.openSession();
		Transaction tx = null;

		try
		{
			tx = session.beginTransaction();
			session.save(customer);
			// We're done; make our changes permanent
			tx.commit();

		}
		catch (Exception e)
		{
			if (tx != null)
			{
				// Something went wrong; discard all partial changes
				tx.rollback();
			}
			throw e;
		}
		finally
		{
			// No matter what, close the session
			session.close();
		}
	}

	public void loadAndUpdateCustomer(Long customer_id, String address)
			throws Exception
	{
		// Ask for a session using the JDBC information we've configured
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();

			Customer c = (Customer) session.load(Customer.class, customer_id);

			c.setAddress(address);

			// We're done; make our changes permanent

			tx.commit();

		}
		catch (Exception e)
		{
			if (tx != null)
			{
				// Something went wrong; discard all partial changes
				tx.rollback();
			}
			throw e;
		}
		finally
		{
			// No matter what, close the session
			session.close();
		}
	}

	public void deleteAllCustomers() throws Exception
	{
		// Ask for a session using the JDBC information we've configured
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();

			Query query = session.createQuery("from Customer");

			List list = query.list();

			for (Iterator i = list.iterator(); i.hasNext();)
			{
				session.delete((Customer) i.next());
			}

			tx.commit();

		}
		catch (Exception e)
		{
			if (tx != null)
			{
				// Something went wrong; discard all partial changes
				tx.rollback();
			}
			throw e;
		}
		finally
		{
			// No matter what, close the session
			session.close();
		}
	}

	private void printCustomer(PrintStream out, Customer customer)
			throws Exception
	{

		byte[] buffer = customer.getImage();
		OutputStream fout = new FileOutputStream("photo_copy.gif");
		fout.write(buffer);
		fout.close();

		out.println("------如下是" + customer.getName() + "的我的信息------");
		out.println("ID: " + customer.getId());
		out.println("口令: " + customer.getPassword());
		out.println("E-Mail: " + customer.getEmail());
		out.println("電話: " + customer.getPhone());
		out.println("地址: " + customer.getAddress());
		String sex = customer.getSex() == 'M' ? "男" : "女";
		out.println("性別: " + sex);
		String marriedStatus = customer.isMarried() ? "已婚" : "未婚";
		out.println("婚姻情況: " + marriedStatus);
		out.println("生日: " + customer.getBirthday());
		out.println("註冊時間: " + customer.getRegisteredTime());
		out.println("自我介紹: " + customer.getDescription());

	}

	public void test(PrintStream out) throws Exception
	{

		Customer customer = new Customer();

		customer.setName("zhangsan");
		customer.setEmail("zhangsan@yahoo.com");
		customer.setPassword("1234");
		customer.setPhone(1381234);
		customer.setAddress("Shanghai");
		customer.setSex('M');
		customer.setDescription("I am very honest.");

		InputStream in = this.getClass().getResourceAsStream("photo.gif");

		byte[] buffer = new byte[in.available()];

		in.read(buffer);

		customer.setImage(buffer);

		customer.setBirthday(Date.valueOf("1980-05-06"));

		saveCustomer(customer);

		findAllCustomers(out);

		loadAndUpdateCustomer(customer.getId(), "Tianjin");

		findAllCustomers(out);

		deleteAllCustomers();
	}

	public static void main(String args[]) throws Exception
	{
		new HibernateTest().test(System.out);
		sessionFactory.close();
	}

}

經過給一下幾行代碼添加註釋的方式進行測試:ui

		saveCustomer(customer);

		findAllCustomers(out);

		loadAndUpdateCustomer(customer.getId(), "Tianjin");

		findAllCustomers(out);

		deleteAllCustomers();

運行後在hibernate2根目錄下面會生成一個photo_copy.gif圖形文件。

上面的例子比較簡單,下面咱們看一個複雜的:表與表之間存在關聯關係,類與類之間存在關聯關係:

新建一個名爲hibernate3的Java Project,導入相應的hibernate包(操做過程如以前所述)。

配置hibernate.cfg.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
    	<property name="show_sql">true</property> <!-- 屬性之間沒有上下關係,放在哪裏都行 -->
    	
    	<property name="connection.url">jdbc:mysql://localhost:3306/myhibernate3</property>
    	<property name="connection.username">root</property>
    	<property name="connection.password">root</property>
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	
    	<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
   
   		<mapping resource="Customer.hbm.xml"/> <!-- 將主配置文件包含對象-關係映射文件,之因此映射是由於hibernate啓動時只會加載主配置文件 -->
   		<mapping resource="Order.hbm.xml"/>
    </session-factory>

</hibernate-configuration>

接下來建立兩個域模型,一個是Customer,一個是Order:

src下面新建包com.test,在該包下面新建類:Customer.java:

package com.test;

import java.util.Set;

public class Customer
{
	private Long id;
	
	private String name;
	
	private Set orders; // 一對多,經過該變量能夠引用到對應的Order集合對象
	
	public Customer(String name, Set orders)
	{
		this.name = name;
		this.orders = orders;
	}
	
	// hibernate通常要求咱們提供一個不帶參數的構造方法,爲了符合hibernate要求,所以:
	public Customer()
	{
		
	}
	
	public Customer(Set orders)
	{
		this.orders = orders;
	}

	public Long getId()
	{
		return id;
	}

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

	public String getName()
	{
		return name;
	}

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

	public Set getOrders()
	{
		return orders;
	}

	public void setOrders(Set orders)
	{
		this.orders = orders;
	}

}

接着新建與Customer成多對一關係的Order.java類:

package com.test;

public class Order
{
	private Long id;
	
	private String orderNumber;
	
	private Customer customer; // 多對一,經過該變量能夠引用到對應的Customer

	public Order(String orderNumber, Customer customer)
	{
		this.orderNumber = orderNumber;
		this.customer = customer;
	}
	
	public Order()
	{
		
	}

	public Long getId()
	{
		return id;
	}

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

	public String getOrderNumber()
	{
		return orderNumber;
	}

	public void setOrderNumber(String orderNumber)
	{
		this.orderNumber = orderNumber;
	}

	public Customer getCustomer()
	{
		return customer;
	}

	public void setCustomer(Customer customer)
	{
		this.customer = customer;
	}
}

下面,在數據模型,寫配置文件,在這以前須要創建兩張表:

數據庫Schema:

create table customers(
	ID bigint not null,
	NAME varchar(15),
	primary key(ID)
);

create table orders(
	ID bigint not null,
	ORDER_NUMBER varchar(15),
	CUSTOMER_ID bigint not null,
	primary key(ID)
);

alter table orders add index IDX_CUSTOMER_ID(CUSTOMER_ID),
                   add constraint FK_CUSTOMER_ID foreign key (CUSTOMER_ID) references customers(ID);

接下來在src下建立Customer.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.test.Customer" table="customers"> <!-- 將類與表相關聯,使得類中的屬性和表中的字段關聯起來 -->
		
		<id name="id" column="id" type="long"> <!-- 類中id屬性和映射到表中的id字段,類型爲int/integer皆可 -->
			<generator class="increment"> <!-- 主鍵id的生成方式爲自增 -->
			</generator>
		</id>
	
		<property name="name" type="string">
			<column name="name" length="15"></column> <!-- 第二種定義column的方式,能夠進行精細化配置 -->
		</property> 
		
		<set name="orders" cascade="save-update" inverse="true"> <!-- 反轉屬性爲true,表示關聯關係由多的一方維持,這是hibernate的一個最佳實踐。 -->
			<key column="customer_id"></key> <!-- key元素設定與所關聯的持久化類對應的表的外鍵 -->
			<one-to-many class="com.test.Order"/>
		</set>

	</class>

</hibernate-mapping>

繼續在src下建立Order.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.test.Order" table="orders"> 
		
		<id name="id" column="id" type="long"> 
			<generator class="increment"> 
			</generator>
		</id>
	
		<property name="orderNumber" type="string">
			<column name="order_number" length="15"></column> 
		</property> 
		
		<many-to-one name="customer" column="customer_id" class="com.test.Customer">
		</many-to-one>

	</class>

</hibernate-mapping>

最後,不要忘記引入mysql的驅動:mysql-connector-java-5.1.34-bin.jar

而後,爲了驗證咱們的配置是否正確且如願生效,咱們編寫一個測試類,在com.test包下面新建一個類Test.java:

package com.test;

import java.util.HashSet;

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

public class Test
{
	public static SessionFactory sessionFactory;
	
	static 
	{
		try
		{
			sessionFactory = new Configuration().configure().
					buildSessionFactory();
		}
		catch(Exception ex)
		{
			System.out.println("exeception occured");
			ex.printStackTrace();
		}
	}
	
	public static void saveCustomerAndOrderWithCascade() throws Exception
	{
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		
		try
		{
			tx = session.beginTransaction();
			
			Customer customer = new Customer("zhangsan", new HashSet());
			
			Order order = new Order();
			order.setOrderNumber("zhangsan_order1");
			
			Order order2 = new Order();
			order2.setOrderNumber("zhangsan_order2");
			
			Order order3 = new Order();
			order3.setOrderNumber("zhangsan_order3");
			
			order.setCustomer(customer); // 將一的一方關聯到多的一方
			order2.setCustomer(customer);
			order3.setCustomer(customer);
			
			customer.getOrders().add(order); // 將多的一方增長到一的一方
			customer.getOrders().add(order2);
			customer.getOrders().add(order3);
			
			session.save(customer);
			
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
				tx.rollback();
			ex.printStackTrace();
		}
		finally
		{
			if(null != session)
				session.close();
		}
	}
	
	public static void main(String[] args) throws Exception
	{
		saveCustomerAndOrderWithCascade();
	}
}

執行結果:Console輸出:

Hibernate: select max(id) from customers
Hibernate: select max(id) from orders
Hibernate: insert into customers (name, id) values (?, ?)
Hibernate: insert into orders (order_number, customer_id, id) values (?, ?, ?)
Hibernate: insert into orders (order_number, customer_id, id) values (?, ?, ?)
Hibernate: insert into orders (order_number, customer_id, id) values (?, ?, ?)

進入數據庫中查看,咱們發現orders表中的外鍵已經關聯到customers表中的主鍵上了。

補充圖例:

下面,繼續進行探索,對於樹模型的關係——找到一個節點,能找到它的多個子節點(或者沒有)和惟一(或者沒有)的父節點,如:

首先創建域模型:在hibernate3項目下的com.test包下創建類:Category.java:

package com.test;

import java.util.Set;

public class Category
{
	private Long id;
	
	private String name;
	
	private Category parentCategory;
	
	private Set childCategories;
	
	public Category(String name, Category parentCategory, Set childCategories)
	{
		this.name = name;
		this.parentCategory = parentCategory;
		this.childCategories = childCategories;
	}
	
	public Category()
	{
		
	}
	
	public Category(Set childCategories)
	{
		this.childCategories = childCategories;
	}

	public Long getId()
	{
		return id;
	}

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

	public String getName()
	{
		return name;
	}

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

	public Category getParentCategory()
	{
		return parentCategory;
	}

	public void setParentCategory(Category parentCategory)
	{
		this.parentCategory = parentCategory;
	}

	public Set getChildCategories()
	{
		return childCategories;
	}

	public void setChildCategories(Set childCategories)
	{
		this.childCategories = childCategories;
	}
}

創建表,數據庫Schema:

create table categories(
	ID bigint not null,
	NAME varchar(15),
	CATEGORY_ID bigint,
	primary key(ID)
);

alter table categories add index IDX_CATEGORY_ID(CATEGORY_ID),
		       add constraint FK_CATEGORY_ID foreign key(CATEGORY_ID) references categories(ID);

創建Category.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.test.Category" table="categories"> <!-- 將類與表相關聯,使得類中的屬性和表中的字段關聯起來 -->
		
		<id name="id" column="id" type="long"> <!-- 類中id屬性和映射到表中的id字段,類型爲int/integer皆可 -->
			<generator class="increment"> <!-- 主鍵id的生成方式爲自增 -->
			</generator>
		</id>
	
		<property name="name" type="string">
			<column name="name" length="15"></column> <!-- 第二種定義column的方式,能夠進行精細化配置 -->
		</property> 
		
		<!-- 反轉屬性爲true,表示關聯關係由多的一方維持,這是hibernate的一個最佳實踐。 -->
		<set name="childCategories" cascade="all" inverse="true"> <!-- cascade="all"表示保存、更新或刪除當前對象時級聯其餘關聯的對象 -->
			<key column="category_id"></key> <!-- key元素設定與所關聯的持久化類對應的表的外鍵 -->
			<one-to-many class="com.test.Category"/>
		</set>
		
		<many-to-one name="parentCategory" column="category_id" class="com.test.Category">
		</many-to-one>
		
	</class>

</hibernate-mapping>

接下來,在Test.java中增長方法——saveCategoryWithCascade和deleteCategoryWithCascade:

package com.test;

import java.util.HashSet;

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

public class Test
{
	public static SessionFactory sessionFactory;
	
	static 
	{
		try
		{
			sessionFactory = new Configuration().configure().
					buildSessionFactory();
		}
		catch(Exception ex)
		{
			System.out.println("exeception occured");
			ex.printStackTrace();
		}
	}
	
	public static void saveCustomerAndOrderWithCascade() throws Exception
	{
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		
		try
		{
			tx = session.beginTransaction();
			
			Customer customer = new Customer("zhangsan", new HashSet());
			
			Order order = new Order();
			order.setOrderNumber("zhangsan_order1");
			
			Order order2 = new Order();
			order2.setOrderNumber("zhangsan_order2");
			
			Order order3 = new Order();
			order3.setOrderNumber("zhangsan_order3");
			
			order.setCustomer(customer); // 將一的一方關聯到多的一方
			order2.setCustomer(customer);
			order3.setCustomer(customer);
			
			customer.getOrders().add(order); // 將多的一方增長到一的一方
			customer.getOrders().add(order2);
			customer.getOrders().add(order3);
			
			session.save(customer);
			
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
				tx.rollback();
			ex.printStackTrace();
		}
		finally
		{
			if(null != session)
				session.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void saveCategoryWithCascade() throws Exception
	{
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			
			// 根據圖例,建立食品類別、蔬菜類別、水果類別、西紅柿類別、蘋果類別、桔子類別。
			Category foodCategory = new Category("food", null, new HashSet());
			Category fruitCategory = new Category("fruit", null, new HashSet());
			Category vegetableCategory = new Category("vegetable", null, new HashSet());
			Category appleCategory = new Category("apple", null, new HashSet());
			Category orangeCategory = new Category("orange", null, new HashSet());
			Category tomatoCategory = new Category("tomato", null, new HashSet());
			
			foodCategory.getChildCategories().add(fruitCategory);
			fruitCategory.setParentCategory(foodCategory);
			
			foodCategory.getChildCategories().add(vegetableCategory);
			vegetableCategory.setParentCategory(foodCategory);
			
			fruitCategory.getChildCategories().add(appleCategory);
			appleCategory.setParentCategory(fruitCategory);
			
			fruitCategory.getChildCategories().add(orangeCategory);
			orangeCategory.setParentCategory(fruitCategory);
			
			vegetableCategory.getChildCategories().add(tomatoCategory);
			tomatoCategory.setParentCategory(vegetableCategory);
			
			session.save(foodCategory); // 級聯保存全部的關聯對象
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
				tx.rollback();
			ex.printStackTrace();
		}
		finally
		{
			if(null != session)
				session.close();
		}
	
	}
	
	public static void deleteCategoryWithCascade() throws Exception
	{
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			
			// session.get和session.load方法完成的功能是同樣的,接受參數類型也是同樣的,它們之間的惟一差異在於根據主鍵尋找某一個對象
			// 若是找不到,get方法返回一個null,而load方法直接拋異常。
			Category category = (Category)session.load(Category.class, new Long(1));
			
			session.delete(category); // 級聯保存全部的關聯對象
			tx.commit();
		}
		catch(Exception ex)
		{
			if(null != tx)
				tx.rollback();
			ex.printStackTrace();
		}
		finally
		{
			if(null != session)
				session.close();
		}
	
	}
	
	public static void main(String[] args) throws Exception
	{
		// saveCustomerAndOrderWithCascade();
		// saveCategoryWithCascade();
		deleteCategoryWithCascade();
	}
}

最後在主配置文件hibernate.cfg.xml中增長對Category.hbm.xml文件的映射:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
    	<property name="show_sql">true</property> <!-- 屬性之間沒有上下關係,放在哪裏都行 -->
    	
    	<property name="connection.url">jdbc:mysql://localhost:3306/myhibernate3</property>
    	<property name="connection.username">root</property>
    	<property name="connection.password">root</property>
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	
    	<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
   
   		<mapping resource="Customer.hbm.xml"/> <!-- 將主配置文件包含對象-關係映射文件,之因此映射是由於hibernate啓動時只會加載主配置文件 -->
   		<mapping resource="Order.hbm.xml"/>
   		<mapping resource="Category.hbm.xml" />
    </session-factory>

</hibernate-configuration>

運行Test.java程序,能夠看到保存和刪除都已經實現了級聯操做。

下面咱們來看如何用hibernate表示一對一和多對多關係:

一對一在實際開發中用的也比較多,好比一我的對應一個身份證。這種一對一的關係可使用共用主鍵來表達。首先導入工程hibernate1(風中葉銀行企陪day6)

Student 和 Certificate 類及其相關的映射文件

package model;

public class Student
{
	private String id; // 標識id
	
	private String cardId; // 學號
	private String name; // 學生姓名
	private int age; // 歲數
	 
	private Certificate cer;// 身分證
	
	private Team team;// 班級

	public int getAge()
	{
		return age;
	}

	public String getName()
	{
		return name;
	}

	public String getCardId()
	{
		return cardId;
	}

	private void setId(String id)
	{
		this.id = id;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

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

	public void setCardId(String cardId)
	{
		this.cardId = cardId;
	}

	public String getId()
	{
		return id;
	}

	public Student()
	{ // 無參的構造函數
	}

	public Certificate getCer()
	{
		return cer;
	}

	public void setCer(Certificate pass)
	{
		this.cer = pass;
	}

	/**
	 * @return 返回 team。
	 */
	public Team getTeam()
	{
		return team;
	}

	/**
	 * @param team
	 *            要設置的 team。
	 */
	public void setTeam(Team team)
	{
		this.team = team;
	}
}
----------------------------------------------------------------------------
package model;

public class Certificate
{
	private String id;
	
	private String describe;
	
	private Student stu;

	/**
	 * @return 返回 stu。
	 */
	public Student getStu()
	{
		return stu;
	}

	/**
	 * @param stu
	 *            要設置的 stu。
	 */
	public void setStu(Student stu)
	{
		this.stu = stu;
	}

	/**
	 * @return 返回 describe。
	 */
	public String getDescribe()
	{
		return describe;
	}

	/**
	 * @param describe
	 *            要設置的 describe。
	 */
	public void setDescribe(String describe)
	{
		this.describe = describe;
	}

	/**
	 * @return 返回 id。
	 */
	public String getId()
	{
		return id;
	}

	/**
	 * @param id
	 *            要設置的 id。
	 */
	private void setId(String id)
	{
		this.id = id;
	}
}
-----------------------------------------------------------------
Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="model.Student" table="student" lazy="true"><!--把類和數表關聯起來-->
		
		<id name="id" unsaved-value="null"><!--id的產生方式是uuid.hex-->
			<generator class="uuid.hex" /> <!-- 或者寫uuid也能夠 -->
		</id>
		
		<property name="cardId" type="string" /><!--映射號-->
		<property name="name" type="string" /><!--映射學生名-->
		<property name="age" type="int" /><!--映射學生歲數-->
		
		
		
		<one-to-one name="cer" class="model.Certificate"  fetch="join" cascade="all"  /><!--映射對應的身分證對象-->
		
		
		
	</class>
</hibernate-mapping> 
----------------------------------------------------------------------------------------------------------
Certificate.hbm.xml:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="model.Certificate" table="certificate" lazy="true">
		
		<id name="id">
			<generator class="foreign">
				<param name="property" >stu</param> <!-- stu是Certificate類的一個成員變量 -->
			</generator>
		</id>
		<!-- describe是數據庫中的一個保留字,不能做爲字段名,所以須要加上``(鍵盤1左邊的) -->
		<property name="describe" column="`describe`" type="string" /> 
		
		<one-to-one name="stu" class="model.Student" fetch="select"
			constrained="true" cascade="none"/> <!-- cascade設置爲none說明身份證丟(刪除操做)了不能說明人沒了:~ -->
			
	</class>
</hibernate-mapping>

schema:

drop database if exists schoolproject;
create database schoolproject;
use schoolproject;

drop table if exists certificate;
CREATE TABLE certificate (
  id varchar(100) NOT NULL default '',
  `describe` varchar(100) default '',
  
  PRIMARY KEY  (id)
) ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_general_ci;


--
-- Dumping data for table 'certificate'
--

INSERT INTO certificate VALUES ('ff80808105416d3b0105416d3eca0001','tomclus');
INSERT INTO certificate VALUES ('ff808081054175b501054175b9190001','tom');

--
-- Table structure for table 'student'
--
drop table if exists student;
CREATE TABLE student (
  id varchar(100) NOT NULL default '',
  name varchar(20) default '',
  `cardId` varchar(20) NOT NULL default '',
  age int(11) default '0',
  PRIMARY KEY  (id)
) ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_general_ci;

--
-- Dumping data for table 'student'
--

INSERT INTO student VALUES ('ff80808105416d3b0105416d3eca0001','tomclus','200512345',33);
INSERT INTO student VALUES ('ff808081054175b501054175b9190001','tom','11111111',33);

BM.java(business manager) 

package BusinessManager;

import model.Certificate;
import model.Student;

import org.hibernate.HibernateException;

import persistence.StudentDAO;

public class BM
{
	public static void main(String[] args) throws HibernateException
	{
		Student stu = new Student();
		
		stu.setName("spark");
		stu.setCardId("200211332");
		stu.setAge(33);

		Certificate cer = new Certificate();
		cer.setDescribe("spark");

		//設定學生與身份證之間的關聯關係
		stu.setCer(cer);
		cer.setStu(stu);

		StudentDAO.saveObj(stu);
	}

}

下面是與之相關的類BaseDAO、StudentDAO、HibernateUtil:

package persistence;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * @author Administrator
 * 
 * TODO 要更改今生成的類型註釋的模板,請轉至 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
public class BaseDAO
{
	static Session session = null;
	static Transaction tx = null;

	/*------------建立新對象-----------------*/
	public static void saveObj(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			tx = session.beginTransaction(); // 開啓事務
			session.save(o);

			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			if (session != null)
				HibernateUtil.closeSession(session);
		}
	}

	/*------------刪除對象-----------------*/
	public static void delObject(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			Transaction tx = session.beginTransaction(); // 開啓事務
			session.delete(o);
			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}
	}

	/*------------修改對象-----------------*/
	public static void updateObj(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			Transaction tx = session.beginTransaction(); // 開啓事務
			session.update(o);
			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}
}
/*
 * 建立日期 2005-7-2
 *
 * TODO 要更改今生成的文件的模板,請轉至
 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
package persistence;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import model.Student;

import org.hibernate.FlushMode;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * @author Administrator
 * 
 * TODO 要更改今生成的類型註釋的模板,請轉至 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
public class StudentDAO extends BaseDAO
{
	static Session session = null;
	static Transaction tx = null;

	public static void update()
	{
		Student stu = null;
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			tx = session.beginTransaction(); // 開啓事務
			Query query = session.getNamedQuery("queryStudent_byAgeAdnName");

			query.setInteger("minAge", 25); // 設置「:」號後的minAge變量值
			query.setString("likeName", "%clus%");// 設置「:」號後的likeName變量值

			List list = query.list();
			for (int i = 0; i < list.size(); i++)
			{
				stu = (Student) list.get(i);
				System.out.println(stu.getName());
			}

			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}

}
package persistence;

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

public class HibernateUtil
{

	private static final SessionFactory sessionFactory;

	static
	{
		try
		{
			sessionFactory = new Configuration().configure()
					.buildSessionFactory();
		}
		catch (HibernateException ex)
		{
			throw new RuntimeException("Exception building SessionFactory: "
					+ ex.getMessage(), ex);
		}
	}

	public static Session currentSession()
	{
		Session s = sessionFactory.openSession();
		return s;
	}

	public static void closeSession(Session s)
	{
		s.close();
	}
}

引入MySql驅動,執行BM.java方法,執行一次保存操做後表中存儲的數據有:

mysql> select * from student;
+----------------------------------+---------+-----------+-----+
| id                               | name    | cardId    | age |
+----------------------------------+---------+-----------+-----+
| 40281f815004a9ef015004a9f0860001 | spark   | 200211332 |  33 |
| ff80808105416d3b0105416d3eca0001 | tomclus | 200512345 |  33 |
| ff808081054175b501054175b9190001 | tom     | 11111111  |  33 |
+----------------------------------+---------+-----------+-----+
3 rows in set

mysql> select * from certificate;
+----------------------------------+----------+
| id                               | describe |
+----------------------------------+----------+
| 40281f815004a9ef015004a9f0860001 | spark    |
| ff80808105416d3b0105416d3eca0001 | tomclus  |
| ff808081054175b501054175b9190001 | tom      |
+----------------------------------+----------+
3 rows in set

mysql> 

能夠看到一對一的主鍵關聯已經成功實現了。

一對一的第二種實現方式:其實仍是經過外鍵來關聯的(這種實現方式實際上就是退化了的一對多關聯)。重命名當前工做空間下的hibernate2項目,導入風中葉老師的hibernate2(day6),能夠看到Student.java、Certificate.java、Student.hbm.xml都沒用任何變換,惟一變化的是id的生成方式,和刪除了one-to-one標籤增長了many-to-one標籤。

Certificate.hbm.xml:

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
	<class name="model.Certificate" table="certificate" lazy="true">
		
		<id name="id">
			<generator class="uuid.hex" />
		</id>
		
		
		<property name="describe" column="`describe`" type="string" />
		
		
		<many-to-one name="stu" 
			class="model.Student"  
			unique="true" <!-- 多對一,而多的一方又是惟一的,暗示着多對一已經退化成了一對一了 -->
			column="stu_id" <!-- 外鍵 -->
		/>  <!-- 惟一的多對一,實際也就變成一對一關係了 -->
		
		
		
	</class>
</hibernate-mapping>

數據庫schema:

drop database if exists schoolproject;
create database schoolproject;
use schoolproject;
--
-- Table structure for table `certificate`
--
DROP TABLE IF EXISTS `certificate`;
CREATE TABLE `certificate` (
  `id` varchar(100) NOT NULL default '',
  `describe` varchar(100) default '',
  `stu_id` varchar(32) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `certificate`
--


/*!40000 ALTER TABLE `certificate` DISABLE KEYS */;
LOCK TABLES `certificate` WRITE;
INSERT INTO `certificate` VALUES ('5abfa70605c5356f0105c53573360002','tomclus','5abfa70605c5356f0105c535730e0001');
INSERT INTO `certificate` VALUES ('5abfa70605c535a60105c535aa370002','tom','5abfa70605c535a60105c535aa040001');
UNLOCK TABLES;
/*!40000 ALTER TABLE `certificate` ENABLE KEYS */;

--
-- Table structure for table `student`
--

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` varchar(100) NOT NULL default '',
  `name` varchar(20) default '',
  `cardId` varchar(20) NOT NULL default '',
  `age` int(11) default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `student`
--


/*!40000 ALTER TABLE `student` DISABLE KEYS */;
LOCK TABLES `student` WRITE;
INSERT INTO `student` VALUES ('5abfa70605c5356f0105c535730e0001','tomclus','200212345',33);
INSERT INTO `student` VALUES ('5abfa70605c535a60105c535aa040001','tom','200254321',33);
UNLOCK TABLES;

執行BM.java,裏面的代碼跟以前的如出一轍。能夠看到certificate表的stu_id已經和student表的id關聯起來了。

下面咱們來看相對來講最複雜的一種:多對多的映射類型

重命名當前項目下的hibernate3,導入風中葉老師的hibernate3(day6),咱們看一下學生和課程之間的多對多經過hibernate如何實現。

多對多在程序中如何體現:兩個類Student、Course,分別定義兩個集合類型的變量:

package model;

import java.util.Set;

public class Student
{
	private String id; // 標識id
	
	private String cardId; // 學號
	private String name; // 學生姓名
	private int age; // 歲數
	
	
	private Set Courses;// 課程

	public int getAge()
	{
		return age;
	}

	public String getName()
	{
		return name;
	}

	public String getCardId()
	{
		return cardId;
	}

	private void setId(String id)
	{
		this.id = id;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

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

	public void setCardId(String cardId)
	{
		this.cardId = cardId;
	}

	public String getId()
	{
		return id;
	}

	public Student()
	{ // 無參的構造函數
	}

	/**
	 * @return 返回 courses。
	 */
	public Set getCourses()
	{
		return Courses;
	}

	/**
	 * @param courses
	 *            要設置的 courses。
	 */
	public void setCourses(Set courses)
	{
		Courses = courses;
	}
}
package model;

import java.util.HashSet;
import java.util.Set;

public class Course
{
	private String id;
	private String name;
	
	private Set Students = new HashSet();

	/**
	 * @return 返回 id。
	 */
	public String getId()
	{
		return id;
	}

	/**
	 * @param id
	 *            要設置的 id。
	 */
	public void setId(String id)
	{
		this.id = id;
	}

	/**
	 * @return 返回 name。
	 */
	public String getName()
	{
		return name;
	}

	/**
	 * @param name
	 *            要設置的 name。
	 */
	public void setName(String name)
	{
		this.name = name;
	}

	/**
	 * @return 返回 students。
	 */
	public Set getStudents()
	{
		return Students;
	}

	/**
	 * @param students
	 *            要設置的 students。
	 */
	public void setStudents(Set students)
	{
		Students = students;
	}
}

而在數據庫中要想體現多對多的關係,就須要使用鏈接表,鏈接表中的內容就是stu_id和course_id。一條這樣的記錄,就表示一個映射:該學生選擇了該課程,該課程被該學生所選。

Student.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

	<class name="model.Student" table="student" 
		select-before-update="true"><!--把類和數表關聯起來-->
		
		<id name="id" unsaved-value="null"><!--id的產生方式是uuid.hex-->
			<generator class="uuid.hex" />
		</id>
		
		<property name="cardId" type="string" /><!--映射號-->
		<property name="name" type="string" /><!--映射學生名-->
		<property name="age" type="int" /><!--映射學生歲數-->
		
<!-- 若是不設置inverse爲true的話,會拋出約束違規異常,Duplicate entry。由於inverse的默認值爲false,表示本身維持級聯關係,這樣在執行save操做時,student和course都要維持(向表中插入一條記錄)就會拋異常 -->
<!-- cascade絕對不能設爲all或者delete,由於刪除課程不能刪除學生,刪除了一個學生也不該該把這個學生的課程刪除 -->
		<set name="courses" table="student_course"
			cascade="none" inverse="true"> 
			<key column="stu_id" /> <!-- 字段stu_id表明中間表student_course中的字段 -->
			
			<many-to-many class="model.Course"
				column="course_id" /> <!-- 字段course_id表明中間表student_course中的字段 -->
		</set>
		
		
		
	</class>
</hibernate-mapping>

Course.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="model.Course" table="course" 
		select-before-update="true"><!--把類和數表關聯起來-->
		
		<id name="id" unsaved-value="null" ><!--id的產生方式是uuid.hex-->
			<generator class="uuid.hex" />
		</id>
		
		<property name="name" type="string" /><!--映射課程名-->
		
		<set name="students" table="student_course"
			cascade="save-update">
			<key column="course_id" />
			<many-to-many class="model.Student"
				column="stu_id" />
		</set>
	</class>
</hibernate-mapping>

數據庫schema:

drop database if exists schoolproject;
create database schoolproject;
use schoolproject;
--
-- Table structure for table `course`
--

DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` varchar(32) NOT NULL default '',
  `name` varchar(45) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `course`
--


/*!40000 ALTER TABLE `course` DISABLE KEYS */;
LOCK TABLES `course` WRITE;
INSERT INTO `course` VALUES ('5abfe4c705ca8ee00105ca8ee45d0002','history');
INSERT INTO `course` VALUES ('5abfe4c705ca8f5e0105ca8f62400002','computer');
INSERT INTO `course` VALUES ('5abfe4c705ca8faf0105ca8fb3750002','music');
INSERT INTO `course` VALUES ('5abfe4c705ca901f0105ca9024290002','ecnomic');
INSERT INTO `course` VALUES ('5abfe4c705ca98420105ca98475a0001','politics');
UNLOCK TABLES;
/*!40000 ALTER TABLE `course` ENABLE KEYS */;

--
-- Table structure for table `student`
--

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` varchar(100) NOT NULL default '',
  `name` varchar(20) default '',
  `cardId` varchar(20) NOT NULL default '',
  `age` int(11) default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `student`
--


/*!40000 ALTER TABLE `student` DISABLE KEYS */;
LOCK TABLES `student` WRITE;
INSERT INTO `student` VALUES ('5abfe4c705ca8ee00105ca8ee42b0001','tomclus','1',25);
INSERT INTO `student` VALUES('5abfe4c705ca8f5e0105ca8f620d0001','tom','2',25);
INSERT INTO `student` VALUES('5abfe4c705ca8faf0105ca8fb3390001','spark','3',25);
INSERT INTO `student` VALUES('5abfe4c705ca901f0105ca9023f70001','jerry','4',25);
UNLOCK TABLES;
/*!40000 ALTER TABLE `student` ENABLE KEYS */;

--
-- Table structure for table `student_course`
--

DROP TABLE IF EXISTS `student_course`;
CREATE TABLE `student_course` (
  `stu_id` varchar(32) NOT NULL default '',
  `course_id` varchar(32) NOT NULL default '',
  PRIMARY KEY  (`stu_id`,`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `student_course`
--


/*!40000 ALTER TABLE `student_course` DISABLE KEYS */;
LOCK TABLES `student_course` WRITE;
INSERT INTO `student_course` VALUES ('5abfe4c705ca8ee00105ca8ee42b0001','5abfe4c705ca8ee00105ca8ee45d0002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8ee00105ca8ee42b0001','5abfe4c705ca8f5e0105ca8f62400002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8ee00105ca8ee42b0001','5abfe4c705ca8faf0105ca8fb3750002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8f5e0105ca8f620d0001','5abfe4c705ca8f5e0105ca8f62400002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8f5e0105ca8f620d0001','5abfe4c705ca901f0105ca9024290002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8faf0105ca8fb3390001','5abfe4c705ca8f5e0105ca8f62400002');
INSERT INTO `student_course` VALUES ('5abfe4c705ca8faf0105ca8fb3390001','5abfe4c705ca8faf0105ca8fb3750002');
UNLOCK TABLES;

相關類BM.java、StudentDAO.java、BaseDAO、HibernateUtil.java:

package BusinessManager;

import org.hibernate.HibernateException;

import persistence.StudentDAO;

public class BM
{
	public static void main(String[] args) throws HibernateException
	{

		StudentDAO.mdfChoice();

	}

}
/*
 * 建立日期 2005-7-2
 *
 * TODO 要更改今生成的文件的模板,請轉至
 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
package persistence;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import model.Course;
import model.Student;

import org.hibernate.FlushMode;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * @author Administrator
 * 
 * TODO 要更改今生成的類型註釋的模板,請轉至 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
public class StudentDAO extends BaseDAO
{
	static Session session = null;
	static Transaction tx = null;

	public static void mdfChoice()
	{
		Set set = new HashSet();
		
		Student stu = null;
		Course course = null;

		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			
			tx = session.beginTransaction(); // 開啓事務
			
			stu = (Student) session.createQuery(
					"from Student s where s.name ='tomclus'").uniqueResult();
			
			
			
			
			course = (Course) session.createQuery(
					"from Course c where c.name='ecnomic'").uniqueResult();
			
			
			stu.getCourses().add(course);
			course.getStudents().add(stu);

			tx.commit();
		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}

}
/*
 * 建立日期 2005-7-2
 *
 * TODO 要更改今生成的文件的模板,請轉至
 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
package persistence;

import model.Student;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * @author Administrator
 * 
 * TODO 要更改今生成的類型註釋的模板,請轉至 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
public class BaseDAO
{
	static Session session = null;
	static Transaction tx = null;

	/*------------建立新對象-----------------*/
	public static void createObj(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			tx = session.beginTransaction(); // 開啓事務
			session.save(o);

			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			if (session != null)
				HibernateUtil.closeSession(session);
		}
	}

	/*------------刪除對象-----------------*/
	public static void delObject(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			tx = session.beginTransaction(); // 開啓事務
			session.delete(o);
			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}
	}

	/*------------修改對象-----------------*/
	public static void mdfObj(Object o)
	{
		try
		{
			session = HibernateUtil.currentSession(); // 開啓鏈接
			tx = session.beginTransaction(); // 開啓事務
			session.update(o);
			tx.commit();

		}
		catch (HibernateException e)
		{ // 捕捉例外
			e.printStackTrace();
			tx.rollback();
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}
}
package persistence;

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

public class HibernateUtil
{

	private static final SessionFactory sessionFactory;

	static
	{
		try
		{
			sessionFactory = new Configuration().configure()
					.buildSessionFactory();
		}
		catch (HibernateException ex)
		{
			throw new RuntimeException("Exception building SessionFactory: "
					+ ex.getMessage(), ex);
		}
	}

	public static Session currentSession()
	{
		Session s = sessionFactory.openSession();
		return s;
	}

	public static void closeSession(Session s)
	{
		s.close();
	}
}

執行BM.java類,學生表和課程表沒有任何變化,惟一變化的是中間表多了一行記錄,用於映射新創建的學生和課程之間的關係。

補充知識點:域對象在持久化層的三種狀態

相關文章
相關標籤/搜索