JForum“Support for several popular databases,including MysqL,Postgresql,Oracle and HsqlDB”。
JForum系统中用于持久化的实体类被放在net.jforum.entities包下,例如:User、UserSession、Post等。关于实体类的DAO操作被定义在多个接口中,例如:关于User的DAO操作被定义在net.jforum.dao.UserDAO接口中。针对不同的数据库,有不同的UserDAO实现类。
如上图,GenericUserDAO是JForum的默认实现,对应的数据库是MysqL。GenericUserDAO、HsqldbUserDAO、OracleUserDAO和sqlServerUserDAO类都有public的无参数构造函数。JForum不是根据“配置文件 + if else”的方式决定初始化哪个UserDAO,而是新建了一个抽象类DataAccessDriver。
- publicabstractclassDataAccessDriver
- {
- privatestaticDataAccessDriverdriver;
- protectedDataAccessDriver(){}
- /**
- *Startstheengine.
- *Thismethodshouldbecalledwhenthesystem
- *isstarting.
- *
- *@paramimplementationThedao.driverimplementation
- */
- publicstaticvoidinit(DataAccessDriverimplementation)
- {
- driver=implementation;
- }
- /**
- *Getsadriverimplementationinstance.
- *YouMUSTusethismethodwhenyouwantainstance
- *ofavalid<code>DataAccessDriver</code>.Neveraccess
- *thedriverimplementationdirectly.
- *
- *@return<code>DataAccessDriver</code>instance
- */
- publicstaticDataAccessDrivergetInstance()
- {
- returndriver;
- }
- publicabstractForumDAOnewForumDAO();
- publicabstractGroupDAOnewGroupDAO();
- publicabstractPostDAOnewPostDAO();
- publicabstractPollDAOnewPollDAO();
- publicabstractRankingDAOnewRankingDAO();
- publicabstractTopicDAOnewTopicDAO();
- publicabstractUserDAOnewUserDAO();
- publicabstractCategoryDAOnewCategoryDAO();
- publicabstractTreeGroupDAOnewTreeGroupDAO();
- publicabstractSmilieDAOnewSmilieDAO();
- publicabstractGroupSecurityDAOnewGroupSecurityDAO();
- publicabstractPrivateMessageDAOnewPrivateMessageDAO();
- publicabstractUserSessionDAOnewUserSessionDAO();
- publicabstractConfigDAOnewConfigDAO();
- publicabstractKarmaDAOnewKarmaDAO();
- publicabstractBookmarkDAOnewBookmarkDAO();
- publicabstractAttachmentDAOnewAttachmentDAO();
- publicabstractModerationDAOnewModerationDAO();
- publicabstractBannerDAOnewBannerDAO();
- publicabstractSummaryDAOnewSummaryDAO();
- publicabstractMailIntegrationDAOnewMailIntegrationDAO();
- publicabstractApiDAOnewApiDAO();
- publicabstractBanlistDAOnewBanlistDAO();
- publicabstractModerationLogDAOnewModerationLogDAO();
- publicabstractLuceneDAOnewLuceneDAO();
- }
- public abstract class DataAccessDriver
- {
- private static DataAccessDriver driver;
- protected DataAccessDriver() {}
- /**
- * Starts the engine.
- * This method should be called when the system
- * is starting.
- *
- * @param implementation The dao.driver implementation
- */
- public static void init(DataAccessDriver implementation)
- {
- driver = implementation;
- }
- /**
- * Gets a driver implementation instance.
- * You MUST use this method when you want a instance
- * of a valid <code>DataAccessDriver</code>. Never access
- * the driver implementation directly.
- *
- * @return <code>DataAccessDriver</code> instance
- */
- public static DataAccessDriver getInstance()
- {
- return driver;
- }
- public abstract ForumDAO newForumDAO();
- public abstract GroupDAO newGroupDAO();
- public abstract PostDAO newPostDAO();
- public abstract PollDAO newPollDAO();
- public abstract RankingDAO newRankingDAO();
- public abstract TopicDAO newTopicDAO();
- public abstract UserDAO newUserDAO();
- public abstract CategoryDAO newCategoryDAO();
- public abstract TreeGroupDAO newTreeGroupDAO();
- public abstract SmilieDAO newSmilieDAO();
- public abstract GroupSecurityDAO newGroupSecurityDAO();
- public abstract PrivateMessageDAO newPrivateMessageDAO();
- public abstract UserSessionDAO newUserSessionDAO();
- public abstract ConfigDAO newConfigDAO();
- public abstract KarmaDAO newKarmaDAO();
- public abstract BookmarkDAO newBookmarkDAO();
- public abstract AttachmentDAO newAttachmentDAO();
- public abstract ModerationDAO newModerationDAO();
- public abstract BannerDAO newBannerDAO();
- public abstract SummaryDAO newSummaryDAO();
- public abstract MailIntegrationDAO newMailIntegrationDAO();
- public abstract ApiDAO newApiDAO();
- public abstract BanlistDAO newBanlistDAO();
- public abstract ModerationLogDAO newModerationLogDAO();
- public abstract LuceneDAO newLuceneDAO();
- }
init()方法仅在系统启动时被调用一次。JForum系统中有多处使用此类init(),有一点反向注入的味道。
系统启动时,初始化DataAccessDriver:
- publicstaticvoidloadDaoImplementation()
- {
- //Startthedao.driverimplementation
- Stringdriver=SystemGlobals.getValue(ConfigKeys.DAO_DRIVER);
- logger.info("LoadingJDBCdriver"+driver);
- try{
- Classc=Class.forName(driver);
- DataAccessDriverd=(DataAccessDriver)c.newInstance();
- DataAccessDriver.init(d);
- }
- catch(Exceptione){
- thrownewForumException(e);
- }
- }
- public static void loadDaoImplementation()
- {
- // Start the dao.driver implementation
- String driver = SystemGlobals.getValue(ConfigKeys.DAO_DRIVER);
- logger.info("Loading JDBC driver " + driver);
- try {
- Class c = Class.forName(driver);
- DataAccessDriver d = (DataAccessDriver)c.newInstance();
- DataAccessDriver.init(d);
- }
- catch (Exception e) {
- throw new ForumException(e);
- }
- }
如果是MysqL,String driver值为:net.jforum.dao.MysqL.MysqLDataAccessDriver