最好将hibernate.cfg.xml文g存放于项目的根目录下?br />
4Q生?hbm.xml文g。File->New->Other->Hibernate->Hibernate Mapping FileQ出现如下界面:
在填写完Password后,点击Refresh按钮Q就会在Tables中列出所有可以访问的数据库表Q然后选中要ؓ其生?hbm.xml文g的表Q点击FinishQ即会生成对应的.hbm.xml文gQ比如我上面选择的是Mobileuser表,׃生成Mobileuser.hbm.xml文g?br />
Q?Q从.hbm.xml文g自动生成实体cR?br />
在Package Explorer中选中Mobileuser.hbm.xml文gQ右?>Hibernate Synchronizer->Synchronize Files Q即可生成对应的实体cdDAOcR如果你仅仅惌实体c,那么可以在Project->Properies->Hibernate Synchronizer->Data Access Objects Q将“I would like to have DAOs created for me”的钩选项L卛_?br />
Q?Q在hibernate.cfg.xml文g中添加对应的mapping resource?br />
在Package Explorer中选中Mobileuser.hbm.xml文gQ右?>Hibernate Synchronizer->Add Mapping ReferenceQ即会在
hibernate.cfg.xml中自动生成如下配|:
Q?Q修改自动生成的hibernate.cfg.xml文g。需要在hibernate.cfg.xml文g的首部添加:
比较J琐的是Q每ơ自动修改hibernate.cfg.xml文g后,都要重新dq个xml片断?br />
万事具备Q现在可以写个测试来验一下了Q?/p>
q个新特性应该明地告诉已有的Hibernate开发者,因ؓ它也遵@POJO(U的旧Java对象)相同的一致性方法,需要学习的知识最。XML持久性的优点也应该介l给新用戗本文讲解的是Hibernate 3持久性方法?
XML持久性ؓ什么重?/strong>
大多数大型商业数据库都支持某UŞ式的本地XML持久性。由于XML持久性是一个相对较新的机制--即对大型厂商也是如此,q个领域中的标准q在不断地Q现。其l果是,Z把无处不在的关系型持久性机制与日益增长的XML解决Ҏ集成在一P架构师必M赖厂商特定的Ҏ或者实现定制的XML持久性框架组件。这两个选择都没有太大的吸引力。厂商特定的Ҏ不是普及的Q因为可能生厂商封?lock-in)Q而定制的框架lg实现可能耗费大量的时间和财力Q导致代码难于维护?/p>
在OR(对象关系)持久性方面,Hibernate XML持久性是一个自然而然的解x案。它可以跨越Hibernate支持的所有关pdq_(如虚拟的或真实的关系型^?U?!-- -->动,允许自由的迁Ud象、基于XML的应用程序和集成解决Ҏ而不用担心下层的关系型实现方法?/p>
体系l构的细节信?/strong>
Hibernate是一个良好架构的框架lgQ它无缝地利用了本地的环境,不需要用戯行Q何特D的q涉或安装操作。从一个数据库切换到另外一个数据库通常只需要改变驱动程序,q|Hibernate(在线配置讄信息)来用另外一U数据库语言?/p>
Hibernate利用dom4j框架lgq行XML的分析和l护。如果需要完全利用Hibernate的XMLҎ,你就必须对dom4j非常熟悉。一般来_你会发现dom4j比Java提供的JAXP或与JAXP兼容的XML分析器要Ҏ使用一些。它要求我们学习的相关知识较,q且利用最的dom4j知识你就能够高效率地使用Hibernate XML持久性?
实际例子Qh格目录同?br />QproductsQ?br />
Qproduct prod_id="3" sku="100101"Q? QdescriptionQAthlete mode body fat scaleQ?descriptionQ?br /> Qlist_priceQ?00.00Q?list_priceQ?br /> Qdrop_priceQ?0.00Q?drop_priceQ?br /> Q?productQ? Qproduct prod_id="4" sku="100102"Q?br /> QdescriptionQThermometerQ?descriptionQ?br /> Qlist_priceQ?0.00Q?list_priceQ?br /> Qdrop_priceQ?1.00Q?drop_priceQ?br /> Q?productQ?br /> Q?productsQ?/td> |
CREATE TABLE PRODUCT ( id INT UNIQUE NOT NULL, description VARCHAR(45) NOT NULL, sku VARCHAR(45) UNIQUE NOT NULL, list_price FLOAT, base_price FLOAT, order_price FLOAT, CONSTRAINT PK_PRODUCT PRIMARY KEY (id ) ) |
/** Product对象表现了定L录项*/ public class Product { int id; String sku; String description; Double listPrice; Double basePrice; Double orderPrice; |
Q?xml version="1.0"?Q?br />
Q?DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"Q?br /> Qhibernate-mapping package="demo"Q?br /> Qclass name="Product" table="product" node="product"Q?br /> Qid name="id" type="int" node="@prod_id" column="id"Q?br /> Q?idQ?br /> Qproperty name="sku" node="@sku" column="sku" not-null="true"/Q?br /> Qproperty name="description" node="description" column="description" not-null="true"/Q? Qproperty name="listPrice" node="list_price" column="list_price" /Q?br /> Qproperty name="basePrice" node="drop_price" column="base_price"/Q?br /> Qproperty name="orderPrice" column="order_price"/Q?br /> Q?classQ?br /> Q?hibernate-mappingQ?/td> |
document = saxReader.read(inputXML); List users = document.selectNodes("http://product"); try { Session session = ibernateUtil.sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Session dom4jSession = session.openSession(EntityMode.DOM4J); Iterator iter = users.iterator(); while (iter.hasNext()) { Object next = iter.next(); dom4jSession.saveOrUpdate("demo.Product", next ); }// end while transaction.commit(); session.close(); |
import java.io.Serializable; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.Transaction; public class HibernateSessionUtil implements Serializable {
//创徏U程局部变量 tLocalsess
public static final ThreadLocal tLocalsess = new ThreadLocal();
//创徏U程局部变量 tLocaltx public static final ThreadLocal tLocaltx = new ThreadLocal(); //取得session
public static Session currentSession(){
//从线E变量tLocalsess中,取得当前session Session session = (Session) tLocalsess.get(); //判断session是否为空Q如果ؓI,创Z个session,q付l线E变量tLocalsess
try{ if (session == null){ session = openSession(); tLocalsess.set(session); } }catch (HibernateException e){ throw new InfrastructureException(e); } return session; } //关闭当前session
public static void closeSession(){
//从线E变量tLocalsess中,取得当前session
Session session = (Session) tLocalsess.get();
//讄U程变量tLocalsess为空 tLocalsess.set(null); try{
//关闭session if (session != null && session.isOpen()){ session.close(); } }catch (HibernateException e){ throw new InfrastructureException(e); } } //事物处理
public static void beginTransaction(){
//从线E变量tLocaltx中取得事物管理对象Transaction
Transaction tx = (Transaction) tLocaltx.get();
try{
//如果为空׃session中创Z个tx if (tx == null){ tx = currentSession().beginTransaction(); tLocaltx.set(tx); } }catch (HibernateException e){ throw new InfrastructureException(e); } } //提交事物
public static void commitTransaction(){
//取得事物 Transaction tx = (Transaction) tLocaltx.get(); try{
//如果不ؓI就提交 if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) tx.commit(); tLocaltx.set(null); }catch (HibernateException e){ throw new InfrastructureException(e); } } //事物回滚
public static void rollbackTransaction(){
//取得tx事物 Transaction tx = (Transaction) tLocaltx.get(); try{
//变量清I?/span>
tLocaltx.set(null);
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
//事物回滚 tx.rollback(); } }catch (HibernateException e){ throw new InfrastructureException(e); } }
//取得session private static Session openSession() throws HibernateException{ return getSessionFactory().openSession(); }
//取得sessionFactory private static SessionFactory getSessionFactory() throws HibernateException{ return SingletonSessionFactory.getInstance(); } }
filter的代码:
public class HibernateSessionCloser implements Filter{ protected FilterConfig filterConfig = null; public void init(FilterConfig filterConfig)throws ServletException{ this.filterConfig = filterConfig; } public void destroy(){ this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try{ chain.doFilter(request, response); } finally{ try{ HibernateSessionUtil.commitTransaction(); }catch (InfrastructureException e){ HibernateSessionUtil.rollbackTransaction(); }finally{ HibernateSessionUtil.closeSession(); } } } }
---------------------------------------------------------------------------------------
(1)、悲觀鎖定QPessimistic LockingQ一如其名稱所C,悲觀的認定每ơ資料存取時Q其它的客戶端也會存取同一{資料,因此該{資料進行鎖定Q直到自己操作完成後解除鎖定?nbsp;
悲觀鎖定通常透過pȝ或資料n本n的功能來實現Q依賴系i或資料庫本w提供的鎖定制QHibernatex如此Q可以利用Query?Criteria的setLockMode()Ҏ來設定要鎖定的表或列QRowQ及光定模式,可設定的鎖定模式有以下的qր:
LockMode.WRITEQ在insert或update時進行鎖定QHibernate會在save()Ҏ時自動獲得鎖定? LockMode.UPGRADEQ利用SELECT ... FOR UPDATE進行鎖定? LockMode.UPGRADE_NOWAITQ利用SELECT ... FOR UPDATE NOWAIT進行鎖定Q在Oracle環境下用? LockMode.READQ在讀取記錄時Hibernate會自動獲得鎖定? LockMode.NONEQ沒有鎖定?/span> (2)、樂觀鎖定QOptimistic lockingQ則樂觀的認料的存取很少發生同時存取的問,因而不作資料n層次上的鎖定Q為了維h的資料Q樂觀鎖定使用應用E式上的邏輯實現版本控制的解決?nbsp;
在不實行悲觀鎖定{略的情況下Q資料不一致的情況一但發生,有幾個解決的ҎQ一E是先更新為主,一E是後更新的ZQ比較複雜的是檢查發生變動的資料來實現Q或是檢查所有屬性來實現樂觀鎖定?br /> 要注意的是,由於樂觀鎖定是用系i׃的程式來控制Q而不是用資料n中的鎖定制Q因而如果有人特意自行更新版本訊息來過檢查Q則鎖定制會無效Q例如在上例中自行更改userV2的version屬性,使之與資料n中的版本號相同的話就不會有錯誤,像這樣版本號被更改Q或是由D料是由外部系ip來Q因而版本資a不受控制時Q鎖定機制將會有問題Q設a時必須注意?/p>