Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]

1、项目结构:

     Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]

1.1、场景说明: 一个订单,包含多个产品

1.2、类文件:

    Order.java 

package com.rhythmk.model;



import java.util.Date;



public class Order {

    public int getOrderID() {

		return orderID;

	}



	public void setOrderID(int orderID) {

		this.orderID = orderID;

	}



	public String getName() {

		return Name;

	}



	public void setName(String name) {

		Name = name;

	}



	public double getSumMoney() {

		return SumMoney;

	}



	public void setSumMoney(double sumMoney) {

		SumMoney = sumMoney;

	}



	public Date getCreateDate() {

		return createDate;

	}



	public void setCreateDate(Date createDate) {

		this.createDate = createDate;

	}



	private  int  orderID;

    private String  Name;

    private double SumMoney;

    

    @Override

	public String toString() {

		return "Order [orderID=" + orderID + ", Name=" + Name + ", SumMoney="

				+ SumMoney + ", createDate=" + createDate + "]";

	}



	private Date createDate;

    

}

 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.rhythmk.model.Order" table="t_order">

        <id name="orderID" type="int">

            <column name="orderID" />

            <generator class="native" />

        </id>

        <property name="Name" type="string">

            <column name="Name" not-null="true" />

        </property>

       <property name="SumMoney" type="double"></property>

        <property name="createDate" type="timestamp">

            <column name="createDate" not-null="true" />

        </property>

     

    </class>

</hibernate-mapping>

    Product.java

package com.rhythmk.model;



public class Product {

	public int getProductID() {

		return productID;

	}



	public void setProductID(int productID) {

		this.productID = productID;

	}



	public String getProductName() {

		return productName;

	}



	public void setProductName(String productName) {

		this.productName = productName;

	}



	private int productID;

	private String productName;

	

	public Order getOrder() {

		return order;

	}



	public void setOrder(Order order) {

		this.order = order;

	}



	private Order order ;



	@Override

	public String toString() {

		return "Product [productID=" + productID + ", productName="

				+ productName + ", order=" + order + "]";

	}

	

}

  product.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.rhythmk.model.Product" table="t_product">

        <id name="productID" type="int">

            <column name="productID" />

            <generator class="native" />

        </id>

        <property name="productName" type="string">

            <column name="productName"  />

        </property>

           <many-to-one name="order"   column="orderID"></many-to-one> 

     

    </class>

</hibernate-mapping>

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="dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_demo</property>

        <property name="connection.username">root</property>

        <property name="connection.password">wangkun</property>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property>

        <!--是否在后台显示Hibernate用到的SQL语句,开发时设置为true,便于差错,程序运行时可以在Eclipse的控制台显示Hibernate的执行Sql语句。项目部署后可以设置为false,提高运行效率 -->

        <property name="hibernate.show_sql">true </property>

        <property name="hibernate.hbm2ddl.auto">update</property>

        

          <mapping  resource="com/rhythmk/model/user.hbm.xml" />

         <mapping  resource="com/rhythmk/model/product.hbm.xml" /> 

          <mapping resource="com/rhythmk/model/order.hbm.xml" />

    </session-factory>



</hibernate-configuration>

 

1.3  、结论:

        在Many方 定义XML配置  :

      <many-to-one name="order"   column="orderID"></many-to-one> 

   写入数据调用session.save方法跟单表保存基本一致。

   读取数据:获取Many对象,默认 One对象都是以延迟加载模式进行加载。

    不论是删除 Many ,还是删除 One 对象 都只删除本身数据 ,并非删除全部主从数据,如果删除One对象,一旦Many还有关联One的对象的存在,则将抛出异常。见(test04_del)

 1.4  、测试验证:

@Test

	public void test02_add() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			session.beginTransaction();

			Order order = new Order();

			order.setCreateDate(new Date());

			order.setName("订单一");

			order.setSumMoney(12);

			session.save(order);



			Product p1 = new Product();

			p1.setOrder(order);

			p1.setProductName("产品1");

			session.save(p1);



			Product p2 = new Product();

			p2.setOrder(order);

			p2.setProductName("产品2");

			session.save(p2);



			session.getTransaction().commit();



		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  输出:

Hibernate: insert into t_order (Name, SumMoney, createDate) values (?, ?, ?)
Hibernate: insert into t_product (productName, orderID) values (?, ?)
Hibernate: insert into t_product (productName, orderID) values (?, ?)

	@Test

	public void test03_load() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			Order order = (Order) session.load(Order.class, 1);

			System.out.println(order);

			System.out.println("-----------Read  Product-----------");

			Product product = (Product) session.load(Product.class, 1);

			System.out.println("-----------Print  Product-----------");

			System.out.println(product);

			System.out.println("-----------Read  Order-----------");

			System.out.println(product.getOrder().getName());

	



		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

	

	

  

输出:

Hibernate: select order0_.orderID as orderID1_0_0_, order0_.Name as Name2_0_0_, order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as createDa4_0_0_ from t_order order0_ where order0_.orderID=?
Order [orderID=1, Name=订单一, SumMoney=12.0, createDate=2014-05-02 15:24:02.0]
-----------Read Product-----------
-----------Print Product-----------
Hibernate: select product0_.productID as productI1_1_0_, product0_.productName as productN2_1_0_, product0_.orderID as orderID3_1_0_ from t_product product0_ where product0_.productID=?
Product [productID=1, productName=产品1, order=Order [orderID=1, Name=订单一, SumMoney=12.0, createDate=2014-05-02 15:24:02.0]]
-----------Read Order-----------
订单一

	@Test

	public void test04_Get() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

		

			System.out.println("-----------Read  Product-----------");

			Product product = (Product) session.get(Product.class, 1);

			System.out.println("-----------Print  Product-----------");

			System.out.println(product);

			System.out.println("-----------Read  Order-----------");

			System.out.println(product.getOrder().getName());

	

		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  输出:

-----------Read Product-----------
Hibernate: select product0_.productID as productI1_1_0_, product0_.productName as productN2_1_0_, product0_.orderID as orderID3_1_0_ from t_product product0_ where product0_.productID=?
-----------Print Product-----------
Hibernate: select order0_.orderID as orderID1_0_0_, order0_.Name as Name2_0_0_, order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as createDa4_0_0_ from t_order order0_ where order0_.orderID=?
Product [productID=1, productName=产品1, order=Order [orderID=1, Name=订单一, SumMoney=12.0, createDate=2014-05-02 15:24:02.0]]
-----------Read Order-----------
订单一

  

	@Test

	public void test04_Del() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			session.beginTransaction();

			/*

			

			Product product = (Product) session.get(Product.class, 1);

			session.delete(product);

		输出:

		Hibernate: select product0_.productID as productI1_1_0_, product0_.productName as productN2_1_0_, product0_.orderID as orderID3_1_0_ from t_product product0_ where product0_.productID=?

        Hibernate: delete from t_product where productID=?

		*/	

			Order order = (Order) session.get(Order.class, 3);

			session.delete(order);

			

			

			session.getTransaction().commit();

		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  输出:


Hibernate: select order0_.orderID as orderID1_0_0_, order0_.Name as Name2_0_0_, order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as createDa4_0_0_ from t_order order0_ where order0_.orderID=?
Hibernate: delete from t_order where orderID=?
org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)

 

-------------------------------------------------OneToMany----------------------------------------------------------------------------

>>> OneToMany  单相关联

 

 

2.1   

 需求背景:

   每个人都有很多标签:

在User 类中添加:

 

	public Set<Tag> getTags() {

		return tags;

	}

	public void setTags(Set<Tag> tags) {

		this.tags = tags;

	}

	private Set<Tag> tags;

 

  同时 添加 Tag类:

package com.rhythmk.model;



public class Tag {

   public Integer getTagId() {

		return tagId;

	}

	public void setTagId(Integer tagId) {

		this.tagId = tagId;

	}

	public String getTagTitle() {

		return tagTitle;

	}

	public void setTagTitle(String tagTitle) {

		this.tagTitle = tagTitle;

	}

	public Integer getUserID() {

		return userID;

	}

	@Override

	public String toString() {

		return "Tag [tagId=" + tagId + ", tagTitle=" + tagTitle + ", userID="

				+ userID + "]";

	}

	public void setUserID(Integer userID) {

		this.userID = userID;

	}

private Integer  tagId;

   private String tagTitle;

   private Integer userID;

}

  

 

添加User对应XML配置:

 

        <set name="tags">

            <key column="userID"></key>

            <!--   此处需要配置完成的类别-->

            <one-to-many class="com.rhythmk.model.Tag" />

        </set>

 

注意:此处 one-to-many 对应的 class 需要填写类的全路径名称

2.2  验证:

@Test

	public void test01_add() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			session.beginTransaction();

			Tag t1 = new Tag();

			t1.setTagTitle("tag1");



			Tag t2 = new Tag();

			t2.setTagTitle("tag2");



			Set<Tag> tags = new HashSet<Tag>();

			tags.add(t1);

			tags.add(t2);



			User entity = new User();

			entity.setUserName("张飞2222");

			entity.setCreateTime(new Date());



			entity.setTags(tags);

			session.save(t1);

			session.save(t2);

			session.save(entity);



			session.getTransaction().commit();



		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  输出:

Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName, createTime) values (?, ?)
Hibernate: update t_tag set userID=? where tagId=?
Hibernate: update t_tag set userID=? where tagId=?

@Test

	public void test02_get() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			session.beginTransaction();



			System.err.println("------01 -----------");

			User entity = (User) session.get(User.class, 6);

			System.err.println("------02 -----------");

			for (Tag t : entity.getTags()) {

				System.out.println(t);

			}



			session.getTransaction().commit();



		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  

输出:

------01 -----------
Hibernate: select user0_.userID as userID1_3_0_, user0_.userName as userName2_3_0_, user0_.createTime as createTi3_3_0_ from t_user user0_ where user0_.userID=?
------02 -----------
Hibernate: select tags0_.userID as userID3_3_0_, tags0_.tagId as tagId1_2_0_, tags0_.tagId as tagId1_2_1_, tags0_.tagTitle as tagTitle2_2_1_ from t_tag tags0_ where tags0_.userID=?
Tag [tagId=2, tagTitle=tag1, userID=null]
Tag [tagId=3, tagTitle=tag2, userID=null]

 

 >>> OneToMany  双相关联

背景:一个标签下有多少人

调整原标签代码:

 

      <set name="users">

            <key column="tagId"></key>

            <!--   此处需已在hibernate-mapping   上配置了 类包名-->

            <one-to-many class="User" />

        </set>

 

one-to-many  class仅填写类名 现将包名调整到 hibernate-mapping属性上 如:

<hibernate-mapping  package="com.rhythmk.model">

调整 Tag.java,添加:

	public Set<User> getUsers() {

		return users;

	}



	public void setUsers(Set<User> users) {

		this.users = users;

	}



	private Set<User> users;

测试:

@Test

	public void test01_add() {

		Session session = null;

		try {

			session = HibernateUtil.getSessionFactory().openSession();

			session.beginTransaction();

			Tag t1 = new Tag();

			t1.setTagTitle("tag1");



			Tag t2 = new Tag();

			t2.setTagTitle("tag2");



			Set<Tag> tags = new HashSet<Tag>();

			tags.add(t1);

			tags.add(t2);



			User u1 = new User();

			u1.setUserName("张飞2222");

			u1.setCreateTime(new Date());

			u1.setTags(tags);



			User u2 = new User();

			u2.setUserName("张飞2333332");

			u2.setCreateTime(new Date());

			u2.setTags(tags);



			Set<User> users = new HashSet<User>();

			users.add(u1);

			users.add(u2);



			t1.setUsers(users);



			t2.setUsers(users);



			session.save(t1);

			session.save(t2);

			session.save(u1);

			session.save(u2);

			session.getTransaction().commit();



		} catch (Exception e) {

			e.printStackTrace();

		} finally {

			if (session != null)

				session.close();

		}

	}

  输出:

 

  

Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName, createTime) values (?, ?)
Hibernate: insert into t_user (userName, createTime) values (?, ?)
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_tag set userID=? where tagId=?
Hibernate: update t_tag set userID=? where tagId=?
Hibernate: update t_tag set userID=? where tagId=?
Hibernate: update t_tag set userID=? where tagId=?

注意:此处因为在提交事务过程中 Tag 以及User都相互影响变化,故出现12条SQL。

   在实际项目中 我们并非需要 One 跟 Many都同时去维护数据,故引入 inverse,当inverse="true" 则不去维护对应关系,现修改User.hbm.xml  如下:

<set name="tags" lazy="extra" inverse="true">

            <key column="userID"></key>

            <!--   此处需要配置完成的类别-->

            <one-to-many class="com.rhythmk.model.Tag" />

        </set>

执行测试输出:

Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName, createTime) values (?, ?)
Hibernate: insert into t_user (userName, createTime) values (?, ?)
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=? where userID=?

 

 

 

代码下载地址:

http://pan.baidu.com/s/1gdFt7ur

 

 

 

 

你可能感兴趣的:(Hibernate)