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。
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:
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