TableCommand.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:14k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: TableCommand.java,v 1.5 2005/10/10 17:01:16 rbair Exp $
  3.  *
  4.  * Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.dataset.provider.sql;
  22. import java.beans.PropertyChangeListener;
  23. import java.beans.PropertyChangeSupport;
  24. import java.sql.PreparedStatement;
  25. import java.util.HashMap;
  26. import java.util.List;
  27. import java.util.Map;
  28. import org.jdesktop.dataset.DataColumn;
  29. import org.jdesktop.dataset.DataRow;
  30. /**
  31.  * A simplified DataCommand for use with an SQLDataProvider, which acts against
  32.  * all of the columns in a given RDBMS table. No joins are used.
  33.  * Because this is a simple table-based DataCommand, it can infer the INSERT,
  34.  * UPDATE, and DELETE SQL statements to use when working with the table.
  35.  * <p>
  36.  *
  37.  * @author rbair
  38.  */
  39. public class TableCommand extends AbstractSqlCommand {
  40.     /**
  41.      * The name of the table from which to get results. If this value is
  42.      * null, then the TableCommand is in an uninitialized state
  43.      */
  44.     private String tableName;
  45.     /**
  46.      * The where clause for this query. This is never null, but may be empty
  47.      */
  48.     private String whereClause = "";
  49.     /**
  50.      * The order by clause for this query. This is never null, but may be empty
  51.      */
  52.     private String orderByClause = "";
  53.     /**
  54.      * The having clause for this query. This is never null, but may be empty
  55.      */
  56.     private String havingClause = "";
  57.     
  58. /**
  59.      * Helper used for notifying of bean property changes. In particular, this
  60.      * is used to notify of changes in the tableName or various clauses
  61.      */
  62.     private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
  63.     
  64.     /** 
  65.      * Creates a new instance of TableCommand 
  66.      */
  67.     public TableCommand() {
  68.         this(null, null);
  69.     }
  70.     
  71.     public TableCommand(String tableName) {
  72.         this(tableName, null);
  73.     }
  74.     
  75.     public TableCommand(String tableName, String whereClause) {
  76.         setTableName(tableName);
  77.         setWhereClause(whereClause);
  78.     }
  79.     
  80.     /**
  81.      * Sets the name of the table in the Database from which to load/save
  82.      * data
  83.      */
  84.     public void setTableName(String tableName) {
  85.         if (this.tableName != tableName) {
  86.             String oldValue = this.tableName;
  87.             this.tableName = tableName;
  88.             pcs.firePropertyChange("tableName", oldValue, tableName);
  89.         }
  90.     }
  91.     
  92.     /**
  93.      * Sets the where clause to use in the query. This clause *must* include
  94.      * the &quot;where&quot; keyword
  95.      */
  96.     public void setWhereClause(String clause) {
  97.         if (whereClause != clause) {
  98.             String oldValue = this.whereClause;
  99.             whereClause = clause == null ? "" : clause;
  100.             pcs.firePropertyChange("whereClause", oldValue, whereClause);
  101.         }
  102.     }
  103.     
  104.     public void setOrderByClause(String clause) {
  105.         if (orderByClause != clause) {
  106.             String oldValue = this.orderByClause;
  107.             orderByClause = clause == null ? "" : clause;
  108.             pcs.firePropertyChange("orderByClause", oldValue, orderByClause);
  109.         }
  110.     }
  111.     
  112.     public void setHavingClause(String clause) {
  113.         if (havingClause != clause) {
  114.             String oldValue = this.havingClause;
  115.             havingClause = clause == null ? "" : clause;
  116.             pcs.firePropertyChange("havingClause", oldValue, havingClause);
  117.         }
  118.     }
  119.     
  120. //
  121. //    public void executeSaveQuery(DataSet ds) {
  122. //     if (ds == null) {
  123. //     return;
  124. //     }
  125. //    
  126. //        if (!(ds instanceof RowSetDataSet)) {
  127. //            throw new IllegalArgumentException("The SimpleJDBCQueryTask " +
  128. //                    "cannot save data sources that it did not generate");
  129. //        }
  130. //        
  131. //        try {
  132. //            CachedRowSet crs = ((RowSetDataSet)ds).getRowSet();
  133. //            /*
  134. //             * HACK! This next line (setTransactionIsolation) is a total hack,
  135. //             * needed because the RI for CachedRowSetWriter tries to set the
  136. //             * transaction isolation level to the CachedRowSets level.
  137. //             * Unfortunately, the default level is unacceptable for HSQL.
  138. //             * The RI probably needs to be hacked so that the CachedRowSetImpl
  139. //             * will have its transaction isolation set to a level acceptable
  140. //             * by the Database.
  141. //             */
  142. //            crs.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
  143. //            crs.acceptChanges(dsc.getConnection());
  144. //            dsc.getConnection().commit();
  145. //        } catch (Exception e) {
  146. //            e.printStackTrace();
  147. //        }
  148. //    }
  149. //
  150.     /**
  151.      * 
  152.      * @param listener
  153.      */
  154.     public void addPropertyChangeListener(PropertyChangeListener listener) {
  155.         pcs.addPropertyChangeListener(listener);
  156.     }
  157.     /**
  158.      * 
  159.      * @param propertyName
  160.      * @param listener
  161.      */
  162.     public void addPropertyChangeListener(String propertyName,
  163.             PropertyChangeListener listener) {
  164.         pcs.addPropertyChangeListener(propertyName, listener);
  165.     }
  166.     
  167.     /**
  168.      *
  169.      */
  170.     public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
  171.      pcs.removePropertyChangeListener(propertyName, listener);
  172.     }
  173.     public String[] getParameterNames() {
  174. return super.getParameterNames(new String[]{whereClause, orderByClause, havingClause});
  175.     }
  176.     private PreparedStatement createPreparedStatement(String parameterizedSql, JDBCDataConnection conn) throws Exception {
  177.         //replace all of the named parameters in the sql with their
  178.         //corrosponding values. This is done by first converting the sql
  179.         //to proper JDBC sql by inserting '?' for each and every param.
  180.         //As this is done, a record is kept of which parameters go with
  181.         //which indexes. Then, the parameter values are applied.
  182.         //map containing the indexes for each named param
  183.         Map<String,List<Integer>> indexes = new HashMap<String,List<Integer>>();
  184.         String sql = constructSql(parameterizedSql, indexes);
  185.         PreparedStatement ps = conn.prepareStatement(sql);
  186.         //now, apply the given set of parameters
  187.         for (String paramName : getParameterNames()) {
  188.             List<Integer> list = indexes.get(paramName);
  189.             if (list != null) {
  190.                 for (int index : list) {
  191.                     ps.setObject(index + 1, getParameter(paramName));
  192.                 }
  193.             }
  194.         }
  195.         return ps;
  196.     }
  197.     
  198.     protected PreparedStatement getSelectStatement(JDBCDataConnection conn) throws Exception {
  199.         if (tableName == null) {
  200.             //this TableCommand has not been configured, throw an exception
  201.             throw new Exception("TableCommand not configured with a table name");
  202.         }
  203.         try {
  204.             //construct the select sql by combining the tableName portion and
  205.             //the various clause portions
  206.             StringBuilder buffer = new StringBuilder();
  207.             buffer.append("select * from ");
  208.             buffer.append(tableName);
  209.             buffer.append(" ");
  210.             buffer.append(whereClause);
  211.             buffer.append(" ");
  212.             buffer.append(orderByClause);
  213.             buffer.append(" ");
  214.             buffer.append(havingClause);
  215.             String sql = buffer.toString().trim();
  216.             return createPreparedStatement(sql, conn);
  217.         } catch (Exception e) {
  218.             e.printStackTrace();
  219.             return null;
  220.         }
  221.     }
  222.     protected PreparedStatement getUpdateStatement(JDBCDataConnection conn, DataRow row) throws Exception {
  223.         if (tableName == null) {
  224.             //this TableCommand has not been configured, throw an exception
  225.             throw new Exception("TableCommand not configured with a table name");
  226.         }
  227.         try {
  228.             Map<String,Object> values = new HashMap<String,Object>();
  229.             //construct the select sql by combining the tableName portion and
  230.             //the various clause portions
  231.             StringBuilder buffer = new StringBuilder();
  232.             buffer.append("update ");
  233.             buffer.append(tableName);
  234.             buffer.append(" set ");
  235.             //iterate over all of the columns in the row. Each cell that has been
  236.             //modified needs to be included in this update statement
  237.             List<DataColumn> columns = row.getTable().getColumns();
  238.             int modCount = 0;
  239.             for (int i=0; i<columns.size(); i++) {
  240.                 DataColumn col = columns.get(i);
  241.                 if (row.isModified(col)) {
  242.                     buffer.append(col.getName());
  243.                     buffer.append(" = :" + col.getName() + ", ");
  244.                     values.put(col.getName(), row.getValue(col));
  245.                     modCount++;
  246.                 }
  247.             }
  248.             //if nothing was modified, skip this row
  249.             if (modCount == 0) {
  250.                 return null;
  251.             }
  252.             //remove the trailing comma
  253.             buffer.delete(buffer.length()-2, buffer.length());
  254.             
  255.             //do the where clause
  256.             buffer.append(" where ");
  257.             int keyColCount = 0;
  258.             for (int i=0; i<columns.size(); i++) {
  259.                 DataColumn col = columns.get(i);
  260.                 if (col.isKeyColumn()) {
  261.                     buffer.append(col.getName());
  262.                     buffer.append(" = :orig_" + col.getName() + " and ");
  263.                     values.put("orig_" + col.getName(), row.getOriginalValue(col));
  264.                     keyColCount++;
  265.                 }
  266.             }
  267.             if (keyColCount == 0) {
  268.                 System.err.println("WARNING!!! No key columns were specified, the entire table '" + tableName + "' will be updated!!");
  269.                 //remove the where clause
  270.                 buffer.delete(buffer.length() - 7, buffer.length());
  271.             } else {
  272.                 buffer.delete(buffer.length() - 4, buffer.length());
  273.             }
  274.             
  275.             String sql = buffer.toString().trim();
  276.             return super.prepareStatement(sql, values, conn);
  277.         } catch (Exception e) {
  278.             e.printStackTrace();
  279.             return null;
  280.         }
  281.     }
  282.     protected PreparedStatement getInsertStatement(JDBCDataConnection conn, DataRow row) throws Exception {
  283.         if (tableName == null) {
  284.             //this TableCommand has not been configured, throw an exception
  285.             throw new Exception("TableCommand not configured with a table name");
  286.         }
  287.         try {
  288.             Map<String,Object> values = new HashMap<String,Object>();
  289.             StringBuilder buffer = new StringBuilder();
  290.             buffer.append("insert into ");
  291.             buffer.append(tableName);
  292.             buffer.append("(");
  293.             for (DataColumn col : row.getTable().getColumns()) {
  294.                 buffer.append(col.getName());
  295.                 buffer.append(", ");
  296.             }
  297.             buffer.replace(buffer.length()-2, buffer.length(), ")");
  298.             buffer.append(" values(");
  299.             for (DataColumn col : row.getTable().getColumns()) {
  300.                 buffer.append(":" + col.getName() + ", ");
  301.                 values.put(col.getName(), row.getValue(col));
  302.             }
  303.             buffer.replace(buffer.length()-2, buffer.length(), ")");
  304.             String sql = buffer.toString().trim();
  305.             return super.prepareStatement(sql, values, conn);
  306.         } catch (Exception e) {
  307.             e.printStackTrace();
  308.             return null;
  309.         }
  310.     }
  311.     protected PreparedStatement getDeleteStatement(JDBCDataConnection conn, DataRow row) throws Exception {
  312.         if (tableName == null) {
  313.             //this TableCommand has not been configured, throw an exception
  314.             throw new Exception("TableCommand not configured with a table name");
  315.         }
  316.         try {
  317.             Map<String,Object> values = new HashMap<String,Object>();
  318.             StringBuilder buffer = new StringBuilder();
  319.             buffer.append("delete from ");
  320.             buffer.append(tableName);
  321.             buffer.append(" where ");
  322.             int keyColCount = 0;
  323.             List<DataColumn> columns = row.getTable().getColumns();
  324.             for (int i=0; i<columns.size(); i++) {
  325.                 DataColumn col = columns.get(i);
  326.                 if (col.isKeyColumn()) {
  327.                     buffer.append(col.getName());
  328.                     buffer.append(" = :orig_" + col.getName() + " and ");
  329.                     values.put("orig_" + col.getName(), row.getOriginalValue(col));
  330.                     keyColCount++;
  331.                 }
  332.             }
  333.             if (keyColCount == 0) {
  334.                 System.err.println("WARNING!!! No key columns were specified, the entire table '" + tableName + "' will be deleted!!");
  335.                 //remove the where clause
  336.                 buffer.delete(buffer.length() - 7, buffer.length());
  337.             } else {
  338.                 buffer.delete(buffer.length() - 4, buffer.length());
  339.             }
  340.             
  341.             String sql = buffer.toString().trim();
  342.             return super.prepareStatement(sql, values, conn);
  343.         } catch (Exception e) {
  344.             e.printStackTrace();
  345.             return null;
  346.         }
  347.     }
  348. }