http://sourceforge.net/projects/hibernate/files/
先决æ¡äšgåQ?/font>
å·²ç»å®‰è£…äº?/span>antå’?/span>MySQLæ•°æ®åº“,数æ®åº“表已ç»å»ºç«‹ã€?/span>
1ã€?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> ä»?/span>Hibernate官方¾|‘站下è²Middlegen-Hibernateå’?/span>hibernate-extensionsåQŒåƈ解压ã€?/span>
2ã€?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> é…ç½®Middlegen-Hibernate:
2.1 é…置数æ®åº“连æŽ?/span>
å‡è®¾˜qžæŽ¥çš„æ•°æ®åº“æ˜?/span>MySQLåQŒåœ¨Middlegen-Hibernate-r5\config\databaseç›®å½•ä¸æœ‰ä¸€ä¸?/span>mysql.xmlæ–‡äšgåQŒæ˜¯ç”¨æ¥é…ç½®MySQLæ•°æ®åº“çš„˜qžæŽ¥çš„ã€‚å†…å®¹äØ“åQ?/span>
<property name="database.script.file" value="${src.dir}/sql/${name}-mysql.sql"/>
<property name="database.driver.file" value="${lib.dir}/mysql-connector-java-3.0.15-ga-bin.jar"/>
<property name="database.driver.classpath" value="${database.driver.file}"/>
<property name="database.driver" value="org.gjt.mm.mysql.Driver"/>
<property name="database.url" value="jdbc:mysql://localhost/jboss"/>
<property name="database.userid" value="jboss"/>
<property name="database.password" value="jboss"/>
<property name="database.schema" value=""/>
<property name="database.catalog" value=""/>
<property name="jboss.datasource.mapping" value="mySQL"/>
ž®?/span>mysql-connector-java-3.0.15-ga-bin.jar拯‚´åˆ?/span>${lib.dir}åQŒä¹Ÿž®±æ˜¯Middlegen-Hibernate-r5\lib目录ã€?/span>
修改é…置文äšgä¸çš„æ•°æ®åº“连接项ç›?/span>database.urlã€?/span>database.useridã€?/span>database.userid ä½?/span>Middlegen-Hibernateå¯ä»¥æ‰‘Öˆ°æ•°æ®åº“ã€?/span>
2.2 é…ç½®Middlegen-Hibernate-r5çš?/span>ant˜q行文äšgbuild.xml
<!DOCTYPE project [
<!ENTITY database SYSTEM "file:./config/database/mysql.xml">
]>
指出使用的数æ®åº“é…置文äšgã€?/font>
<project name="Middlegen Hibernate" default="all" basedir=".">
<property file="${basedir}/build.properties"/>
<property name="name" value="hibernatesample"/>
æŒ‡å‡ºä½ çš„åº”ç”¨åç§°ã€?/font>
<property name="build.gen-src.dir" value="C:/sample"/>
指出hbmçš„è¾“å‡ø™µ\径ã€?/span>
<hibernate
destination="${build.gen-src.dir}"
package="org.hibernate.sample"
genXDocletTags="false"
genIntergratedCompositeKeys="false"
javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"
/>
指出hbm所在的包的ä½ç½®ã€?/span>
指出hbm.xml䏿˜¯å¦éœ€è¦?/span>XDoclet Tagsã€?/span>
3ã€?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> ˜q行Middlegen-Hibernate:
åœ?/span>Middlegen-Hibernate目录下è¿è¡?/span>antåQŒè¿›å…?/span>Middlegen-Hibernate的图形界é¢ã€‚å¯ä»¥è®¾¾|®è¡¨åQŒå’Œå—æ®µçš„ç‰¹æ€§ã€‚ç„¶åŽæŒ‰GenarateåQŒäñ”ç”?/span>hbm.xmlæ–‡äšgã€?/span>
4ã€?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> é…ç½®hibernate-extensions
åœ?/span>hibernate-extensions-2.1.2\tools\bin目录有一ä¸?/span>setenv.batæ–‡äšgåQŒæ”¹å˜å…¶å†…容为:
set JDBC_DRIVER=C:\java\Middlegen-Hibernate-r5\lib\mysql-connector-java-3.0.15-ga-bin.jar
set HIBERNATE_HOME=C:\java\hibernate-2.1.6
set CORELIB=%HIBERNATE_HOME%\lib
set LIB=..\lib
set PROPS=%HIBERNATE_HOME%\src
set CP=%JDBC_DRIVER%;%PROPS%;%HIBERNATE_HOME%\hibernate2.jar;%CORELIB%\commons-logging-1.0.4.jar;%CORELIB%\commons-collections-2.1.1.jar;%CORELIB%\commons-lang-1.0.1.jar;%CORELIB%\cglib-full-2.0.2.jar;%CORELIB%\dom4j-1.4.jar;%CORELIB%\odmg-3.0.jar;%CORELIB%\xml-apis.jar;%CORELIB%\xerces-2.4.0.jar;%CORELIB%\xalan-2.4.0.jar;%LIB%\jdom.jar;%LIB%\..\hibernate-tools.jar
注愾U¢è‰²å—体æç¤ºçš„凿˜¯èµ\径和JARæ–‡äšgåï¼Œä¸€å®šè¦æ£ç¡®ã€?/span>
5ã€è¿è¡?/span>hibernate-extensionsåQŒæ ¹æ?/span>hbm.xml产生POJOæ–‡äšg
åœ?/span>DOSä¸è¿è¡?/span>hbm2java c:\sample\org\hibernate\sample\*.xml --output=c:\sample\Student.hbm.xml
...
<hibernate-mapping>
<class name="model.Student" table="student">
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
<property name="name" type="string"/>
<set name="courses"
table="student_course"
cascade="save-update"
>
<key column="stu_id"/>
<many-to-many class="model.Course
column="course_id"/>
</set>
<class>
</hibernate-mapping>
多对多关¾p»éœ€è¦é…¾|®çš„属性比较多一些。åˆå¦è€…ç»å¸æ€¼šæŠ?lt;key column=""/>å’?lt;column="">çš„å€?br />
弄å了,其实åªè¦è®îC½ä¸€ä¸ªåŽŸåˆ™ï¼š<key column="">æ€ÀL˜¯å’Œæœ¬íw«ç±»çš„主键id对应åQŒè€?lt;column="">
æ€ÀL˜¯ä¸Žå…³è”类的主键id相对应。对于上é¢çš„Student.hbm.xml,å…Œ™”¾cÀL˜¯Course,本èín¾cÕdˆ™æ˜¯Student
Course.hbm.xml
...
<hibernate-mapping>
<class name="model.Course" table="course">
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
<propery name="name" type="string"/>
<set name="students"
table="student_course"
cascade="save-update"
>
<key columm="course_id"/>
<many-to-many class="model.Student"
column="stu_id"/>
</set>
</class>
</hibernate-mapping>
注æ„åQšStudent与Courseçš„cascade都设¾|®äØ“save-updateåQŒåœ¨å¤šå¯¹å¤šçš„关系ä¸ï¼Œall,delete½{?br />
cascade是没有æ„义的åQŒå› 为多对多关系ä¸ï¼Œòq¶ä¸èƒ½å› ä¸ºçˆ¶å¯¹è±¡è¢«åˆ é™¤ï¼Œè€Œé€ æˆè¢«åŒ…括的å对è±?br />
è¢«åˆ é™¤ï¼Œå› äØ“å¯èƒ½˜q˜æœ‰å…¶ä»–的父对象å‚考了˜q™ä¸ªå对象ã€?/span>
å¦å¤–åQŒåœ¨å¤šå¯¹å¤šå…³¾pÖM¸åQŒå¦‚æžœåŒæ–šwƒ½æœ‰æŽ§åˆ¶æƒåQˆä¹Ÿž®±æ˜¯åŒæ–¹éƒ½æ²¡æœ‰è®¾¾|®inverse="true"åQ‰ï¼Œåˆ?br /> åŒæ–¹éƒ½è¦æŠŠå…³è”å…³¾pÕdæ˜ åˆ°æ•°æ®åº“。必™åÕdœ¨æŸä¸€æ–¹è®¾¾|®inverse="true"åQŒç„¶åŽåœ¨æ‰§è¡Œè¯å¥æ—¶ä‹Éç”?br /> ä¸ÀLŽ§æ–¹è¿›è¡Œæ“作(也就是没有设¾|®inverse="true"的那一方)ã€?/strong>
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20))); |
detachedCriteria.getExecutableCriteria(session).list(); |
HibernateTemplate.execute(new HibernateCallback() {  public Object doInHibernate(Session session) throws HibernateException {   ....  } } |
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); detachedCriteria.createAlias("employees", "e").add(Restrictions.eq("name", "department")).add(Restrictions.gt(("e.age"), new Integer(20))); departmentManager.findByCriteria(detachedCriteria); |
public List findByCriteria(final DetachedCriteria detachedCriteria) {  return (List) getHibernateTemplate().execute(new HibernateCallback() {   public Object doInHibernate(Session session) throws HibernateException {    Criteria criteria = detachedCriteria.getExecutableCriteria(session);    return criteria.list();   }  }); } |
Criteria criteria = detachedCriteria.getExecutableCriteria(session); return criteria.list(); |
private boolean exposeNativeSession = false; ... |
Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session)); |
public Criteria getExecutableCriteria(Session session) {  impl.setSession( (SessionImpl) session ); // è¦æ±‚SessionImplåQŒSpringä¼ é€’çš„æ˜¯Proxy  return impl; } |
public List findByCriteria(final DetachedCriteria detachedCriteria) {  return (List) getHibernateTemplate().execute(new HibernateCallback() {   public Object doInHibernate(Session session) throws HibernateException {    Criteria criteria = detachedCriteria.getExecutableCriteria(session);    return criteria.list();   }  }, true); } |
一对多ã€å¤šå¯¹å¤šåQˆæœ«ç«¯äؓ多)的情况:在集åˆçš„é…ç½®ä¸è®¾¾|®ï¼Œä»?set ä¸ÞZ¾‹åQŒå¦‚下所½Cºï¼š
<set name="students" inverse="true" cascade="all" lazy="false" batch-size="2" ><!-- 一对多的åšg˜qŸåŠ è½½è®¾¾|?-->
<key>
<column name="TEAMID" length="32" not-null="true" />
</key>
<one-to-many class="edu.dgut.ke.model.Student" />
</set>
一对一ã€å¤šå¯¹ä¸€åQˆæœ«ç«¯äؓ一åQ‰çš„æƒ…况åQšå¦‚æžœè¦å¯ÒŽœ«ç«¯äؓ一的关è”设¾|®æ‰¹é‡åŠ è½½ï¼Œè¦åœ¨“一”˜q™ç«¯çš„é…¾|®æ–‡ä»¶ä¸˜q›è¡Œè®„¡½®åQŒæ¯”如å¦ç”Ÿå¯¹íw«ä†¾è¯ï¼Œè¦å®žçް坹ççñ”的批é‡åŠ è½½ï¼Œåº”è®¾¾|®å¦‚ä¸?br />
<class name="edu.dgut.ke.model.Certificate" table="CERTIFICATE" lazy="true" batch-size="10" >
‹¹‹è¯•例å
1.ä¸ç®¡A¾cÕd¯¹property1在酾|®æ–‡ä»‰™‡Œæ˜¯ä»€ä¹ˆç–ç•?å¯èƒ½æ˜¯é¢„先抓å?ç«‹å³æˆ–åšg˜qŸæ£€ç´?它们都失æ•?,˜q™æ—¶éƒ½é‡‡ç”¨HQL指定的左外连æŽ?左外˜qžæŽ¥å¿…定会åˆå§‹åŒ–property1属æ€?或对è±?,但是如果é…置文äšg里对property1的检索ç–ç•¥æ˜¯å»¶è¿ŸåŠ è²,A¾cÕd¾— 到对properyt1的引ç”?ä¸ÞZº†å¾—到˜q™ä¸ªå¼•用,需è¦å†‹Æ¡å‘é€ä¸€æ¡SQLè¯å¥æ¥ç¡®ç«‹è¿™¿U引用关¾p?˜q™ç§æƒ…况在property1ä¸ºé›†åˆæ—¶¾l常出现.
2.A¾cÕdœ¨é…置文äšgä¸è®¾¾|®çš„对property2的预先抓å–ç–略将被忽ç•?/strong>(ä¸ç®¡˜q™ä¸ª½{–略是fetch或是select),对property2有媄å“的讄¡½®æ˜¯ç«‹å›_’Œå»¶è¿ŸåŠ è²,hibernateåªçœ‹å¾—到˜q™ä¸¤¿Uç–ç•?所以在使用è¯å¥"from A as a left outer join a.property1"æ—?property2çš„åŠ è½½ç–略将仅由lazy="true"或者是lazy="false"æ¥å†³å®?nbsp;
Team.hbm.xml
... ...
<set name="students" inverse="true" cascade="all" lazy="true" fetch="join"><!-- 一对多的åšg˜qŸåŠ è½½è®¾¾|?-->
<key>
<column name="TEAMID" length="32" not-null="true" />
</key>
<one-to-many class="edu.dgut.ke.model.Student" />
</set>
... ...
Student.hbm.xml
... ...
<many-to-one name="certificate"
class="edu.dgut.ke.model.Certificate"
unique="true"
column="cardId"
cascade="all"
lazy="false"
fetch="join">
</many-to-one>
<many-to-one name="team" class="edu.dgut.ke.model.Team" fetch="join">
<column name="TEAMID" length="32" not-null="true" />
</many-to-one>
... ...
‹¹‹è¯•代ç
Session session = HibernateSessionFactory.getSession();
List list = session.createQuery("from Student as s left join s.team").list();
HibernateSessionFactory.closeSession();
//list 包括两个长度ä¸?的数¾l?æ¯ä¸€ä¸ªæ•°¾l„ä¸åŒ…括一个å¦ç”Ÿå¯¹è±¡å’Œä¸€ä¸ªç¾U§å¯¹è±?br />
Object[] stuAndTeam1 = (Object[]) list.get(0);
Student stu = (Student) stuAndTeam1[0];
System.out.println(stu.getStudentname());
System.out.println(stu.getTeam().getTeamname());
System.out.println(stu.getTeam().getStudents().size());
很多½E‹åºéœ€è¦åœ¨æŸä¸ªäº‹åŠ¡ä¸èŽ·å–对象,然厞®†å¯¹è±¡å‘é€åˆ°ç•Œé¢å±‚去æ“作åQŒæœ€åŽåœ¨ä¸€ä¸ªæ–°çš„事务ä¿å˜æ‰€åšçš„修改ã€?在高òq¶å‘讉K—®çš„环境ä¸ä½¿ç”¨˜q™ç§æ–¹å¼åQŒé€šå¸¸ä½¿ç”¨é™„带版本信æ¯çš„æ•°æ®æ¥ä¿è¯˜q™äº›“é•?#8220;工作å•元之间的隔¼›…R€?
Hibernate通过æä¾›ä½¿ç”¨Session.update()æˆ?tt class="literal" style="color: #0000ff">Session.merge()æ–ÒŽ³• 釿–°å…Œ™”è„Þq®¡å®žä¾‹çš„åŠžæ³•æ¥æ”¯æŒ˜q™ç§æ¨¡åž‹ã€?
// in the first session Cat cat = (Cat) firstSession.load(Cat.class, catId); Cat potentialMate = new Cat(); firstSession.save(potentialMate); // in a higher layer of the application cat.setMate(potentialMate); // later, in a new session secondSession.update(cat); // update cat secondSession.update(mate); // update mate
如果å…ähœ‰catIdæŒä¹…åŒ–æ ‡è¯†çš„Cat之å‰å·²ç»è¢?tt class="literal">å¦ä¸€Session(secondSession)装è²äº†ï¼Œ 应用½E‹åº˜q›è¡Œé‡å…³è”æ“ä½?reattach)的时候会抛出一个异常ã€?
å¦‚æžœä½ ç¡®å®šå½“å‰session没有包å«ä¸Žä¹‹å…ähœ‰ç›¸åŒæŒä¹…åŒ–æ ‡è¯†çš„æŒä¹…实例åQŒä‹Éç”?tt class="literal">update()ã€?å¦‚æžœæƒ³éšæ—¶åˆòq¶ä½ 的的改动而ä¸è€ƒè™‘session的状æ€ï¼Œä½¿ç”¨merge()ã€?/strong> æ¢å¥è¯è¯´åQŒåœ¨ä¸€ä¸ªæ–°sessionä¸é€šå¸¸½W¬ä¸€ä¸ªè°ƒç”¨çš„æ˜?tt class="literal">update()æ–ÒŽ³•åQŒä»¥ä¾¿ä¿è¯é‡æ–°å…³è”脱½Ž?detached)对象的æ“作首先被执行ã€?
希望相关è”çš„è„Þq®¡å¯¹è±¡åQˆé€šè¿‡å¼•用“å¯åˆ°è¾?#8221;的脱½Ž¡å¯¹è±¡ï¼‰çš„æ•°æ®ä¹Ÿè¦æ›´æ–°åˆ°æ•°æ®åº“æ—¶åQˆåƈ且也仅仅在这¿U情况)åQ?应用½E‹åºéœ€è¦å¯¹è¯¥ç›¸å…Œ™”的脱½Ž¡å¯¹è±¡å•独调ç”?tt class="literal">update() 当然˜q™äº›å¯ä»¥è‡ªåŠ¨å®ŒæˆåQŒå³é€šè¿‡ä½¿ç”¨ä¼ æ’æ€§æŒä¹…化(transitive persistence)åQŒè¯·çœ?a title="11.11. ä¼ æ’æ€§æŒä¹…化(transitive persistence)" tppabs="http://www.hibernate.org/hib_docs/v3/reference/zh-cn/html/objectstate.html#objectstate-transitive">½W?nbsp;11.11 èŠ?“ä¼ æ’æ€§æŒä¹…化(transitive persistence)”ã€?
lock()æ–ÒŽ³•也å…许程åºé‡æ–°å…³è”æŸä¸ªå¯¹è±¡åˆ°ä¸€ä¸ªæ–°session上。丘q‡ï¼Œè¯¥è„±½Ž?detached)的对象必™åÀL˜¯æ²¡æœ‰ä¿®æ”¹˜q‡çš„åQ?
//just reassociate: sess.lock(fritz, LockMode.NONE); //do a version check, then reassociate: sess.lock(izi, LockMode.READ); //do a version check, using SELECT ... FOR UPDATE, then reassociate: sess.lock(pk, LockMode.UPGRADE);
è¯äh³¨æ„,lock()å¯ä»¥æé…多ç§LockModeåQ?更多信æ¯è¯·é˜…读API文档以åŠå…³äºŽäº‹åС处ç†(transaction handling)çš„ç« èŠ‚ã€‚é‡æ–°å…³è”䏿˜?tt class="literal">lock()的唯一用途ã€?
其他用于长时间工作å•元的模型会在½W?nbsp;12.3 èŠ?“ä¹è§‚òq¶å‘控制(Optimistic concurrency control)”ä¸è®¨è®ºã€?
æ–‡ç« å‡ºå¤„:http://docs.huihoo.com/framework/hibernate/reference-v3_zh-cn/objectstate.html分页支挾c»ï¼š
抽象业务¾c?
用户在webå±‚æž„é€ æŸ¥è¯¢æ¡ä»¶detachedCriteriaåQŒå’Œå¯é€‰çš„startIndexåQŒè°ƒç”¨ä¸šåŠ¡bean的相应findByCriteriaæ–ÒŽ³•åQŒè¿”回一个PaginationSupport的实例psã€?/p>
ps.getItems()得到已分™åµå¥½çš„结果集
ps.getIndexes()得到分页索引的数¾l?
ps.getTotalCount()得到æ€È»“果数
ps.getStartIndex()当å‰åˆ†é¡µç´¢å¼•
ps.getNextIndex()下一™å늃¦å¼?
ps.getPreviousIndex()上一™å늃¦å¼?br />
æ–‡ç« å‡ºå¤„:http://www.javaeye.com/topic/14657
q Object execute(HibernateCallback action)
q List execute(HibernateCallback action)
˜q™ä¸¤ä¸ªæ–¹æ³•都需è¦ä¸€ä¸?/span>HibernateCallback的实例,HibernateCallback实例å¯åœ¨ä»ÖM½•有效çš?/span>Hibernateæ•°æ®è®‰K—®ä¸ä‹É用。程åºå¼€å‘者通过HibernateCallbackåQŒå¯ä»¥å®Œå…¨ä‹Éç”?/span>Hibernateç‰|´»çš„æ–¹å¼æ¥è®‰K—®æ•°æ®åº“,解决Springž®è£…HibernateåŽçµ‹zÀL€§ä¸‘³çš„¾~ºé™·ã€?/span>HibernateCallback是一个接å£ï¼Œè¯¥æŽ¥å£åªæœ‰ä¸€ä¸ªæ–¹æ³?/span>doInHibernate(org.hibernate.Session session)åQŒè¯¥æ–ÒŽ³•åªæœ‰ä¸€ä¸ªå‚æ•?/span>Sessionã€?/span>
通常åQŒç¨‹åºä¸é‡‡ç”¨å®žçްHibernateCallback的匿å内部类æ¥èŽ·å?/span>HibernateCallback的实例,æ–ÒŽ³•doInHibernate的方法体ž®±æ˜¯Spring执行的æŒä¹…化æ“作。具体代ç 如下:
public class PersonDaoImpl implements PersonDao
{
//¿U有实例å˜é‡ä¿å˜SessionFactory
private SessionFactory sessionFactory;
//ä¾èµ–注入必须çš?/span>setteræ–ÒŽ³•
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
/**
* é€šè¿‡äººåæŸ¥æ‰¾æ‰€æœ‰åŒ¹é…该åçš„Person实例
* @param name 匚w…çš„ähå?/span>
* @return 匚w…该ä“Q命的全部Person集åˆ
*/
public List findPersonsByName(final String name)
{
//创å¾HibernateTemplate实例
HibernateTemplate hibernateTemplate =
new HibernateTemplate(this.sessionFactory);
//˜q”回HibernateTemplateçš?/span>execute的结æž?/span>
return (List) hibernateTemplate.execute(
//创å¾åŒ¿å内部¾c?/span>
new HibernateCallback()
{
public Object doInHibernate(Session session) throws HibernateException
{
//使用æ¡äšg查询的方法返å›?/span>
List result = session.createCriteria(Person.class)
.add(Restrictions.like(“name”, name+”%”)
.list();
return result;
}
});
}
}
注æ„åQšæ–¹æ³?/span>doInHibernateæ–ÒŽ³•内å¯ä»¥è®¿é—?/span>SessionåQŒè¯¥Session对象是绑定到该线½E‹çš„Session实例。该æ–ÒŽ³•内的æŒä¹…层æ“作,与ä¸ä½¿ç”¨Springæ—¶çš„æŒä¹…层æ“作完全相åŒã€‚è¿™ä¿è¯å¯¹äºŽå¤æ‚çš„æŒä¹…层讉K—®åQŒä¾ç„¶å¯ä»¥ä‹Éç”?/span>Hibernate的访问方å¼ã€?/span>
一ã€?span style="font: 7pt 'Times New Roman'"> æ•°æ®åº“事务概å¿?/span>
æ•°æ®åº“事务的特å¾åQ?/span> ACID
Atomic åQˆåŽŸåæ€§ï¼‰ã€?/span> Consistency åQˆä¸€è‡´æ€§ï¼‰ã€?/span> Isolation åQˆé𔼛ÀL€§ï¼‰å’?/span> Durability åQˆæŒä¹…性)ã€?/span> DBMS 用日志æ¥ä¿è¯æ•°æ®çš„åŽŸåæ€§ã€ä¸€è‡´æ€§å’ŒæŒä¹…性;用é”的机制æ¥ä¿è¯æ•°æ®çš„éš”¼›ÀL€§ã€?/span>
二�span style="font: 7pt 'Times New Roman'"> 事务的边�/span>
æ•°æ®åº“支æŒ?/span> 2 ¿U事务模å¼ï¼šè‡ªåЍæäº¤å’Œæ‰‹åЍæäº¤ã€?/span>
JDBC API 的事务边�/span>
Hibernate API 声明事务边界
注:一ä¸?/span> session å¯ä»¥å¯¹åº”多个事务åQŒä½†æ˜¯æŽ¨èçš„åšæ³•是一ä¸?/span> session 对应一个事务ã€?/span>
三ã€?/font> 多事务的òq¶å‘问题
å½“å¤šä¸ªäº‹åŠ¡åŒæ—¶è®¿é—®ç›¸åŒçš„æ•°æ®çš„æ—¶å€™ï¼Œ½E‹åºå¦‚果没有采å–适当的隔¼›ÀLŽªæ–½ï¼Œž®×ƒ¼šå‘生数æ®åº“çš„òq¶å‘问题。常è§çš„òq¶å‘问题有:
½W¬ä¸€¾cÖM¸¢å¤±æ›´æ–ŽÍ¼šæ’¤æ¶ˆäº‹åŠ¡çš„æ—¶å€™ï¼ŒæŠŠå…¶ä»–çš„äº‹åŠ¡å·²ç»æäº¤çš„æ•°æ®ç»™è¦†ç›–了;
è„读åQ›è¯»äº†æ²¡æœ‰æäº¤çš„æ•°æ®åQ?/span>
虚读åQšä¸€ä¸ªäº‹åŠ¡è¯»åˆ°å¦å¤–一个事务已¾læäº¤çš„æ–°æ’入的数æ®åQ?/span>
ä¸å¯é‡å¤è¯»ï¼šä¸€ä¸ªäº‹åŠ¡è¯»åˆ°å¦å¤–一个事务已¾læäº¤çš„æ›´æ–°çš„æ•°æ®ï¼›
½W¬äºŒ¾cÖM¸¢å¤±æ›´æ–ŽÍ¼šä¸€ä¸ªäº‹åŠ¡è¦†ç›–å¦å¤–一个事务已¾læäº¤çš„æ›´æ–°æ•°æ®ã€?/span>
四�/strong> �/span>
一般地åQŒå¤§åž‹çš„ DBMS 都会自动的管ç†é”定机åˆÓž¼Œä½†æ˜¯åœ¨å¯¹æ•°æ®çš„安全性ã€å®Œæ•´æ€§å’Œä¸€è‡´æ€§æœ‰ç‰ÒŽ®Šè¦æ±‚的地方,å¯ä»¥ç”׃º‹åŠ¡æœ¬íw«æ¥½Ž¡ç†ç的机制ã€?/span>
有一点è¦å…Ïx³¨çš„æ˜¯åQšé”的粒度越大,隔离性越好,òq¶å‘性越差ã€?/span>
按照é”çš„½E‹åº¦æ¥åˆ†æœ‰ï¼š
å…׃íné”:用读æ“作åQŒéžç‹¬å 的,其他事务å¯ä»¥è¯»ï¼Œä½†æ˜¯ä¸èƒ½æ›´æ–°åQŒåÆˆå‘æ€§å¥½åQ?/span>
独å é”:用与 insert update å’?/span> delete ½{‰è¯å¥ï¼Œå…¶ä»–事务ä¸èƒ½è¯»ï¼Œä¹Ÿä¸èƒ½æ”¹åQŒåÆˆå‘æ€§å·®åQ?/span>
æ›´æ–°é”:执行 update çš„æ—¶å€™ï¼ŒåŠ é”ã€?/span>
æÈåQšå¤šæ˜¯äº‹åŠ¡åˆ†åˆ«é”定了一个资æºï¼Œåˆè¯·æ±‚é”定对方已¾lé”定的资æºåQŒå°±é€ æˆäº†è¯·æ±‚环ã€?/span>
é™ä½Žæ»é”的最好办法是使用çŸäº‹åŠ¡ã€?/span>
五ã€?/font> æ•°æ®åº“的事务隔离¾U§åˆ«
æ•°æ®åº“æä¾?/span> 4 ¿U事务隔¼›Èñ”别:
Serializable åQšä¸²è¡ŒåŒ–åQ›ï¼ˆéš”离¾U§åˆ«æœ€é«˜ï¼‰ 1
Repeatable Read åQšå¯é‡å¤è¯»ï¼› 2
Read Commited åQšè¯»å·²æäº¤æ•°æ®ï¼› 4
Read Uncommited åQšè¯»æœªæäº¤æ•°æ®ï¼›åQˆé𔼛Èñ”别最低) 8
Hiberate ä¸çš„隔离¾U§åˆ«çš„设¾|?/span>
åœ?/span> Hibernate 的酾|®æ–‡ä»¶ä¸ hibernate.connection.isolation=2
å…ã€?/font> 悲观é”å’Œä¹è§‚ç?/span>
从应用程åºçš„角度æ¥çœ‹åQŒé”åˆ†äØ“æ‚²è§‚é”å’Œä¹è§‚é”ã€?/span>
悲观é”:昄¡¤ºçš„䨓½E‹åºåŠ é”åQŒä½†æ˜¯é™ä½ŽåÆˆå‘æ€§ã€?/span>
Select ……. For update;
åœ?/span> Hibernate ä¸çš„代ç
Session.get(Account.class,net Long(1),LockMode.UPGRADE) åQ?/span> // ½E‹åºé‡‡ç”¨æ‚²è§‚é”?/span>
ä¹è§‚é”:ä¾é DBMS æ¥ç®¡ç†é”åQŒç¨‹åºä¾é 版本控制æ¥é¿å…òq¶å‘问题ã€?/span>
在对è±?/span> - å…³ç³»æ˜ å°„çš„æ–‡ä»¶ä¸åQŒç”¨ <version> 或è€?/span> <timestamp> å¯ä»¥½Ž¡ç†òq¶å‘。ä¹è§‚çæ¯”æ‚²è§‚çæœ‰æ›´å¥½çš„òq¶å‘性,优先考虑ä¹è§‚çã€?/span>
Hibernate æä¾›äº?/span> 3 ¿U检索ç–略:
l 延迟‹‚€ç´¢ï¼›
l 立峋‚€ç´¢ï¼›
l ˜q«åˆ‡å·¦å¤–˜qžæŽ¥åQ?/span>
Hibernate æä¾› 2 ¿Uæ–¹å¼æ¥¼‹®å®š‹‚€ç´¢ç–ç•¥ï¼Œä¸€ä¸æ˜¯åœ¨é…¾|®æ–‡ä»¶å½“ä¸ï¼Œå¦å¤–一¿U是在程åºç§è®„¡½®ã€‚当ç„Óž¼Œå¦‚æžœä½ åœ¨½E‹åºä¸è®¾¾|®äº†‹‚€ç´¢ç–ç•¥ï¼Œé‚£ä¹ˆä½ åœ¨é…置文äšgä¸çš„讄¡½®ä¹Ÿå°±æ— 效了。å¦å¤–的一¿U情冉|˜¯ HQL 会忽略酾|®æ–‡ä»¶çš„讄¡½®åQŒè€Œæ€ÀL˜¯é‡‡ç”¨˜q«åˆ‡å·¦å¤–˜qžæŽ¥ã€?/span>
一ã€?¾cÈñ”别的‹‚€ç´?/span>
å¯ä»¥é€‰æ‹©çš„æ£€ç´¢ç–略是立峋‚€ç´¢å’Œå»¶è¿Ÿ‹‚€ç´¢ï¼Œé»˜è®¤çš„æ˜¯ç«‹å³‹‚€ç´¢ã€‚用é…置文äšgä¸çš„ <class> 节点çš?/span> lazy æ¥æŽ§åˆ¶ã€?/span>
注æ„åQšä¸½Ž¡ä½ 在酾|?/span> class çš?/span> lazy æ˜?/span> true ˜q˜æ˜¯ false åQŒå¯¹ get() å’?/span> create Criteria () æ–ÒŽ³•都ä¸èµ·ä½œç”¨ï¼Œåªæœ‰å¯?/span> load() æ–ÒŽ³•起作用ã€?/span>
å½“ä½ ä½¿ç”¨çš„æ£€ç´¢ç–略是 lazy çš„æ—¶å€™ï¼Œå½“ä½ æ‰§è¡Œ
Customer customer = (Customer)session.load(Customer.class,new Long(1));
的时候, Hibernate ä¸ä»Žæ•°æ®åº“检索数æ®ï¼Œè€Œåªæ˜¯äñ”生一个代ç†ç±»åQŒåªæœ‰å½“ä½ æ‰§è¡?/span>
Customer.getName();
的时候, Hibernate æ‰åˆ°æ•°æ®åº“å–æ•°æ®ã€‚æ‰€ä»¥ï¼Œå¦‚ä¸‹çš„ä»£ç æ˜¯ä¼šè¢«æŠ›å‡ºå¼‚常的:
get() æ–ÒŽ³•æ€ÀL˜¯ç”¨çš„立峋‚€ç´¢ï¼Œå¦‚果和它相关è”çš„¾cÖM¹Ÿæ˜¯ç”¨çš„ç«‹åÏx£€ç´¢ï¼Œé‚£ä¹ˆä¹Ÿä¼šæŠŠç›¸å…Œ™”的数æ®ä¹Ÿ‹‚€ç´¢å‡ºæ¥ã€?/span>
二ã€?ä¸€å¯¹å’Œå¤šå¯¹å¤šå…³è”æ£€ç´?/span>
一般地åQŒäؓ了有å‡å°‘å¯ÒŽ•°æ®åº“的访问,我们往往用åšg˜qŸæ£€ç´¢çš„½{–略。所以,我们优先使用如下方å¼åQ?/span>
<set class=”order” inverse=”true’ lazy=”true” >
但是åQŒæˆ‘们在‹‚€ç´?#8220;å¤?#8221;的一方的时候, Hibernate ä¸èƒ½ä¸ºæˆ‘们äñ”生代ç†ç±»ã€‚ç”±æ¤ï¼Œæˆ‘们ž®Þp¦ç”?/span> betch-size 的酾|®æ¥å‡å°‘ SQL è¯å¥ã€?/span>
当我们ä‹Éç”?/span> outer-join 属性的时候,我们ž®±æ²¡æœ‰å¿…è¦ä‹Éç”?/span> lazy 属性了ã€?/span> Outer-join 会一‹Æ¡å°†“一”方和与之相关çš?#8220;å¤?#8221;方用左外˜qžæŽ¥çš„æ–¹å¼æ£€ç´¢å‡ºæ¥ã€?/span>
Session session = sessionFactory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Customer customer = (Customer)session.get(Customer.class,new Long(1));
产生çš?/span> SQL è¯å¥å¦‚下åQ?/span>
Hibernate: select customer0_.ID as ID1_, customer0_.NAME as NAME2_1_, orders1_.CUSTOMER_ID as CUSTOMER3_3_, orders1_.ID as ID3_, orders1_.ID as ID0_, orders1_.ORDER_NUMBER as ORDER2_1_0_, orders1_.CUSTOMER_ID as CUSTOMER3_1_0_ from sampledb.customers customer0_ left outer join sampledb.orders orders1_ on customer0_.ID=orders1_.CUSTOMER_ID where customer0_.ID=?
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import cn.hxex.blog.hibernate.HibernateUtil;
public class HibernateFilter implements Filter {
private static Log log = LogFactory.getLog(HibernateFilter.class);
/**
* ˜q‡æ×oå™¨çš„ä¸»è¦æ–ÒŽ³•
* 用于实现Hibernate事务的开始和æäº¤
*/
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
// 得到SessionFactory对象的实�br> SessionFactory sf = HibernateUtil.getSessionFactory();
try
{
// 开始一个新的事�br> log.debug("Starting a database transaction");
sf.getCurrentSession().beginTransaction();
log.debug( "Request Path:\t" + ((HttpServletRequest)request).getServletPath() );
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// æäº¤äº‹åŠ¡
log.debug("Committing the database transaction");
sf.getCurrentSession().getTransaction().commit();
}
catch (Throwable ex)
{
ex.printStackTrace();
try
{
// 回滚事务
log.debug("Trying to rollback database transaction after exception");
sf.getCurrentSession().getTransaction().rollback();
}
catch (Throwable rbEx)
{
log.error("Could not rollback transaction after exception!", rbEx);
}
// 抛出异常
throw new ServletException(ex);
}
}
/**
* Servlet˜q‡æ×o器的åˆå§‹åŒ–æ–¹æ³?br> * å¯ä»¥è¯Õd–é…置文äšgä¸è®¾¾|®çš„é…ç½®å‚æ•°
*/
public void init(FilterConfig filterConfig) throws ServletException {}
/**
* Servletçš„é”€æ¯æ–¹æ³?br> * 用于释放˜q‡æ×o器所甌™¯·çš„资æº?br> */
public void destroy() {}
}
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
public class BaseModel implements Serializable{
/**
* The Generated SerialVersionUID
*/
private static final long serialVersionUID = 7766184319541530720L;
/**
* The identify of the object
*/
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* Common implement equals method
*/
public boolean equals( Object obj )
{
if( this==obj ) return true;
if( !( obj instanceof BaseModel ) )
return false;
BaseModel target = (BaseModel)obj;
if( this.getId()!=null && this.getId().length()>0 )
{
return this.getId().equals( target.getId() );
}
if( target.getId()!=null && target.getId().length()>0 )
{
return false;
}
return EqualsBuilder.reflectionEquals(this, obj);
}
/**
* Generate the hash code
*/
public int hashCode()
{
if( this.getId()!=null && this.getId().length()>0 )
{
return this.getId().hashCode();
}
return HashCodeBuilder.reflectionHashCode(this);
}
/**
* Common implement toString method
*/
public String toString()
{
return ReflectionToStringBuilder.toString( this );
}
}
equals()æ–ÒŽ³•,用于判æ–两个对象是å¦ç›¸ç‰,ä½†åÆˆä¸æ˜¯åœ¨ä‹Éç”?=="˜q›è¡Œä¸¤ä¸ªå¯¹è±¡æ˜¯å¦ç›¸ç‰çš„åˆ¤æ–æ—¶è°ƒç”¨.å› äØ“ä½¿ç”¨"=="所判æ–的是两个对象的引用是å¦ç›¸½{?也å¯ä»¥ç®€å•ç†è§£äؓ两个实例所引用的是å¦äؓ内å˜ä¸çš„åŒä¸€ä¸ªå¯¹è±?equals()æ–ÒŽ³•å¯ä»¥ç†è§£ä¸ÞZ¸¤ä¸ªå¯¹è±¡åœ¨"å«ä¹‰"上是å¦ç›¸½{?也就是说˜q™ä¸¤ä¸ªå¯¹è±¡æ‰€è¡¨è¾¾çš„æ„æ€æ˜¯å¦ç›¸å?equals()æ–ÒŽ³•在对象ä¿å˜åˆ°é›†åˆå®¹å™¨¾c?Collection)䏿—¶è¢«è°ƒç”?å› äØ“é›†åˆå®¹å™¨¾cÖM¸å…许其ä¸å˜åœ¨ä¸¤ä¸ªç›¸åŒå¯¹è±¡å®žä¾‹,其判æ–çš„ä¾æ®ž®±æ˜¯é€šè¿‡è°ƒç”¨è¯¥å®žä½“对象的equals()æ–ÒŽ³•æ¥è¿›è¡Œåˆ¤æ–çš„.
如果修改了equals()æ–ÒŽ³•,ž®±å¿…™åÖM¿®æ”¹hashCode()æ–ÒŽ³•.如果ä¸è¿™æ ïLš„è¯?ž®Þp¿åjava.lang.Object的通用的hashCode的约å®?从而导致该¾cÀL— 法与åŸÞZºŽæ•£åˆ—值的集刾cÖM¸€èµäh£å¸¸å·¥ä½?
toString()æ–ÒŽ³•,用于ž®†å½“å‰Java对象的实例è{æ¢äØ“å¯ä»¥æè¿°å…¶å†…容的å—符ä¸?˜q™ä¸ªæ–ÒŽ³•的作用是在程åºè°ƒè¯•çš„˜q‡ç¨‹å¯ä»¥æ–¹ä¾¿åœ°å¾—到实体对象ä¸ä»¤äh感兴‘£çš„ä¿¡æ¯,æœ‰åˆ©äºŽæ›´å‡†ç¡®åŠæ—¶åœ°å‘现程åºä¸çš„é—®é¢?
对于Hibernate 3.1 以å‰çš„的版本在实现Hibernate工具¾cÀL—¶,需è¦é€šè¿‡ä¸¤ä¸ª¾U¿ç¨‹
局部å˜é‡æ¥ä¿å˜ä¸Žå½“å‰è¿›è¡Œç›¸å¯¹åº”çš„Session和事务对象的实例.
而对于Hibernate 3.1 以åŽçš„版æœ?使用¾U¿ç¨‹å±€éƒ¨å˜é‡ä¿å˜Session和事务对象的
工作ž®±å®Œå…¨ä¸éœ€è¦è‡ªå·±åŽ»å®žçŽ°äº?åªéœ€åœ¨Hibernate.cfg.xmlé…置文äšgä¸å¢žåŠ ä¸€ä¸ªåä¸?br>Current_session_context_class的属æ€?òq¶ä¸”讄¡½®è¯¥å±žæ€§çš„å€égØ“thread.˜q™æ ·Hibernate
ž®±å¯ä»¥è‡ªåŠ¨åœ°ä½¿ç”¨¾U¿ç¨‹å±€éƒ¨å˜é‡æ¥ä¿å˜å½“å‰çš„è¿›½E‹çš„Session和事务对象了.
相应åœ?Hibernateä¹ŸäØ“å…¶Sessionå¯¹è±¡å¢žåŠ äº†getTransaction()æ–ÒŽ³•,以便å¯ä»¥éšæ—¶
得到当å‰çš„äº‹åŠ¡åÆˆ˜q›è¡Œæäº¤æˆ–者回滚æ“ä½?˜q™ä¸ªæ–ÒŽ³•在以å‰ç‰ˆæœ¬çš„hibernate䏿˜¯ä¸å˜åœ?br>çš?
Hibernate工具¾cÖM¸»è¦åŒ…括以下功èƒ?
(1)Hibernateçš„åˆå§‹åŒ–æ“作
˜q™ä¸ªåŠŸèƒ½ä¸æ”¾åœ¨ä“Q何方法ä¸,é‡‡ç”¨é™æ€ç¼–ç çš„å¤„ç†æ–¹å¼,在对象的åˆå§‹åŒ–的时候被
调用一‹Æ¡å°±å¯ä»¥äº?
(2)得到当å‰çš„é…¾|®ä¿¡æ?/em>
˜q™ä¸ªæ–ÒŽ³•å¯ä»¥å¾—到当å‰çš„é…¾|®ä¿¡æ?以便于动æ€è¿›è¡Œé…¾|®å‚数的修改.hibernate
的酾|®ä¿¡æ¯åªåœ¨Hibernateåˆå§‹åŒ–的时候ä‹É用一‹Æ?在完æˆåˆå§‹åŒ–之åŽå¯šw…¾|®æ–‡ä»?br> 或者Configuration对象所åšçš„修改ž®†ä¸ä¼šç”Ÿæ•?
(3)得到SessionFactory对象的实�/em>
˜q™ä¸ªæ–ÒŽ³•用于得到当剾pÈ»Ÿ˜q行时的SessionFactory对象的实ä¾?˜q™ä¸ªå¯¹è±¡çš„实ä¾?br> 对于整个¾pÈ»Ÿè€Œè¨€æ˜¯å…¨å±€å”¯ä¸€çš?
(4)释放å„ç§èµ„æº
˜q™ä¸ªæ–ÒŽ³•用于¾lˆæ¢Hibernate的报务åŽ,释放å„ç§Hibernate所使用的资æº?虽然˜q™ä¸ª
æ–ÒŽ³•å‡ ä¹Žä¸ä¼šç”¨åˆ°,但对于申误‚µ„æºçš„åŠæ—¶é‡Šæ”¾æ˜¯æ¯ä¸ªç¨‹åºåº”该掌æ¡çš„基本原则.
(5)é‡å¾SessionFactory
ç”׃ºŽSessionFactory对于整个Hibernate应用是唯一çš?òq¶ä¸”是在Hibernateåˆå§‹åŒ?br> 之åŽå»ºç«‹å¥½çš„,而且对于é…置文äšg的修改也ä¸ä¼šå½±å“到已¾låˆå§‹åŒ–çš„SessionFactory
对象.那么如何æ‰èƒ½ä½¿ä¿®æ”¹çš„é…置信æ¯å¯¹Hibernate起作用呢.˜q™å°±éœ€è¦é‡å»ºSessionFactory
对象实例.
(6)拦截器注�/em>
ç”¨äºŽæ³¨å†Œæ‹¦æˆªå™¨åÆˆé‡å¾SessionFactory.
HibenateUtil.java
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
/**
* 基础的Hibernate辅助¾c»ï¼Œç”¨äºŽHibernate的酾|®å’Œå¯åЍã€?br> * <p>
* é€šè¿‡é™æ€çš„åˆå§‹åŒ–ä»£ç æ¥è¯Õd–Hibernateå¯åЍ傿•°åQŒåƈåˆå§‹åŒ?br> * <tt>Configuration</tt>å’?lt;tt>SessionFactory</tt>对象ã€?br> * <p>
*
* @author galaxy
*/
public class HibernateUtil
{
private static Log log = LogFactory.getLog(HibernateUtil.class);
// 指定定义拦截器属性å
private static final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";
// 陿€Configurationå’ŒSessionFactory对象的实例(全局唯一的)
private static Configuration configuration;
private static SessionFactory sessionFactory;
static
{
// 从缺çœçš„é…置文äšg创å¾SessionFactory
try
{
// 创å¾é»˜è®¤çš„Configuration对象的实ä¾?br> // å¦‚æžœä½ ä¸ä½¿ç”¨JDK 5.0或者注释请使用new Configuration()
// æ¥åˆ›å»ºConfiguration()对象的实ä¾?br> configuration = new Configuration();
// è¯Õd–hibernate.properties或者hibernate.cfg.xmlæ–‡äšg
configuration.configure();
// 如果在酾|®æ–‡ä»¶ä¸é…置了拦截器åQŒé‚£ä¹ˆå°†å…¶è®¾¾|®åˆ°configuration对象ä¸?br> String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS);
if (interceptorName != null)
{
Class interceptorClass =
HibernateUtil.class.getClassLoader().loadClass(interceptorName);
Interceptor interceptor = (Interceptor)interceptorClass.newInstance();
configuration.setInterceptor(interceptor);
}
if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) != null)
{
// 让Hibernatež®†SessionFacory¾l‘定到JNDI
configuration.buildSessionFactory();
}
else
{
// ä½¿ç”¨é™æ€å˜é‡æ¥ä¿æŒSessioFactory对象的实ä¾?br> sessionFactory = configuration.buildSessionFactory();
}
}
catch (Throwable ex)
{
// 输出异常信æ¯
log.error("Building SessionFactory failed.", ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
/**
* ˜q”回原始的Configuration对象的实ä¾?br> *
* @return Configuration
*/
public static Configuration getConfiguration()
{
return configuration;
}
/**
* ˜q”回全局的SessionFactory对象的实ä¾?br> *
* @return SessionFactory
*/
public static SessionFactory getSessionFactory()
{
SessionFactory sf = null;
String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME);
if ( sfName != null)
{
log.debug("Looking up SessionFactory in JNDI.");
try
{
sf = (SessionFactory) new InitialContext().lookup(sfName);
}
catch (NamingException ex)
{
throw new RuntimeException(ex);
}
}
else
{
sf = sessionFactory;
}
if (sf == null)
throw new IllegalStateException( "SessionFactory not available." );
return sf;
}
/**
* å…³é—当å‰çš„SessionFactoryòq¶ä¸”释放所有的资æº
*/
public static void shutdown()
{
log.debug("Shutting down Hibernate.");
// Close caches and connection pools
getSessionFactory().close();
// Clear static variables
configuration = null;
sessionFactory = null;
}
/**
* ä½¿ç”¨é™æ€çš„Configuration对象æ¥é‡æ–°æž„建SessionFactoryã€?br> */
public static void rebuildSessionFactory()
{
log.debug("Using current Configuration for rebuild.");
rebuildSessionFactory(configuration);
}
/**
* 使用指定的Configuration对象æ¥é‡æ–°æž„建SessionFactory对象ã€?br> *
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg)
{
log.debug("Rebuilding the SessionFactory from given Configuration.");
synchronized(sessionFactory)
{
if (sessionFactory != null && !sessionFactory.isClosed())
sessionFactory.close();
if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null)
cfg.buildSessionFactory();
else
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
}
}
/**
* 在当å‰SessionFactory䏿³¨å†Œä¸€ä¸ªæ‹¦æˆªå™¨
*/
public static SessionFactory registerInterceptorAndRebuild(Interceptor interceptor)
{
log.debug("Setting new global Hibernate interceptor and restarting.");
configuration.setInterceptor(interceptor);
rebuildSessionFactory();
return getSessionFactory();
}
/**
* 获得拦截器对�br> *
* @return Interceptor
*/
public static Interceptor getInterceptor()
{
return configuration.getInterceptor();
}
/**
* æäº¤å½“å‰äº‹åŠ¡åQŒåƈ开始一个新的事åŠ?br> */
public static void commitAndBeginTransaction()
{
sessionFactory.getCurrentSession().getTransaction().commit();
sessionFactory.getCurrentSession().beginTransaction();
}
}