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