浏览 3157 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-29
最后修改:2009-03-29
1、Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个公共的具体方法时,那么它所有的子类都会自动拥有了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功进行编译了,因为你必须让每一个类都要再实现这个方法。 2、由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣,一个抽象类的实现只能由这个抽象类的子类给出。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。 3、从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。这里也可以理解为,混合类可以有共同的业务逻辑,也可以有很多特定的业务逻辑。 4、结合1、2点中抽象类和Java接口的各自优势,最精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java 抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java 接口在最上面,然后紧跟着抽象类。这个模式就是“缺省适配模式”。 在Java语言API中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。 Java接口和Java抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。 具体例子:torque3.3 一、 Torque多数据库支持的实现方式: 接口类:DB.java 抽象类:AbstractDBAdapter.java 部分遵循了java语言的命名规范:Abstract +接口名 具体实现类:DBOracle.java 连接oracle DBMSSQL.java 连接SQL Server DBSybase.java 连接Sysbase 上述类均继承:AbstractDBAdapter.java 配置文件torque.properties torque.database.default=yf torque.database.yf.adapter=sqlserver torque.dsfactory.yf.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory torque.dsfactory.yf.pool.maxWait = 10000 torque.dsfactory.yf.pool.maxIdle=8 torque.dsfactory.yf.pool.maxActive=20 torque.dsfactory.yf.pool.minEvictableIdleTimeMillis = 3600000 torque.dsfactory.yf.connection.driver = com.microsoft.jdbc.sqlserver.SQLServerDriver torque.dsfactory.yf.connection.url = jdbc:sqlserver://10.7.14.14:1433;databaseName=AuthCenter torque.dsfactory.yf.connection.user = sa torque.dsfactory.yf.connection.password = shdxgwzf 当我们更换为数据库时,修改配置文件(红色字体部分),即可。 package org.apache.torque.adapter; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; import java.util.Date; import org.apache.torque.TorqueException; import org.apache.torque.util.Query; /** * <code>DB</code> defines the interface for a Torque database * adapter. Support for new databases is added by implementing this * interface. A couple of default settings is provided by * subclassing <code>AbstractDBAdapter</code>. The new database adapter * and its corresponding JDBC driver need to be registered in the service * configuration file. * * <p>The Torque database adapters exist to present a uniform * interface to database access across all available databases. Once * the necessary adapters have been written and configured, * transparent swapping of databases is theoretically supported with * <i>zero code changes</i> and minimal configuration file * modifications. * * All database adapters need to be thread safe, as they are instantiated * only once fore a given configured database and may be accessed * simultaneously from several threads. * * <p>Torque uses the driver class name to find the right adapter. * A JDBC driver corresponding to your adapter must be added to the properties * file, using the fully-qualified class name of the driver. If no driver is * specified for your database, <code>driver.default</code> is used. * * <pre> * #### MySQL MM Driver * database.default.driver=org.gjt.mm.mysql.Driver * database.default.url=jdbc:mysql://localhost/DATABASENAME * </pre> * * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a> * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a> * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> * @version $Id: DB.java 476550 2006-11-18 16:08:37Z tfischer $ */ public interface DB extends Serializable, IDMethod { /** Database does not support limiting result sets. * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_NONE = 0; /** <code>SELECT ... LIMIT <limit>, [<offset>]</code> * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_POSTGRES = 1; /** <code>SELECT ... LIMIT [<offset>, ] <offset></code> * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_MYSQL = 2; /** <code>SET ROWCOUNT <offset> SELECT ... SET ROWCOUNT 0</code> * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_SYBASE = 3; /** <code><pre>SELECT ... WHERE ... AND ROWNUM < <limit></pre></code> * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_ORACLE = 4; /** <code><pre>SELECT ... WHERE ... AND ROW_NUMBER() OVER() < <limit></pre></code> * @deprecated This should not be exposed to the outside */ int LIMIT_STYLE_DB2 = 5; /** * Key for the configuration which contains database adapters. */ String ADAPTER_KEY = "adapter"; /** * Key for the configuration which contains database drivers. */ String DRIVER_KEY = "driver"; /** * This method is used to ignore case. * * @param in The string to transform to upper case. * @return The upper case string. */ String toUpperCase(String in); /** * Returns the character used to indicate the beginning and end of * a piece of text used in a SQL statement (generally a single * quote). * * @return The text delimeter. */ char getStringDelimiter(); /** * Returns the constant from the {@link * org.apache.torque.adapter.IDMethod} interface denoting which * type of primary key generation method this type of RDBMS uses. * * @return IDMethod constant */ String getIDMethodType(); /** * Returns SQL used to get the most recently inserted primary key. * Databases which have no support for this return * <code>null</code>. * * @param obj Information used for key generation. * @return The most recently inserted database key. */ String getIDMethodSQL(Object obj); /** * Locks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to lock. * @throws SQLException No Statement could be created or executed. */ void lockTable(Connection con, String table) throws SQLException; /** * Unlocks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to unlock. * @throws SQLException No Statement could be created or executed. */ void unlockTable(Connection con, String table) throws SQLException; /** * Modifies a SQL snippet such that its case is ignored by the database. * The SQL snippet can be a column name (like AURHOR.NAME), an * quoted explicit sql string (like 'abc') or any other sql value (like a * number etc.). * * @param in The SQL snippet whose case to ignore. * @return The string in a case that can be ignored. */ String ignoreCase(String in); /** * This method is used to ignore case in an ORDER BY clause. * Usually it is the same as ignoreCase, but some databases * (Interbase for example) does not use the same SQL in ORDER BY * and other clauses. * * @param in The string whose case to ignore. * @return The string in a case that can be ignored. */ String ignoreCaseInOrderBy(String in); /** * This method is used to check whether the database natively * supports limiting the size of the resultset. * * @return True if the database natively supports limiting the * size of the resultset. */ boolean supportsNativeLimit(); /** * This method is used to check whether the database natively * supports returning results starting at an offset position other * than 0. * * @return True if the database natively supports returning * results starting at an offset position other than 0. */ boolean supportsNativeOffset(); /** * This method is used to generate the database specific query * extension to limit the number of record returned. * * @param query The query to modify * @param offset the offset Value * @param limit the limit Value * * @throws TorqueException if any error occurs when building the query */ void generateLimits(Query query, int offset, int limit) throws TorqueException; /** * Whether backslashes (\) should be escaped in explicit SQL strings. * If true is returned, a BACKSLASH will be changed to "\\". If false * is returned, a BACKSLASH will be left as "\". * * @return true if the database needs to escape backslashes * in SqlExpressions. */ boolean escapeText(); /** * This method is used to check whether the database supports * limiting the size of the resultset. * * @return The limit style for the database. * @deprecated This should not be exposed to the outside */ int getLimitStyle(); /** * This method is used to format any date string. * Database can use different default date formats. * * @param date the Date to format * @return The proper date formatted String. */ String getDateString(Date date); /** * This method is used to format a boolean string. * * @param b the Boolean to format * @return The proper date formatted String. */ String getBooleanString(Boolean b); /** * Whether ILIKE should be used for case insensitive like clauses. * * @return true if ilike should be used for case insensitive likes, * false if ignoreCase should be applied to the compared strings. */ boolean useIlike(); /** * Whether an escape clause in like should be used. * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\'; * * @return whether the escape clause should be appended or not. */ boolean useEscapeClauseForLike(); } package org.apache.torque.adapter; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; import org.apache.torque.TorqueException; import org.apache.torque.util.Query; /** * This class is the abstract base for any database adapter * Support for new databases is added by subclassing this * class and implementing its abstract methods, and by * registering the new database adapter and its corresponding * JDBC driver in the service configuration file. * * <p>The Torque database adapters exist to present a uniform * interface to database access across all available databases. Once * the necessary adapters have been written and configured, * transparent swapping of databases is theoretically supported with * <i>zero code changes</i> and minimal configuration file * modifications. * * <p>Torque uses the driver class name to find the right adapter. * A JDBC driver corresponding to your adapter must be added to the properties * file, using the fully-qualified class name of the driver. If no driver is * specified for your database, <code>driver.default</code> is used. * * <pre> * #### MySQL MM Driver * database.default.driver=org.gjt.mm.mysql.Driver * database.default.url=jdbc:mysql://localhost/DATABASENAME * </pre> * * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a> * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a> * @version $Id: DB.java 393063 2006-04-10 20:59:16Z tfischer $ */ public abstract class AbstractDBAdapter implements DB { /** * Empty constructor. */ protected AbstractDBAdapter() { } /** * This method is used to ignore case. * * @param in The string to transform to upper case. * @return The upper case string. */ public abstract String toUpperCase(String in); /** * Returns the character used to indicate the beginning and end of * a piece of text used in a SQL statement (generally a single * quote). * * @return The text delimeter. */ public char getStringDelimiter() { return '\''; } /** * Returns the constant from the {@link * org.apache.torque.adapter.IDMethod} interface denoting which * type of primary key generation method this type of RDBMS uses. * * @return IDMethod constant */ public abstract String getIDMethodType(); /** * Returns SQL used to get the most recently inserted primary key. * Databases which have no support for this return * <code>null</code>. * * @param obj Information used for key generation. * @return The most recently inserted database key. */ public abstract String getIDMethodSQL(Object obj); /** * Locks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to lock. * @throws SQLException No Statement could be created or executed. */ public abstract void lockTable(Connection con, String table) throws SQLException; /** * Unlocks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to unlock. * @throws SQLException No Statement could be created or executed. */ public abstract void unlockTable(Connection con, String table) throws SQLException; /** * This method is used to ignore case. * * @param in The string whose case to ignore. * @return The string in a case that can be ignored. */ public abstract String ignoreCase(String in); /** * This method is used to ignore case in an ORDER BY clause. * Usually it is the same as ignoreCase, but some databases * (Interbase for example) does not use the same SQL in ORDER BY * and other clauses. * * @param in The string whose case to ignore. * @return The string in a case that can be ignored. */ public String ignoreCaseInOrderBy(String in) { return ignoreCase(in); } /** * This method is used to check whether the database natively * supports limiting the size of the resultset. * * @return True if the database natively supports limiting the * size of the resultset. */ public boolean supportsNativeLimit() { return false; } /** * This method is used to check whether the database natively * supports returning results starting at an offset position other * than 0. * * @return True if the database natively supports returning * results starting at an offset position other than 0. */ public boolean supportsNativeOffset() { return false; } /** * This method is used to generate the database specific query * extension to limit the number of record returned. * * @param query The query to modify * @param offset the offset Value * @param limit the limit Value * * @throws TorqueException if any error occurs when building the query */ public void generateLimits(Query query, int offset, int limit) throws TorqueException { if (supportsNativeLimit()) { query.setLimit(String.valueOf(limit)); } } /** * This method is for the SqlExpression.quoteAndEscape rules. The rule is, * any string in a SqlExpression with a BACKSLASH will either be changed to * "\\" or left as "\". SapDB does not need the escape character. * * @return true if the database needs to escape text in SqlExpressions. */ public boolean escapeText() { return true; } /** * This method is used to check whether the database supports * limiting the size of the resultset. * * @return The limit style for the database. * @deprecated This should not be exposed to the outside */ public int getLimitStyle() { return LIMIT_STYLE_NONE; } /** * This method is used to format any date string. * Database can use different default date formats. * * @param date the Date to format * @return The proper date formatted String. */ public String getDateString(Date date) { Timestamp ts = null; if (date instanceof Timestamp) { ts = (Timestamp) date; } else { ts = new Timestamp(date.getTime()); } return ("{ts '" + ts + "'}"); } /** * This method is used to format a boolean string. * * @param b the Boolean to format * @return The proper date formatted String. */ public String getBooleanString(Boolean b) { return (Boolean.TRUE.equals(b) ? "1" : "0"); } /** * Whether ILIKE should be used for case insensitive like clauses. * * As most databases do not use ILIKE, this implementation returns false. * This behaviour may be overwritten in subclasses. * * @return true if ilike should be used for case insensitive likes, * false if ignoreCase should be applied to the compared strings. */ public boolean useIlike() { return false; } /** * Whether an escape clause in like should be used. * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\'; * * As most databases do not need the escape clause, this implementation * always returns <code>false</code>. This behaviour can be overwritten * in subclasses. * * @return whether the escape clause should be appended or not. */ public boolean useEscapeClauseForLike() { return false; } } package org.apache.torque.adapter; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import java.util.ListIterator; import java.util.Set; import org.apache.torque.util.Query; import org.apache.torque.util.UniqueList; /** * This code should be used for an Oracle database pool. * * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a> * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a> * @author <a href="mailto:bschneider@vecna.com">Bill Schneider</a> * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> * @version $Id: DBOracle.java 476550 2006-11-18 16:08:37Z tfischer $ */ public class DBOracle extends AbstractDBAdapter { /** * Serial version */ private static final long serialVersionUID = 8966976210230241194L; /** date format used in getDateString() */ private static final String DATE_FORMAT = "dd-MM-yyyy HH:mm:ss"; /** * Empty constructor. */ protected DBOracle() { } /** * This method is used to ignore case. * * @param in The string to transform to upper case. * @return The upper case string. */ public String toUpperCase(String in) { return new StringBuffer("UPPER(").append(in).append(")").toString(); } /** * This method is used to ignore case. * * @param in The string whose case to ignore. * @return The string in a case that can be ignored. */ public String ignoreCase(String in) { return new StringBuffer("UPPER(").append(in).append(")").toString(); } /** * This method is used to format any date string. * * @param date the Date to format * @return The date formatted String for Oracle. */ public String getDateString(Date date) { return "TO_DATE('" + new SimpleDateFormat(DATE_FORMAT).format(date) + "', 'DD-MM-YYYY HH24:MI:SS')"; } /** * @see org.apache.torque.adapter.DB#getIDMethodType() */ public String getIDMethodType() { return SEQUENCE; } /** * Returns the next key from a sequence. Uses the following * implementation: * * <blockquote><code><pre> * select sequenceName.nextval from dual * </pre></code></blockquote> * * @param sequenceName The name of the sequence (should be of type * <code>String</code>). * @return SQL to retreive the next database key. * @see org.apache.torque.adapter.DB#getIDMethodSQL(Object) */ public String getIDMethodSQL(Object sequenceName) { return ("select " + sequenceName + ".nextval from dual"); } /** * Locks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to lock. * @exception SQLException No Statement could be created or executed. */ public void lockTable(Connection con, String table) throws SQLException { Statement statement = con.createStatement(); StringBuffer stmt = new StringBuffer(); stmt.append("SELECT next_id FROM ") .append(table) .append(" FOR UPDATE"); statement.executeQuery(stmt.toString()); } /** * Unlocks the specified table. * * @param con The JDBC connection to use. * @param table The name of the table to unlock. * @exception SQLException No Statement could be created or executed. */ public void unlockTable(Connection con, String table) throws SQLException { // Tables in Oracle are unlocked when a commit is issued. The // user may have issued a commit but do it here to be sure. con.commit(); } /** * This method is used to check whether the database supports * limiting the size of the resultset. * * @return LIMIT_STYLE_ORACLE. * @deprecated This should not be exposed to the outside */ public int getLimitStyle() { return DB.LIMIT_STYLE_ORACLE; } /** * Return true for Oracle * @see org.apache.torque.adapter.AbstractDBAdapter#supportsNativeLimit() */ public boolean supportsNativeLimit() { return true; } /** * Return true for Oracle * @see org.apache.torque.adapter.AbstractDBAdapter#supportsNativeOffset() */ public boolean supportsNativeOffset() { return true; } /** * Build Oracle-style query with limit or offset. * If the original SQL is in variable: query then the requlting * SQL looks like this: * <pre> * SELECT B.* FROM ( * SELECT A.*, rownum as TORQUE$ROWNUM FROM ( * query * ) A * ) B WHERE B.TORQUE$ROWNUM > offset AND B.TORQUE$ROWNUM * <= offset + limit * </pre> * * @param query The query to modify * @param offset the offset Value * @param limit the limit Value */ public void generateLimits(Query query, int offset, int limit) { StringBuffer preLimit = new StringBuffer() .append("SELECT B.* FROM ( ") .append("SELECT A.*, rownum AS TORQUE$ROWNUM FROM ( "); StringBuffer postLimit = new StringBuffer() .append(" ) A ") .append(" ) B WHERE "); if (offset > 0) { postLimit.append(" B.TORQUE$ROWNUM > ") .append(offset); if (limit >= 0) { postLimit.append(" AND B.TORQUE$ROWNUM <= ") .append(offset + limit); } } else { postLimit.append(" B.TORQUE$ROWNUM <= ") .append(limit); } query.setPreLimit(preLimit.toString()); query.setPostLimit(postLimit.toString()); query.setLimit(null); // the query must not contain same column names or aliases. // Find double column names and aliases and create unique aliases // TODO: does not work for functions yet UniqueList selectColumns = query.getSelectClause(); int replacementSuffix = 0; Set columnNames = new HashSet(); // first pass: only remember aliased columns // No replacements need to take place because double aliases // are not allowed anyway // So alias names will be retained for (ListIterator columnIt = selectColumns.listIterator(); columnIt.hasNext();) { String selectColumn = (String) columnIt.next(); // check for sql function if ((selectColumn.indexOf('(') != -1) || (selectColumn.indexOf(')') != -1)) { // Sql function. Disregard. continue; } // check if alias name exists int spacePos = selectColumn.lastIndexOf(' '); if (spacePos == -1) { // no alias, disregard for now continue; } String aliasName = selectColumn.substring(spacePos + 1); columnNames.add(aliasName); } // second pass. Regard ordinary columns only for (ListIterator columnIt = selectColumns.listIterator(); columnIt.hasNext();) { String selectColumn = (String) columnIt.next(); // check for sql function if ((selectColumn.indexOf('(') != -1) || (selectColumn.indexOf(')') != -1)) { // Sql function. Disregard. continue; } { int spacePos = selectColumn.lastIndexOf(' '); if (spacePos != -1) { // alias, already processed in first pass continue; } } // split into column name and tableName String column; { int dotPos = selectColumn.lastIndexOf('.'); if (dotPos != -1) { column = selectColumn.substring(dotPos + 1); } else { column = selectColumn; } } if (columnNames.contains(column)) { // column needs to be aliased // get replacement name String aliasName; do { aliasName = "a" + replacementSuffix; ++replacementSuffix; } while (columnNames.contains(aliasName)); selectColumn = selectColumn + " " + aliasName; columnIt.set(selectColumn); columnNames.add(aliasName); } else { columnNames.add(column); } } } /** * This method is for the SqlExpression.quoteAndEscape rules. The rule is, * any string in a SqlExpression with a BACKSLASH will either be changed to * "\\" or left as "\". SapDB does not need the escape character. * * @return false. */ public boolean escapeText() { return false; } /** * Whether an escape clause in like should be used. * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\'; * * Oracle needs this, so this implementation always returns * <code>true</code>. * * @return whether the escape clause should be appended or not. */ public boolean useEscapeClauseForLike() { return true; } } 二、关于torque数据源工厂类的实现方式: 接口类:DataSourceFactory.java 抽象类:AbstractDataSourceFactory.java 遵循了java语言的命名规范:Abstract +接口名 具体实现类:C3P0DataSourceFactory.java SharedPoolDataSourceFactory.java JndiDataSourceFactory.java 上述类均继承:AbstractDataSourceFactory.java 配置文件torque.properties torque.dsfactory.yf.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory torque.dsfactory.yf.pool.maxWait = 10000 torque.dsfactory.yf.pool.maxIdle=8 torque.dsfactory.yf.pool.maxActive=20 torque.dsfactory.yf.pool.minEvictableIdleTimeMillis = 3600000 torque.dsfactory.yf.connection.driver = com.microsoft.jdbc.sqlserver.SQLServerDriver torque.dsfactory.yf.connection.url = jdbc:sqlserver://10.7.14.14:1433;databaseName=AuthCenter torque.dsfactory.yf.connection.user = sa torque.dsfactory.yf.connection.password = shdxgwzf 其中C3P0DataSourceFactory.java 是我为将hibernate使用的C3P0数据库连接池作为一种可以使用的数据库连接池而实现的。当我们更换为C3P0数据库连接池,修改配置文件(红色字体部分),即可。 package org.apache.torque.dsfactory; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.sql.DataSource; import org.apache.commons.configuration.Configuration; import org.apache.torque.TorqueException; /** * A factory that returns a DataSource. * * @author <a href="mailto:jmcnally@apache.org">John McNally</a> * @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a> * @version $Id: DataSourceFactory.java 473821 2006-11-11 22:37:25Z tv $ */ public interface DataSourceFactory { /** * Key for the configuration which contains DataSourceFactories */ String DSFACTORY_KEY = "dsfactory"; /** * Key for the configuration which contains the fully qualified name * of the factory implementation class */ String FACTORY_KEY = "factory"; /** * @return the <code>DataSource</code> configured by the factory. * @throws TorqueException if the source can't be returned */ DataSource getDataSource() throws TorqueException; /** * Initialize the factory. * * @param configuration where to load the factory settings from * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. */ void initialize(Configuration configuration) throws TorqueException; /** * Sets the current schema for the database connection * * @param schema The current schema name * @deprecated use DatabaseInfo.setSchema() instead. Will be removed * in a future version of Torque. */ void setSchema(String schema); /** * This method returns the current schema for the database connection * * @return The current schema name. Null means, no schema has been set. * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. * @deprecated use DatabaseInfo.getSchema() instead. Will be removed * in a future version of Torque. */ String getSchema(); /** * A hook which is called when the resources of the associated DataSource * can be released. * After close() is called, the other methods may not work any more * (e.g. getDataSource() might return null). * It is not guaranteed that this method does anything. For example, * we do not want to close connections retrieved via JNDI, so the * JndiDataSouurceFactory does not close these connections * * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. */ void close() throws TorqueException; } package org.apache.torque.dsfactory; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Iterator; import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.MappedPropertyDescriptor; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.configuration.Configuration; import org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.torque.Torque; import org.apache.torque.TorqueException; import org.apache.torque.TorqueRuntimeException; /** * A class that contains common functionality of the factories in this * package. * * @author <a href="mailto:jmcnally@apache.org">John McNally</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @version $Id: AbstractDataSourceFactory.java 473821 2006-11-11 22:37:25Z tv $ */ public abstract class AbstractDataSourceFactory implements DataSourceFactory { /** "pool" Key for the configuration */ public static final String POOL_KEY = "pool"; /** "connection" Key for the configuration */ public static final String CONNECTION_KEY = "connection"; /** "schema" Key for the configuration */ public static final String SCHEMA_KEY = "schema"; /** "defaults" Key for the configuration */ public static final String DEFAULTS_KEY = "defaults"; /** "defaults.pool" Key for the configuration */ public static final String DEFAULT_POOL_KEY = DEFAULTS_KEY + "." + POOL_KEY; /** "defaults.connection" Key for the configuration */ public static final String DEFAULT_CONNECTION_KEY = DEFAULTS_KEY + "." + CONNECTION_KEY; /** default schema name for the configuration */ public static final String DEFAULT_SCHEMA_KEY = DEFAULTS_KEY + "." + SCHEMA_KEY; /** The log */ private static Log log = LogFactory.getLog(AbstractDataSourceFactory.class); /** Internal Marker for the Schema name of this database connection */ private String schema = null; /** * Encapsulates setting configuration properties on * <code>DataSource</code> objects. * * @param property the property to read from the configuration * @param c the configuration to read the property from * @param ds the <code>DataSource</code> instance to write the property to * @throws Exception if anything goes wrong */ protected void setProperty(String property, Configuration c, Object ds) throws Exception { if (c == null || c.isEmpty()) { return; } String key = property; Class dsClass = ds.getClass(); int dot = property.indexOf('.'); try { if (dot > 0) { property = property.substring(0, dot); MappedPropertyDescriptor mappedPD = new MappedPropertyDescriptor(property, dsClass); Class propertyType = mappedPD.getMappedPropertyType(); Configuration subProps = c.subset(property); // use reflection to set properties Iterator j = subProps.getKeys(); while (j.hasNext()) { String subProp = (String) j.next(); String propVal = subProps.getString(subProp); Object value = ConvertUtils.convert(propVal, propertyType); PropertyUtils .setMappedProperty(ds, property, subProp, value); if (log.isDebugEnabled()) { log.debug("setMappedProperty(" + ds + ", " + property + ", " + subProp + ", " + value + ")"); } } } else { if ("password".equals(key)) { // do not log value of password // for this, ConvertUtils.convert cannot be used // as it also logs the value of the converted property // so it is assumed here that the password is a String String value = c.getString(property); PropertyUtils.setSimpleProperty(ds, property, value); if (log.isDebugEnabled()) { log.debug("setSimpleProperty(" + ds + ", " + property + ", " + " (value not logged)" + ")"); } log.error(property + " == " + value ); } else { Class propertyType = PropertyUtils.getPropertyType(ds, property); Object value = ConvertUtils.convert(c.getString(property), propertyType); PropertyUtils.setSimpleProperty(ds, property, value); if (log.isDebugEnabled()) { log.debug("setSimpleProperty(" + ds + ", " + property + ", " + value + ")"); } else { if("user".equals(key) || "url".equals(key) || "driver".equals(key)) log.error(property + " == " + value ); } } } } catch (RuntimeException e) { throw new TorqueRuntimeException( "Runtime error setting property " + property, e); } catch (Exception e) { log.error( "Property: " + property + " value: " + c.getString(key) + " is not supported by DataSource: " + ds.getClass().getName()); } } /** * Iterate over a Configuration subset and apply all * properties to a passed object which must contain Bean * setter and getter * * @param c The configuration subset * @param o The object to apply the properties to * @throws TorqueException if a property set fails */ protected void applyConfiguration(Configuration c, Object o) throws TorqueException { log.debug("applyConfiguration(" + c + ", " + o + ")"); if (c != null) { try { for (Iterator i = c.getKeys(); i.hasNext();) { String key = (String) i.next(); setProperty(key, c, o); } } catch (Exception e) { log.error(e); throw new TorqueException(e); } } } /** * Initializes the ConnectionPoolDataSource. * * @param configuration where to read the settings from * @throws TorqueException if a property set fails * @return a configured <code>ConnectionPoolDataSource</code> */ protected ConnectionPoolDataSource initCPDS(Configuration configuration) throws TorqueException { log.debug("Starting initCPDS"); ConnectionPoolDataSource cpds = new DriverAdapterCPDS(); Configuration c = Torque.getConfiguration(); if (c == null || c.isEmpty()) { log.warn("Global Configuration not set," + " no Default connection pool data source configured!"); } else { Configuration conf = c.subset(DEFAULT_CONNECTION_KEY); applyConfiguration(conf, cpds); } Configuration conf = configuration.subset(CONNECTION_KEY); applyConfiguration(conf, cpds); return cpds; } /** * Sets the current schema for the database connection * * @param schema The current schema name */ public void setSchema(String schema) { this.schema = schema; } /** * This method returns the current schema for the database connection * * @return The current schema name. Null means, no schema has been set. * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. * @deprecated use DatabaseInfo.setSchema() instead. Will be removed * in a future version of Torque. */ public String getSchema() { return schema; } /** * @return the <code>DataSource</code> configured by the factory. * @throws TorqueException if the source can't be returned */ public abstract DataSource getDataSource() throws TorqueException; /** * Initialize the factory. * * @param configuration where to load the factory settings from * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. */ public void initialize(Configuration configuration) throws TorqueException { if (configuration == null) { throw new TorqueException( "Torque cannot be initialized without " + "a valid configuration. Please check the log files " + "for further details."); } schema = configuration.getString(SCHEMA_KEY, null); if (StringUtils.isEmpty(schema)) { Configuration conf = Torque.getConfiguration(); schema = conf.getString(DEFAULT_SCHEMA_KEY, null); } } } package org.apache.torque.dsfactory; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import org.apache.commons.configuration.Configuration; import org.apache.commons.dbcp.datasources.SharedPoolDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.torque.Torque; import org.apache.torque.TorqueException; /** * A factory that looks up the DataSource using the JDBC2 pool methods. * * @author <a href="mailto:jmcnally@apache.org">John McNally</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @version $Id: SharedPoolDataSourceFactory.java 476550 2006-11-18 16:08:37Z tfischer $ */ public class SharedPoolDataSourceFactory extends AbstractDataSourceFactory { /** The log. */ private static Log log = LogFactory.getLog(SharedPoolDataSourceFactory.class); /** The wrapped <code>DataSource</code>. */ private SharedPoolDataSource ds = null; /** * @see org.apache.torque.dsfactory.DataSourceFactory#getDataSource */ public DataSource getDataSource() { return ds; } /** * @see org.apache.torque.dsfactory.DataSourceFactory#initialize */ public void initialize(Configuration configuration) throws TorqueException { super.initialize(configuration); ConnectionPoolDataSource cpds = initCPDS(configuration); SharedPoolDataSource dataSource = initJdbc2Pool(configuration); dataSource.setConnectionPoolDataSource(cpds); this.ds = dataSource; } /** * Initializes the Jdbc2PoolDataSource. * * @param configuration where to read the settings from * @throws TorqueException if a property set fails * @return a configured <code>Jdbc2PoolDataSource</code> */ private SharedPoolDataSource initJdbc2Pool(Configuration configuration) throws TorqueException { log.debug("Starting initJdbc2Pool"); SharedPoolDataSource dataSource = new SharedPoolDataSource(); Configuration c = Torque.getConfiguration(); if (c == null || c.isEmpty()) { log.warn("Global Configuration not set," + " no Default pool data source configured!"); } else { Configuration conf = c.subset(DEFAULT_POOL_KEY); applyConfiguration(conf, dataSource); } Configuration conf = configuration.subset(POOL_KEY); applyConfiguration(conf, dataSource); return dataSource; } /** * Closes the pool associated with this factory and releases it. * @throws TorqueException if the pool cannot be closed properly */ public void close() throws TorqueException { try { ds.close(); } catch (Exception e) { log.error("Exception caught during close()", e); throw new TorqueException(e); } ds = null; } } package org.apache.torque.dsfactory; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import org.apache.commons.configuration.Configuration; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.torque.Torque; import org.apache.torque.TorqueException; /** * A factory that looks up the DataSource using the JDBC2 pool methods. * * @author <a href="mailto:jmcnally@apache.org">John McNally</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @version $Id: C3P0DataSourceFactory.java 476550 2006-11-18 16:08:37Z tfischer $ */ public class C3P0DataSourceFactory extends AbstractDataSourceFactory { /** The log. */ private static Log log = LogFactory.getLog(C3P0DataSourceFactory.class); /** The wrapped <code>DataSource</code>. */ private ComboPooledDataSource ds = null; /** * @see org.apache.torque.dsfactory.DataSourceFactory#getDataSource */ public DataSource getDataSource() { return ds; } /** * @see org.apache.torque.dsfactory.DataSourceFactory#initialize */ public void initialize(Configuration configuration) throws TorqueException { log.debug("Starting initialize ----------- "); super.initialize(configuration); ComboPooledDataSource dataSource = initJdbc2Pool(configuration); this.ds = dataSource; } /** * Initializes the Jdbc2PoolDataSource. * * @param configuration where to read the settings from * @throws TorqueException if a property set fails * @return a configured <code>Jdbc2PoolDataSource</code> */ private ComboPooledDataSource initJdbc2Pool(Configuration configuration) throws TorqueException { log.debug("Starting initJdbc2Pool"); Configuration c = Torque.getConfiguration(); ComboPooledDataSource dataSource = new ComboPooledDataSource(); if (c == null || c.isEmpty()) { log.warn("Global Configuration not set," + " no Default pool data source configured!"); } else { Configuration conf = c.subset(DEFAULT_POOL_KEY); applyConfiguration(conf, dataSource); } //init 数据库连接 Configuration connConf = configuration.subset(CONNECTION_KEY); applyConfiguration(connConf, dataSource); //init 数据库连接池 Configuration conf = configuration.subset(POOL_KEY); applyConfiguration(conf, dataSource); return dataSource; } /** * Closes the pool associated with this factory and releases it. * @throws TorqueException if the pool cannot be closed properly */ public void close() throws TorqueException { try { ds.close(); } catch (Exception e) { log.error("Exception caught during close()", e); throw new TorqueException(e); } ds = null; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |