通过示例休眠–第1部分(删除孤儿)
先決條件 :
為了嘗試以下示例,您將需要以下提到的JAR文件:
- org.springframework.aop-3.0.6.RELEASE.jar
- org.springframework.asm-3.0.6.RELEASE.jar
- org.springframework.aspects-3.0.6.RELEASE.jar
- org.springframework.beans-3.0.6.RELEASE.jar
- org.springframework.context.support-3.0.6.RELEASE.jar
- org.springframework.context-3.0.6.RELEASE.jar
- org.springframework.core-3.0.6.RELEASE.jar
- org.springframework.jdbc-3.0.6.RELEASE.jar
- org.springframework.orm-3.0.6.RELEASE.jar
- org.springframework.transaction-3.0.6.RELEASE.jar。
- org.springframework.expression-3.0.6.RELEASE.jar
- commons-logging-1.0.4.jar
- log4j.jar
- aopalliance-1.0.jar
- dom4j-1.1.jar
- hibernate-commons-annotations-3.2.0.Final.jar
- hibernate-core-3.6.4.Final.jar
- hibernate-jpa-2.0-api-1.0.0.Final.jar
- javax.persistence-2.0.0.jar
- jta-1.1.jar
- javassist-3.1.jar
- slf4j-api-1.6.2.jar
- mysql-connector-java-5.1.13-bin.jar
- commons-collections-3.0.jar
對于希望eclipse項(xiàng)目進(jìn)行嘗試的任何人,您都可以在此處下載帶有上述JAR依賴項(xiàng)的文件。
簡介 :
成立于2011年。正義聯(lián)盟(Justice League)的規(guī)模過大,正在尋找開發(fā)商來幫助創(chuàng)建超級英雄注冊系統(tǒng)。 熟悉Hibernate和ORM的開發(fā)人員已準(zhǔn)備好使用Hibernate來完成系統(tǒng)和處理持久層的工作。 為簡單起見,他將使用一個(gè)簡單的獨(dú)立應(yīng)用程序來保留超級英雄。 這是此示例的布局方式:
- 桌子設(shè)計(jì)
- 域類和Hibernate映射
- DAO和服務(wù)類
- 應(yīng)用程序的Spring配置
- 一個(gè)簡單的主類,展示所有工作原理
讓旅程開始……………………。
表格設(shè)計(jì):
設(shè)計(jì)由三個(gè)簡單的表格組成,如下圖所示;
如您所見,它是一個(gè)簡單的一對多關(guān)系,由聯(lián)接表鏈接。 Hibernate將使用Join Table來填充域類中的Super hero列表,我們將在下一步繼續(xù)查看。
域類和Hibernate映射:
與主要擁有實(shí)體(正義聯(lián)盟實(shí)體)鏈接的聯(lián)接表主要只有兩個(gè)域類。 因此,讓我們繼續(xù)看看如何使用注釋構(gòu)造域類。
package com.justice.league.domain;import java.io.Serializable;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;import org.hibernate.annotations.Type;@Entity @Table(name = "SuperHero") public class SuperHero implements Serializable {/*** */private static final long serialVersionUID = -6712720661371583351L;@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "super_hero_id")private Long superHeroId;@Column(name = "super_hero_name")private String name;@Column(name = "power_description")private String powerDescription;@Type(type = "yes_no")@Column(name = "isAwesome")private boolean isAwesome;public Long getSuperHeroId() {return superHeroId;}public void setSuperHeroId(Long superHeroId) {this.superHeroId = superHeroId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPowerDescription() {return powerDescription;}public void setPowerDescription(String powerDescription) {this.powerDescription = powerDescription;}public boolean isAwesome() {return isAwesome;}public void setAwesome(boolean isAwesome) {this.isAwesome = isAwesome;}} 因?yàn)槲覍ySQL用作主要數(shù)據(jù)庫,所以我將GeneratedValue策略用作GenerationType.AUTO ,只要創(chuàng)建了新的超級英雄,它將自動進(jìn)行遞增。 所有其他映射都為大家所熟悉,除了
我們將布爾值映射到數(shù)據(jù)庫中Char字段的最后一個(gè)變量。
我們在數(shù)據(jù)庫字段中使用Hibernate的@Type批注將true&false表示為Y&N。 Hibernate有許多@Type實(shí)現(xiàn),您可以在這里閱讀。 在這種情況下,我們使用了這種類型。
好了,現(xiàn)在我們有了代表超級英雄的班級,讓我們繼續(xù)看一下我們的正義聯(lián)盟領(lǐng)域的模樣,這將保留所有對聯(lián)盟表示忠誠的超級英雄。
package com.justice.league.domain;import java.io.Serializable; import java.util.ArrayList; import java.util.List;import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.Table;@Entity @Table(name = "JusticeLeague") public class JusticeLeague implements Serializable {/*** */private static final long serialVersionUID = 763500275393020111L;@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "justice_league_id")private Long justiceLeagueId;@Column(name = "justice_league_moto")private String justiceLeagueMoto;@Column(name = "number_of_members")private Integer numberOfMembers;@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)@JoinTable(name = "JUSTICE_LEAGUE_SUPER_HERO", joinColumns = { @JoinColumn(name = "justice_league_id") }, inverseJoinColumns = { @JoinColumn(name = "super_hero_id") })private List<SuperHero> superHeroList = new ArrayList<SuperHero>(0);public Long getJusticeLeagueId() {return justiceLeagueId;}public void setJusticeLeagueId(Long justiceLeagueId) {this.justiceLeagueId = justiceLeagueId;}public String getJusticeLeagueMoto() {return justiceLeagueMoto;}public void setJusticeLeagueMoto(String justiceLeagueMoto) {this.justiceLeagueMoto = justiceLeagueMoto;}public Integer getNumberOfMembers() {return numberOfMembers;}public void setNumberOfMembers(Integer numberOfMembers) {this.numberOfMembers = numberOfMembers;}public List<SuperHero> getSuperHeroList() {return superHeroList;}public void setSuperHeroList(List<SuperHero> superHeroList) {this.superHeroList = superHeroList;}}這里要注意的重要事實(shí)是注釋@OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.EAGER,orphanRemoval = true) 。 在這里,我們設(shè)置了orphanRemoval = true 。
那到底是做什么的呢?
好吧,假設(shè)您的聯(lián)賽中有一群超級英雄。 并說一個(gè)超級英雄是干草堆。 所以我們需要從聯(lián)盟中移除他/她。 使用JPA級聯(lián),由于無法檢測孤立記錄,因此這是不可能的 然后您將擁有刪除了“超級英雄”的數(shù)據(jù)庫,而您的收藏中仍然有對它的引用。
在JPA 2.0之前,您沒有orphanRemoval支持,并且是刪除孤立記錄的唯一方法
是要使用以下Hibernate特定(或ORM特定)注釋,現(xiàn)在已棄用 ;
@ org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
但是,通過引入屬性orphanRemoval,我們現(xiàn)在能夠通過JPA處理孤立記錄的刪除。
現(xiàn)在我們有了Domain類
DAO和服務(wù)類:
為了保持良好的設(shè)計(jì)標(biāo)準(zhǔn),我將DAO(數(shù)據(jù)訪問對象)層和服務(wù)層分開。 因此,讓我們看一下DAO的界面和實(shí)現(xiàn)。 請注意,我有
通過HibernateDAOSupport使用了HibernateTemplate ,從而避免了任何特定于Hibernate的細(xì)節(jié),并使用Spring以統(tǒng)一的方式訪問所有內(nèi)容。
在接口層中,我已根據(jù)需要定義了事務(wù)處理。 這樣做是為了使每當(dāng)不需要事務(wù)時(shí),您都可以在該特定方法的方法級別定義它,在更多情況下,您將需要事務(wù)
除了數(shù)據(jù)檢索方法。 ?
根據(jù)JPA規(guī)范,您需要一個(gè)有效的事務(wù)來執(zhí)行插入/刪除/更新功能 。
因此,讓我們看一下DAO的實(shí)現(xiàn);
package com.justice.league.dao.hibernate;import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;import com.justice.league.dao.JusticeLeagueDAO; import com.justice.league.domain.JusticeLeague;@Qualifier(value="justiceLeagueHibernateDAO") public class JusticeLeagueHibernateDAOImpl extends HibernateDaoSupportimplements JusticeLeagueDAO {@Overridepublic void createOrUpdateJuticeLeagure(JusticeLeague league) {if (league.getJusticeLeagueId() == null) {getHibernateTemplate().persist(league);} else {getHibernateTemplate().update(league);}}@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = false) public JusticeLeague retrieveJusticeLeagueById(Long id){return getHibernateTemplate().get(JusticeLeague.class, id);}} 在這里,我定義了一個(gè)@Qualifier,以讓Spring知道這是DAO類的Hibernate實(shí)現(xiàn)。 請注意以休眠結(jié)尾的軟件包名稱。 在我看來,這是一個(gè)很好的設(shè)計(jì)概念,可遵循的將您的實(shí)現(xiàn)分離為
分開包裝以保持設(shè)計(jì)整潔。
好的,讓我們繼續(xù)進(jìn)行服務(wù)層的實(shí)現(xiàn)。 在這種情況下,服務(wù)層只是充當(dāng)調(diào)用DAO方法的中介層。 但是在現(xiàn)實(shí)世界的應(yīng)用程序中,您可能會在服務(wù)層中進(jìn)行其他驗(yàn)證,與安全性相關(guān)的過程等。
package com.justice.league.service;import com.justice.league.domain.JusticeLeague;public interface JusticeLeagureService {public void handleJusticeLeagureCreateUpdate(JusticeLeague justiceLeague);public JusticeLeague retrieveJusticeLeagueById(Long id); }package com.justice.league.service.impl;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component;import com.justice.league.dao.JusticeLeagueDAO; import com.justice.league.domain.JusticeLeague; import com.justice.league.service.JusticeLeagureService;@Component("justiceLeagueService") public class JusticeLeagureServiceImpl implements JusticeLeagureService {@Autowired@Qualifier(value = "justiceLeagueHibernateDAO")private JusticeLeagueDAO justiceLeagueDAO;@Overridepublic void handleJusticeLeagureCreateUpdate(JusticeLeague justiceLeague) {justiceLeagueDAO.createOrUpdateJuticeLeagure(justiceLeague);}public JusticeLeague retrieveJusticeLeagueById(Long id){return justiceLeagueDAO.retrieveJusticeLeagueById(id);} }這里沒有什么要注意的。 首先,@ Component在春天上下文中將此服務(wù)實(shí)現(xiàn)與名稱JusticeLeagueService綁定在一起,以便我們可以將bean稱為ID為JusticeLeagueService的bean 。
并且我們已經(jīng)自動連接了JusticeLeagueDAO并定義了一個(gè)@Qualifier,以便它將綁定到Hibernate實(shí)現(xiàn)。
Qualifier的值應(yīng)與我們在DAO Implementation類中為類級別Qualifier賦予的名稱相同。
最后,讓我們看一下將所有這些連接在一起的Spring配置。
應(yīng)用程序的Spring配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><context:component-scan base-package="com.justice.league" /><context:annotation-config /><tx:annotation-driven /><bean id="sessionFactory"class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="packagesToScan"><list><value>com.justice.league.**.*</value></list></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop><prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/my_test</prop><prop key="hibernate.connection.username">root</prop><prop key="hibernate.connection.password">password</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop></props></property></bean><bean id="justiceLeageDAO"class="com.justice.league.dao.hibernate.JusticeLeagueHibernateDAOImpl"><property name="sessionFactory" ref="sessionFactory" /></bean><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean></beans> 請注意,在我單獨(dú)運(yùn)行它的情況下,我在此實(shí)例中使用了HibernateTransactionManager 。 如果你是
在應(yīng)用服務(wù)器中運(yùn)行它,您幾乎總是會使用JTA事務(wù)管理器。
為了簡化起見,我還使用了由hibernate自動創(chuàng)建表的方法。 packagesToScan屬性指示掃描根包com.justice.league。**。*下的所有子包(包括嵌套在其中的嵌套包)為
掃描@Entity注釋的類。
我們還將會話工廠限制在了JusticeLeagueDAO上,以便我們可以使用Hibernate Template。
為了進(jìn)行測試,您可以根據(jù)需要最初使用標(biāo)簽<prop key =“ hibernate.hbm2ddl.auto”> create </ prop> ,然后讓hibernate為您創(chuàng)建表。
好了,現(xiàn)在我們已經(jīng)看到了應(yīng)用程序的構(gòu)建塊,讓我們首先在正義聯(lián)盟內(nèi)創(chuàng)建一些超級英雄,看看它們?nèi)绾喂ぷ?
一個(gè)簡單的主類來展示所有工作原理:
作為第一個(gè)示例,讓我們看看我們將如何通過幾個(gè)超級英雄來維持正義聯(lián)盟。
package com.test;import java.util.ArrayList; import java.util.List;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.justice.league.domain.JusticeLeague; import com.justice.league.domain.SuperHero; import com.justice.league.service.JusticeLeagureService;public class TestSpring {/*** @param args*/public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");JusticeLeagureService service = (JusticeLeagureService) ctx.getBean("justiceLeagueService");JusticeLeague league = new JusticeLeague();List<SuperHero> superHeroList = getSuperHeroList();league.setSuperHeroList(superHeroList);league.setJusticeLeagueMoto("Guardians of the Galaxy");league.setNumberOfMembers(superHeroList.size());service.handleJusticeLeagureCreateUpdate(league);}private static List<SuperHero> getSuperHeroList() {List<SuperHero> superHeroList = new ArrayList<SuperHero>();SuperHero superMan = new SuperHero();superMan.setAwesome(true);superMan.setName("Clark Kent");superMan.setPowerDescription("Faster than a speeding bullet");superHeroList.add(superMan);SuperHero batMan = new SuperHero();batMan.setAwesome(true);batMan.setName("Bruce Wayne");batMan.setPowerDescription("I just have some cool gadgets");superHeroList.add(batMan);return superHeroList;}}如果我們進(jìn)入數(shù)據(jù)庫并進(jìn)行檢查,我們將看到以下輸出;
mysql> select * from superhero; +---------------+-----------+-----------------+-------------------------------+ | super_hero_id | isAwesome | super_hero_name | power_description | +---------------+-----------+-----------------+-------------------------------+ | 1 | Y | Clark Kent | Faster than a speeding bullet | | 2 | Y | Bruce Wayne | I just have some cool gadgets | +---------------+-----------+-----------------+-------------------------------+mysql> select * from justiceleague; +-------------------+-------------------------+-------------------+ | justice_league_id | justice_league_moto | number_of_members | +-------------------+-------------------------+-------------------+ | 1 | Guardians of the Galaxy | 2 | +-------------------+-------------------------+-------------------+如您所見,我們堅(jiān)持了兩位超級英雄,并將他們與正義聯(lián)盟聯(lián)系在一起。 現(xiàn)在,讓我們看看下面的示例如何刪除孤兒。
package com.test;import java.util.ArrayList; import java.util.List;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.justice.league.domain.JusticeLeague; import com.justice.league.domain.SuperHero; import com.justice.league.service.JusticeLeagureService;public class TestSpring {/*** @param args*/public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");JusticeLeagureService service = (JusticeLeagureService) ctx.getBean("justiceLeagueService");JusticeLeague league = service.retrieveJusticeLeagueById(1l);List<SuperHero> superHeroList = league.getSuperHeroList();/*** Here we remove Batman(a.k.a Bruce Wayne) out of the Justice League* cos he aint cool no more*/for (int i = 0; i < superHeroList.size(); i++) {SuperHero superHero = superHeroList.get(i);if (superHero.getName().equalsIgnoreCase("Bruce Wayne")) {superHeroList.remove(i);break;}}service.handleJusticeLeagureCreateUpdate(league);}}在這里,我們首先通過主鍵檢索正義聯(lián)盟的記錄。 然后,我們循環(huán)瀏覽并從聯(lián)盟中刪除蝙蝠俠,然后再次調(diào)用createOrUpdate方法。 當(dāng)我們定義了刪除孤兒時(shí),所有不在數(shù)據(jù)庫列表中的超級英雄都將被刪除。
再次,如果查詢數(shù)據(jù)庫,我們將看到蝙蝠俠已經(jīng)按照以下說明被刪除了;
mysql> select * from superhero; +---------------+-----------+-----------------+-------------------------------+ | super_hero_id | isAwesome | super_hero_name | power_description | +---------------+-----------+-----------------+-------------------------------+ | 1 | Y | Clark Kent | Faster than a speeding bullet | +---------------+-----------+-----------------+-------------------------------+就是這樣了。 正義聯(lián)盟(Justice League)如何使用休眠模式自動刪除蝙蝠俠而無需費(fèi)心自己做的故事。
接下來,我們將期待美國隊(duì)長如何使用休眠標(biāo)準(zhǔn)來構(gòu)建靈活的查詢,以便找到可能的敵人。 小心!!!!
祝大家有美好的一天,并感謝您的閱讀!
如果您有任何建議或意見,請不要理會。
參考:“ 通過示例進(jìn)行休眠–第1部分(除去孤兒)”,來自我們的JCG合作伙伴 Dinuka Arseculeratne,在“ My Journey Through IT”博客中
相關(guān)文章 :- 休眠陷阱
- 休眠自動提交命令強(qiáng)制MySQL在過多的磁盤I / O中運(yùn)行
- DataNucleus 3.0與Hibernate 3.5
- Hibernate映射集合性能問題
- Spring MVC3 Hibernate CRUD示例應(yīng)用程序
- Java教程和Android教程列表
翻譯自: https://www.javacodegeeks.com/2011/11/hibernate-by-example-part-1-orphan.html
總結(jié)
以上是生活随笔為你收集整理的通过示例休眠–第1部分(删除孤儿)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 水的ph值是什么意思 水的ph值介绍
- 下一篇: 美团退款商家拒绝了还能再申请吗