1、創建兩個實體類。
一個實體類是商品類,另一個實體類是商品的分類類。
在一對多關系的兩個實體中,在編寫實體類時必須要遵循以下規則:
(1)在一的那一方的實體中,必須要有一個私有的多那一方的實體對象屬性,並且提供公有的getter和setter方法。
private Integer gid; private String gname; private String gmessage; /** * 在一對多關系中,在一的這一方,必須要有一個多的對象的私有屬性 * 別提供共有的getter和setter方法。 */ private Sort sort; public Sort getSort() { return sort; } public void setSort(Sort sort) { this.sort = sort; }
(2)在多的那一方的實體類中,必須要有一個私有的set集合屬性來保存一的那一方的對象,並提供公有的getter和setter屬性。
private Integer sid; private String gname; private String gmessage; /** * 在一對多關系中,在多的那一方,必須要有一個set集合屬性來保存一個那個實體 * 並提供共有的getter和setter方法。 */ private Set<Good> getSet = new HashSet<Good>(); public Set<Good> getGetSet() { return getSet; } public void setGetSet(Set<Good> getSet) { this.getSet = getSet; }
2、編寫兩個實體類的映射文件。
(1)一的那一方的映射文件。
在一的這一方,需要使用<many-to-one>標簽來配置對應關系。
<hibernate-mapping> <class name="com.jack.entity.Good" table="t_good"> <id name="gid" column="gid"> <generator class="native"></generator> </id> <property name="gname" column="gname"></property> <property name="gmessage" column="gmessage"></property> <!-- 表示商品所屬的分類 name屬性的值:因為在Good商品實體中,用sort表示Sort實體類,所有這里寫sort class屬性的值:sort類的全路徑 column屬性的值:外鍵的名稱 --> <many-to-one name="sort" class="com.jack.entity.Sort" column="gsid"></many-to-one> </class> </hibernate-mapping>
(2)多的那一方的映射文件。
在多的這一方,需要使用<set>標簽來配置對應關系。
<hibernate-mapping> <class name="com.jack.entity.Sort" table="t_sort"> <id name="sid" column="sid"> <generator class="native"></generator> </id> <property name="sname" column="sname"></property> <property name="smessage" column="smessage"></property> <!-- 在多的這一邊使用set標簽來設置對應關系 name屬性的值:因為在Sort中使用getSet保存good屬性。 column屬性的值:外鍵的名稱,由於在Hibernate使用雙向維護主鍵 所有在這邊的column的值必須要和另一邊的值一致 class屬性的值:Good實體類的全路徑。 --> <set name="getSet"> <key column="gsid"></key> <one-to-many class="com.jack.entity.Good" /> </set> </class> </hibernate-mapping>
3、編寫核心配置文件
<hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name=" hibernate.current_session_context_class">thread</property> <mapping resource="com/jack/entity/Good.hbm.xml"/> <mapping resource="com/jack/entity/Sort.hbm.xml"/> </session-factory> </hibernate-configuration>
4、編寫工具類
public class HibernateUtils { private static Configuration configuration = null; private static SessionFactory sessionFactory = null; static{ configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } public static Session getSeeion() { return sessionFactory.getCurrentSession(); } }
5、編寫級聯保存代碼
第一種代碼(復雜):
@Test public void TestAdd(){ Session session = null; Transaction tx = null; try { session = HibernateUtils.getSeeion(); tx = session.beginTransaction(); /** * 創建兩個商品 */ Good good1 = new Good(); good1.setGname("蛋糕"); good1.setGmessage("奶油蛋糕"); Good good2 =new Good(); good2.setGname("牙膏"); good2.setGmessage("冷酸靈牙膏"); /** * 創建兩個類別 */ Sort sort1 =new Sort(); sort1.setSname("食品"); sort1.setSmessage("食品類"); Sort sort2 = new Sort(); sort2.setSname("生活用品"); sort2.setSmessage("生活用品類"); /** * 將商品放到類別中 */ sort1.getGetSet().add(good1); sort2.getGetSet().add(good2); /** * 將類別設置到商品中 */ good1.setSort(sort1); good2.setSort(sort2); /** * 保存類別 * 保存商品 */ session.save(sort1); session.save(sort2); session.save(good1); session.save(good2); tx.commit(); } catch (Exception e) { tx.rollback(); }finally{ } }
第二種代碼(簡單):
首先在多的那一方的配置文件的<set>標簽內,寫入cascade屬性,其值為save-update。
<set name="getSet" cascade="save-update"> <key column="gsid"></key> <one-to-many class="com.jack.entity.Good" /> </set>
然后編寫代碼
@Test public void TestAdd2(){ Session session = null; Transaction tx = null; try { session = HibernateUtils.getSeeion(); tx = session.beginTransaction(); /** * 創建兩個商品 */ Good good3 = new Good(); good3.setGname("面包"); good3.setGmessage("面包"); /** * 獲得食品類 */ Sort sort1 = session.get(Sort.class, 1); /** * 將商品放到類別中 */ sort1.getGetSet().add(good3); /** * 保存類別 * 現在只需要保存類別,商品也會自動保存 */ session.save(sort1); tx.commit(); } catch (Exception e) { tx.rollback(); }finally{ } }
6、Hibernate默認雙方都要維護主鍵,這樣會降低效率,通過配置inverse屬性可以讓一方放棄維護主鍵,這樣可以提高操作效率。一般讓多的那一方放棄。
<!-- true:表示不維護 false:表示維護主鍵 默認為false,維護主鍵 --> <set name="getSet" cascade="save-update" inverse="true"> <key column="gsid"></key> <one-to-many class="com.jack.entity.Good" /> </set>
7、測試結果
8、級聯刪除
首先配置cascade屬性,值為delete
<set name="getSet" cascade="save-update,delete" inverse="true"> <key column="gsid"></key> <one-to-many class="com.jack.entity.Good" /> </set>
編寫代碼實現刪除(刪除食品類)
@Test public void TestDelete(){ Session session = null; Transaction tx = null; try { session = HibernateUtils.getSeeion(); tx = session.beginTransaction(); /** * 找到食品類 */ Sort sort = session.get(Sort.class, 1); /** 刪除食品類 */ session.delete(sort); tx.commit(); } catch (Exception e) { tx.rollback(); }finally{ } }
測試結果:
9、級聯修改
修改前數據庫
修改代碼(把蛋糕放到生活用品中):
@Test public void TestUpdate(){ Session session = null; Transaction tx = null; try { session = HibernateUtils.getSeeion(); tx = session.beginTransaction(); /** * 找到生活用品 */ Sort sort = session.get(Sort.class, 2); /** * 找到蛋糕 */ Good good =session.get(Good.class, 4); /** * 把蛋糕放到生活用品中去 */ sort.getGetSet().add(good); /** * 把生活用品設置到蛋糕中去 */ good.setSort(sort); tx.commit(); } catch (Exception e) { tx.rollback(); }finally{ } }
修改之后結果: