⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractdomain.java

📁 把java对象映射成数据库表中的一条记录
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * The Original Code is jRelationalFramework.
 *
 * The Initial Developer of the Original Code is is.com.
 * Portions created by is.com are Copyright (C) 2000 is.com.
 * All Rights Reserved.
 *
 * Contributor(s): Jonathan Carlson (joncrlsn@users.sf.net)
 * Contributor(s): ____________________________________
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License (the "GPL") or the GNU Lesser General
 * Public license (the "LGPL"), in which case the provisions of the GPL or
 * LGPL are applicable instead of those above.  If you wish to allow use of
 * your version of this file only under the terms of either the GPL or LGPL
 * and not to allow others to use your version of this file under the MPL,
 * indicate your decision by deleting the provisions above and replace them
 * with the notice and other provisions required by either the GPL or LGPL
 * License.  If you do not delete the provisions above, a recipient may use
 * your version of this file under either the MPL or GPL or LGPL License.
 *
 */
package com.is.jrf;


import com.is.util.sql.JDBCHelper;
import com.is.util.sql.JDBCHelperPool;

import java.sql.SQLException;
import java.sql.Timestamp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.lang.reflect.Field;

import org.apache.log4j.Category;


/**
 * Subclasses of AbstractDomain are generally table-specific objects.<p>
 *
 * If you have questions, make sure you read the documentation.  (see
 * Package.html).
 *
 * <p> Note: The "current date/time" function will be inserted into the
 * update SQL whenever a JRFConstants.CURRENT_TIMESTAMP is encountered for
 * an attribute.<p>
 *
 * Note: For an example of how to use the executeSQLQuery() method, see the
 * implementation of the findCustom(sqlString,jdbcHelper) method. <p>
 *
 * Note: If any of the superclass methods should never be used, you can
 * override them with a method that throws an exception.<p>
 *
 * JDBCHelperPool is now supported (version 1.5).  Find methods handle the
 * pools differently than the Update (save,delete) methods.  The find
 * methods "manually" return the JDBCHelper to the pool (if the JDBCHelper
 * is not part of a transaction).  The update methods depend upon the
 * endTransaction and rollback methods to return the connection to the pool.
 *
 */
public abstract class AbstractDomain
        implements JRFConstants
  {

  // These variables must be set (using their setters) from the setup()
  // method of the subclass.
  private   DatabasePolicy i_databasePolicy     = null;
  private   JDBCHelper     i_jdbcHelper         = null;
  private   JDBCHelperPool i_jdbcHelperPool     = null;
  private   String         i_jdbcHelperPoolName = null;
  private   String         i_tableName          = null;
  private   String         i_tableAlias         = null;

  private   String         i_subtypeTableName   = null;
  private   String         i_subtypeTableAlias  = null;
  private   JoinTable      i_subtypeTable       = null;
  private   ArrayList      i_subtypeColumnSpecs = new ArrayList();

  // These variables are set by the default constructor of this superclass.
  private   ArrayList      i_columnSpecs          = new ArrayList();
  private   ArrayList      i_joinTables           = new ArrayList();
  private   ColumnSpec     i_primaryKeyColumnSpec = null;
  private   ColumnSpec     i_subtypeIdentifierColumnSpec = null;

  // Following are some attributes that can be turned off when looking for
  // better performance when saving many objects.  To turn these off, set
  // them to false in the setup() method of the subclass.
  private   boolean        i_validateBeforeSaving = true;
  private   boolean        i_returnSavedObject    = true;

  private   boolean        i_useANSIJoins = true;

  private   boolean        i_usePostFind = true;

  private   boolean        i_shouldAutoCommit = false;

  /** This is the index of the first row to be converted to an object and
   * returned.  The index numbers start at 1 (not 0) */
  private   int            i_startingIndex = -1;
  /** This is the index of the last row to be converted to an object and
   * returned.  The index numbers start at 1 (not 0) */
  private   int            i_endingIndex = -1;

  static final Category LOG = Category.getInstance(AbstractDomain.class.getName());

  static final Map s_subtypeDomains = new HashMap();


  /* ===============  Constructors  =============== */

  /**
   * The option argument affects the behavior of this framework.  This was
   * added for the NO_POST_FIND option, but others may be added.
   *
   * @param option a value of type 'int'
   */
  public AbstractDomain(int option)
    {
    this();
    if (option == NO_POST_FIND)
        {
        this.setUsePostFind(false);
        }
    }

  /**
   * This constructor must be executed whether implicitly or explicitly.  If
   * the subclass setup() method does not set the database policy, table
   * name or JDBCHelper properly, then a NullPointerException is thrown with
   * a helpful error message rather than having it happen deep in the stack
   * where it is hard to figure out what went wrong.
   */
  public AbstractDomain()
    {
    this.setup();
    if (i_tableName == null ||
        i_tableName.trim().length()==0)
        {
        throw new ConfigurationException(
            "The table name was not set properly in the setup() method "
            + "of this class: " + this.getClass());
        }
    if (i_columnSpecs.size() == 0)
        {
        throw new ConfigurationException(
            "No column specs defined in " + this.getClass());
        }

    // Set i_primaryKeyColumnSpec and i_subtypeIdentifierColumnSpec
    this.categorizeColumnSpecs();

    // Determine the appropriate Join behavior
    // The default is to use ANSI joins
    String joinProperty = JRFProperties.getProperty("useANSIJoins");
    if (joinProperty != null &&
        (joinProperty.equalsIgnoreCase("false") ||
         joinProperty.equalsIgnoreCase("no")))
        {
        i_useANSIJoins = false;
        }

    this.setupSubtypeObjects();
    } // AbstractDomain()

  /* ===============  Static Methods  =============== */

  /**
   *  Inform this supertype domain class of a subtype domain class
   *  @param subtypeIdentifierValue  - value of the SUBTYPE_IDENTIFIER field
   *  @param domainClass  - value of the SUBTYPE_IDENTIFIER field
   */
  public static synchronized void addSubtypeDomain(Object subtypeIdentifierValue,
                                                   Class domainClass)
    {
    // Make sure the SUBTYPE_CODE field exists.
    Field subtypeCodeField = null;
    try
        {
        subtypeCodeField = domainClass.getField("SUBTYPE_CODE");
        }
    catch (Exception e)
        {
        String msg =
            "There is no public static SUBTYPE_CODE field defined "
            + "in subtype class: " + domainClass.getName();
        LOG.error(msg, e);
        throw new ConfigurationException(e, msg);
        }
    Object codeValue = null;
    try
        {
        codeValue = subtypeCodeField.get(domainClass);
        }
    catch (Exception e)
        {
        String msg =
            "There was a problem accessing the static SUBTYPE_CODE field "
            + "in subtype class: " + domainClass.getName();
        LOG.error(msg, e);
        throw new ConfigurationException(e, msg);
        }
    // compare
    s_subtypeDomains.put(codeValue, domainClass);
    }


  /* ===============  Getters and Setters  =============== */


  /**
   * If false, no validation will be done on this object before saving it.
   * Validating a UNIQUE attribute requires doing an SQL call so this might
   * improve performance in some cases.
   * @see AbstractDomain#setValidateBeforeSaving
   */
  public boolean getValidateBeforeSaving()
    {
    return i_validateBeforeSaving;
    }
  /** @see AbstractDomain#getValidateBeforeSaving */
  public void setValidateBeforeSaving(boolean b)
    {
    i_validateBeforeSaving = b;
    }


  /**
   * If true, the object is retrieved from the database and is returned to
   * the user at the end of the save operation.  This is important to be
   * true when using an optimisitic lock, a sequenced primary key, or a
   * current timestamp and you intend to make more updates to the object.
   *
   * @return a value of type 'boolean'
   * @see AbstractDomain#setReturnSavedObject
   */
  public boolean getReturnSavedObject()
    {
    return i_returnSavedObject;
    }
  /** @see AbstractDomain#getReturnSavedObject */
  public void setReturnSavedObject(boolean b)
    {
    i_returnSavedObject = b;
    }


  /**
   * If true, ANSI JOIN clauses will be used
   * @see AbstractDomain#setUseANSIJoins
   */
  public boolean useANSIJoins()
    {
    return i_useANSIJoins;
    }
  /** @see AbstractDomain#useANSIJoins */
  public void setUseANSIJoins(boolean b)
    {
    i_useANSIJoins = b;
    }


  /**
   * If true, the postFind() method will be called.
   * @see AbstractDomain#setUsePostFind
   * @return a value of type 'boolean'
   */
  public boolean usePostFind()
    {
    return i_usePostFind;
    }
  /** @see AbstractDomain#usePostFind */
  public void setUsePostFind(boolean b)
    {
    i_usePostFind = b;
    }


  /**
   *  The default is false.  This value is sent to the JDBCHelper
   *  whenever it is set.
   */
  public boolean getShouldAutoCommit()
    {
    return i_shouldAutoCommit;
    }
  public void setShouldAutoCommit(boolean b)
    {
    i_shouldAutoCommit = b;
    }


  public String getTableName()
    {
    return i_tableName;
    }
  /**
   * If the name looks like this: 'Customer c', then 'Customer' will be the
   * tableName and 'c' will be the tableAlias.
   *
   * @param s a value of type 'String'
   */
  public void setTableName(String s)
    {
    StringTokenizer st = new StringTokenizer(s, " ");
    if (st.hasMoreTokens())
        {
        i_tableName = st.nextToken();
        }
    else
        {
        throw new ConfigurationException("Invalid table name in " + this);
        }
    if (st.hasMoreTokens())
        {
        i_tableAlias = st.nextToken();
        }
    else
        {
        i_tableAlias = i_tableName;
        }
    } // setTableName(aString)


  public String getSubtypeTableName()
    {
    return i_subtypeTableName;
    }

  /**
   * If the name looks like this: 'Customer c', then 'Customer' will be the
   * tableName and 'c' will be the tableAlias.
   *
   * @param s a value of type 'String'
   */
  public void setSubtypeTableName(String s)
    {
    StringTokenizer st = new StringTokenizer(s, " ");
    if (st.hasMoreTokens())
        {
        i_subtypeTableName = st.nextToken();
        }
    else
        {
        throw new ConfigurationException("Invalid subtype table name: '" + s + "'");
        }
    if (st.hasMoreTokens())
        {
        i_subtypeTableAlias = st.nextToken();
        }
    else
        {
        i_subtypeTableAlias = i_subtypeTableName;
        }
    } // setSubtypeTableName(aString)


  public JoinTable getSubtypeTable()
    {
    return i_subtypeTable;
    }

  /** This is called by the constructor after setup() is called */
  private void setupSubtypeObjects()
    {
    if (i_subtypeColumnSpecs.size() == 0)
        {
        return;
        }
    if (i_subtypeTableName == null)
        {
        throw new ConfigurationException("Subtype table name was not set.");
        }

    // Subtype table will be treated as a join table for 'select'ing.
    i_subtypeTable =
            new JoinTable(
                i_subtypeTableName + " " + i_subtypeTableAlias,
                i_primaryKeyColumnSpec.getColumnName(), // super (left) table columns
                i_primaryKeyColumnSpec.getColumnName()); // sub table columns

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -