昨天还在用Torque,今天听说Hibernate更好,明天说不准又有更好的持久层工具...
如何使应用程序不变化的情况下选择不同的持久层呢?
看看Finetix LLC的资深顾问Charles Chan 给我们现身说法。
														
																
																
																		
																				Charles Chan 
																		
																在文章 Object-Relational Mapping with Apache Jakarta OJB
中介绍了Apache OJB的使用,并在文章附录中提到一种屏蔽不同持久层的设计思路,他采用了工厂方法模式(Factory Method),并通过实例Apache OJB来说明他的设计。
这个设计有两个产品,一个是PersistenceManager,另一个是Transaction 。
OJBPersistenceManager和OJBTransaction 分别是两个产品的实现。 
														
																
It is often desirable to decouple your application from the specifics of a persistence framework, so that you can easily switch frameworks in the future. I recommend creating custom PersistenceManager and Transaction classes for this purpose. For example:
														
														
														
																 Example 
																13
																: PersistenceManager and Transaction Interfaces
																Example 
																13
																: PersistenceManager and Transaction Interfaces

 /** */
																
																		/**
																/** */
																
																		/**
																		
																				
																				 * The abstract base class for all PersistenceManager. It provides
* The abstract base class for all PersistenceManager. It provides
 * method to persist and object and to obtain the current
* method to persist and object and to obtain the current
 * transaction.
* transaction.
 */
																		*/
																
																
																		
																		 public
																 
																abstract
																 
																class
																 PersistenceManager
																
																public
																 
																abstract
																 
																class
																 PersistenceManager

 
																
																		 {
																
																
																		{
 public
																		 
																		static
																		 PersistenceManager getInstance()
																		public
																		 
																		static
																		 PersistenceManager getInstance()

 
																		
																				 {
																		
																		
																				{
 return
																				 
																				new
																				 OJBPersistenceManager();
																				return
																				 
																				new
																				 OJBPersistenceManager();
 }
}
																		
																		 

 public
																		 
																		abstract
																		 
																		void
																		 makePersistent(Object o)
																		public
																		 
																		abstract
																		 
																		void
																		 makePersistent(Object o)
 throws
																		 PersistenceException;
																		throws
																		 PersistenceException; 

 public
																		 
																		abstract
																		 Transaction currentTransaction()
																		public
																		 
																		abstract
																		 Transaction currentTransaction()
 throws
																		 PersistenceException;
																		throws
																		 PersistenceException; 

 }
}
																
																 

 
														 
														
														
														
																 
																
																		
																		 
																		 /** */
																
																		/**
																
																/** */
																
																		/**
																		
																				
																				 * A Transaction interface. It provides minimal support for
* A Transaction interface. It provides minimal support for
 * beginning, committing, and rolling back a transaction.
* beginning, committing, and rolling back a transaction.
 */
																		*/
																
																
																		
																		 public
																 
																interface
																 Transaction
																
																public
																 
																interface
																 Transaction

 
																
																		 {
																
																
																		{
 public
																		 
																		void
																		 begin() 
																		throws
																		 PersistenceException;
																		public
																		 
																		void
																		 begin() 
																		throws
																		 PersistenceException; 

 public
																		 
																		void
																		 commit() 
																		throws
																		 PersistenceException;
																		public
																		 
																		void
																		 commit() 
																		throws
																		 PersistenceException; 

 public
																		 
																		void
																		 rollback() 
																		throws
																		 PersistenceException;
																		public
																		 
																		void
																		 rollback() 
																		throws
																		 PersistenceException;
 }
}
																
																 

 
														 
														
														
														
																 
																
																		
																		 
																		 /** */
																
																		/**
																
																/** */
																
																		/**
																		
																				
																				 * An OJB specific implementation of the PersistenceManager
* An OJB specific implementation of the PersistenceManager
 * class.
* class.
 */
																		*/
																
																
																		
																		 public
																 
																class
																 OJBPersistenceManager 
																extends
																 PersistenceManager
																
																public
																 
																class
																 OJBPersistenceManager 
																extends
																 PersistenceManager

 
																
																		 {
																
																
																		{
 private
																		 PersistenceBroker broker 
																		=
																		 
																		null
																		;
																		private
																		 PersistenceBroker broker 
																		=
																		 
																		null
																		; 

 public
																		 OJBPersistenceManager()
																		public
																		 OJBPersistenceManager()

 
																		
																				 {
																		
																		
																				{
 broker 
																				=
																				 PersistenceBrokerFactory.defaultPersistenceBroker();
broker 
																				=
																				 PersistenceBrokerFactory.defaultPersistenceBroker();
 }
}
																		
																		 

 public
																		 
																		void
																		 makePersistent(Object o) 
																		throws
																		 PersistenceException
																		public
																		 
																		void
																		 makePersistent(Object o) 
																		throws
																		 PersistenceException

 
																		
																				 {
																		
																		
																				{
 try
																				try
																				
																						
																						 
																						 
																				
																				
																						 {
																				
																				
																						{
 broker.store(o);
broker.store(o);
 }
}
																				
																				
																						
																						 catch
																				 (PersistenceBrokerException e)
																				
																				catch
																				 (PersistenceBrokerException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 }
}
																		
																		 

 public
																		 Transaction currentTransaction() 
																		throws
																		 PersistenceException
																		public
																		 Transaction currentTransaction() 
																		throws
																		 PersistenceException

 
																		
																				 {
																		
																		
																				{
 return
																				 
																				new
																				 OJBTransaction(broker);
																				return
																				 
																				new
																				 OJBTransaction(broker);
 }
}
																		
																		
																				
																				 }
}
																
																 

 
														 
														
																
 
														
																 
																
																		
																		 
																		 /** */
																
																		/**
																
																/** */
																
																		/**
																		
																				
																				 * An OJB specific implementation of the Transaction
* An OJB specific implementation of the Transaction
 * interface.
* interface.
 */
																		*/
																
																
																		
																		 public
																 
																class
																 OJBTransaction 
																implements
																 Transaction
																
																public
																 
																class
																 OJBTransaction 
																implements
																 Transaction

 
																
																		 {
																
																
																		{
 private
																		 PersistenceBroker broker 
																		=
																		 
																		null
																		;
																		private
																		 PersistenceBroker broker 
																		=
																		 
																		null
																		; 

 public
																		 OJBTransaction(PersistenceBroker broker)
																		public
																		 OJBTransaction(PersistenceBroker broker)

 
																		
																				 {
																		
																		
																				{
 this
																				.broker 
																				=
																				 broker;
																				this
																				.broker 
																				=
																				 broker;
 }
}
																		
																		 

 public
																		 
																		void
																		 begin() 
																		throws
																		 PersistenceException
																		public
																		 
																		void
																		 begin() 
																		throws
																		 PersistenceException

 
																		
																				 {
																		
																		
																				{
 try
																				try
																				
																						
																						 
																						 
																				
																				
																						 {
																				
																				
																						{
 broker.beginTransaction();
broker.beginTransaction();
 }
}
																				
																				
																						
																						 catch
																				(TransactionAbortedException e)
																				
																				catch
																				(TransactionAbortedException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 catch
																				(TransactionInProgressException e)
																				
																				catch
																				(TransactionInProgressException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 }
}
																		
																		 

 public
																		 
																		void
																		 commit() 
																		throws
																		 PersistenceException
																		public
																		 
																		void
																		 commit() 
																		throws
																		 PersistenceException

 
																		
																				 {
																		
																		
																				{
 try
																				try
																				
																						
																						 
																						 
																				
																				
																						 {
																				
																				
																						{
 broker.commitTransaction();
broker.commitTransaction();
 }
}
																				
																				
																						
																						 catch
																				(TransactionAbortedException e)
																				
																				catch
																				(TransactionAbortedException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 catch
																				(TransactionNotInProgressException e)
																				
																				catch
																				(TransactionNotInProgressException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 }
}
																		
																		 

 public
																		 
																		void
																		 rollback() 
																		throws
																		 PersistenceException
																		public
																		 
																		void
																		 rollback() 
																		throws
																		 PersistenceException

 
																		
																				 {
																		
																		
																				{
 try
																				try
																				
																						
																						 
																						 
																				
																				
																						 {
																				
																				
																						{
 broker.abortTransaction();
broker.abortTransaction();
 }
}
																				
																				
																						
																						 catch
																				(TransactionNotInProgressException e)
																				
																				catch
																				(TransactionNotInProgressException e)

 
																				
																						 {
																				
																				
																						{
 //
																						 rethrow PersistenceException
																						//
																						 rethrow PersistenceException
																						
																								
																								 }
																						
																						}
																				
																				
																						
																						 }
}
																		
																		
																				
																				 }
}
																
																 

 
														 
														
																
After the above classes are created, it is very simple to convert the test application to use them:
														下面是这个Factory的使用: 
														
														
														
																 Example 
																14
																: Example Using PersistenceManager and Transaction Interfaces
																Example 
																14
																: Example Using PersistenceManager and Transaction Interfaces
 PersistenceManager pm 
																=
																 PersistenceManager.getInstance();
PersistenceManager pm 
																=
																 PersistenceManager.getInstance();
 Transaction tx 
																=
																 pm.currentTransaction();
Transaction tx 
																=
																 pm.currentTransaction(); 

 tx.begin();
tx.begin();
 Manager manager 
																=
																 newManager();
Manager manager 
																=
																 newManager();
 manager.setName(
																"
																John Smith
																"
																);
manager.setName(
																"
																John Smith
																"
																);
 manager.setProjectNumber(
																new
																 Integer(
																10
																));
manager.setProjectNumber(
																new
																 Integer(
																10
																)); 

 pm.makePersistent(manager);
pm.makePersistent(manager); 

 Employee employee 
																=
																 newEmployee();
Employee employee 
																=
																 newEmployee();
 employee.setName(
																"
																David Cosby
																"
																);
employee.setName(
																"
																David Cosby
																"
																); 

 pm.makePersistent(employee);
pm.makePersistent(employee); 

 tx.commit();
tx.commit(); 

 
														 
														
																
It looks surprisingly like JDO, doesn't it? With a little more effort, you can also hide the OJB query mechanism. 
														改进建议:
1. 改用抽象工厂方法, 一套持久层产品提供一个工厂,用于创建不同的产品(如:PersistenceManager,Transaction....) 
														2.考虑从不同的持久层产品中抽取一套通用的持久层接口