J2EE中倡导的应该是面向接口,而不是面向类来编程,因为只有面向接口,才能真正做到层与层之间的解耦。面向接口编程最重要的价值在于隐藏实现,将抽象的实现细节封装起来不对外开放。
在大多数情况下,还需要对抽象类提取必要的接口,简单来做就是,把抽象DAO 类中的方法,全部抽取出来形成一个单独的接口。假如所有 DAO 的操作方法都一样,这样做没问题。但是实际上各个 DAO 类之间,尽管有大量相同的方法,但也总是存在一些不一致的方法,这样一来,问题就来了。我们总不能把接口做的很大吧 ....
接口隔离原则(ISP ):使用多个专门的接口比使用单一的总接口好!
实现这个原则的通常的方式有两种:
(1 )使用委托分离接口
(2 )使用多重继承分离接口
具体到抽象DAO 类,我们应该为所有具体的 DAO 类的共性方法抽取到抽象 DAO 类中,并将这些方法抽象为接口,之后再为每个具体的 DAO 类定义接口,在此接口中定义不再抽象 DAO 类中的方法,最后具体的 DAO 类应该继承抽象 DAO 类,同时实现本 DAO 类所对应的接口。通过这样的方式,就可以做到接口的隔离和防止大接口形成的污染了。
具体步骤如下:
1、 先建立一个HibernateSessionFactory 类来实现 Session 的创建与回收。
主要代码见下:
........
publicclassHibernateSessionFactory{
privatestaticStringCONFIG_FILE_LOCATION="/hibernate.cfg.xml";
privatestaticfinalThreadLocal<Session>threadLocal=newThreadLocal<Session>();
privatestaticConfigurationconfiguration=newConfiguration();
privatestaticorg.hibernate.SessionFactorysessionFactory;
privatestaticStringconfigFile=CONFIG_FILE_LOCATION;
static{
try{
configuration.configure(configFile);
sessionFactory=configuration.buildSessionFactory();
}catch(Exceptione){
System.err
.println("%%%%ErrorCreatingSessionFactory%%%%");
e.printStackTrace();
}
}
publicstaticSessiongetSession()throwsHibernateException {
Sessionsession=(Session)threadLocal.get();
if(session==null||!session.isOpen()){
if(sessionFactory==null){
rebuildSessionFactory();
}
session=(sessionFactory!=null)?sessionFactory.openSession():null;
threadLocal.set(session);
}
returnsession;
}
publicstaticvoidcloseSession()throwsHibernateException {
Sessionsession=(Session)threadLocal.get();
threadLocal.set(null);
if(session!=null){
session.close();
}
}
............
}
2、 定义一个IBaseHibernateDAO 接口,用来定义每个实体 DAO 类的公共方法,如 getSession() , save() , delete() 等,然后再建一个 BaseHibernate 类来实现该接口。
public interface IBaseHibernateDAO{
public SessiongetSession();
public void save(ObjecttransientInstance);
public void delete(ObjecttransientInstance);
}
public class BaseHibernateDAO implements IBaseHibernateDAO{
public SessiongetSession(){
return HibernateSessionFactory. getSession ();
}
public void delete(ObjecttransientInstance) throws RuntimeException{
getSession().delete(transientInstance);
}
public void save(ObjecttransientInstance) throws RuntimeException{
getSession().save(transientInstance);
}
}
3、 设计每个实体DAO 类的时候,先为其定义一个接口,定义其 特有的操作方法 ,如:
public interface IClientDAO extends IBaseHibernateDAO{
public ClientfindById(java.lang.Stringid);
public List findByExample(Clientinstance);
public List findByProperty(StringpropertyName,Objectvalue);
public List findByCEmail(ObjectCEmail);
public List findByCPhone(ObjectCPhone);
public List findByCName(ObjectCName);
public List findByCSex(ObjectCSex);
public List findAll();
public Clientmerge(ClientdetachedInstance);
public void attachDirty(Clientinstance);
public void attachClean(Clientinstance);
}
publicclassClientDAOextendsBaseHibernateDAOimplementsIClientDAO{
privatestaticfinalLoglog=LogFactory.getLog(ClientDAO.class);
//propertyconstants
publicstaticfinalString_CEMAIL="CEmail";
publicstaticfinalString_CPHONE="CPhone";
publicstaticfinalString_CNAME="CName";
publicstaticfinalString_CSEX="CSex";
publicvoidsave(ClienttransientInstance){
log.debug("savingClientinstance");
try{
super.save(transientInstance);
log.debug("savesuccessful");
}catch(RuntimeExceptionre){
log.error("savefailed",re);
throwre;
}
}
publicvoiddelete(ClientpersistentInstance){
log.debug("deletingClientinstance");
try{
super.delete(persistentInstance);
log.debug("deletesuccessful");
}catch(RuntimeExceptionre){
log.error("deletefailed",re);
throwre;
}
}
publicClientfindById(java.lang.Stringid){
log.debug("gettingClientinstancewithid:"+id);
try{
Clientinstance=(Client)getSession().get("com.DB.Entity.Client",id);
returninstance;
}catch(RuntimeExceptionre){
log.error("getfailed",re);
throwre;
}
}
publicListfindByExample(Clientinstance){
log.debug("findingClientinstancebyexample");
try{
Listresults=getSession().createCriteria("com.DB.Entity.Client").add(
Example.create(instance)).list();
log.debug("findbyexamplesuccessful,resultsize:"
+results.size());
returnresults;
}catch(RuntimeExceptionre){
log.error("findbyexamplefailed",re);
throwre;
}
}
publicListfindByProperty(StringpropertyName,Objectvalue){
log.debug("findingClientinstancewithproperty:"+propertyName
+",value:"+value);
try{
StringqueryString="fromClientasmodelwheremodel."
+propertyName+"=?";
QueryqueryObject=getSession().createQuery(queryString);
queryObject.setParameter(0,value);
returnqueryObject.list();
}catch(RuntimeExceptionre){
log.error("findbypropertynamefailed",re);
throwre;
}
}
publicListfindByCEmail(ObjectCEmail){
returnfindByProperty(_CEMAIL,CEmail);
}
publicListfindByCPhone(ObjectCPhone){
returnfindByProperty(_CPHONE,CPhone);
}
publicListfindByCName(ObjectCName){
returnfindByProperty(_CNAME,CName);
}
publicListfindByCSex(ObjectCSex){
returnfindByProperty(_CSEX,CSex);
}
publicListfindAll(){
log.debug("findingallClientinstances");
try{
StringqueryString="fromClient";
QueryqueryObject=getSession().createQuery(queryString);
returnqueryObject.list();
}catch(RuntimeExceptionre){
log.error("findallfailed",re);
throwre;
}
}
}
4、建立一个工厂类来对DAO进行统一的管理,该工厂类采用xml文件配置方式来反射生成DAO实例
<p
评论