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

📄 jdbcdatasetschemareader.java

📁 ADO.NET在Java中的使用 ADO.NET最大的特性在于对断开数据库连接方式的全方位支持
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * $Id: JDBCDataSetSchemaReader.java,v 1.1.2.2 2006/01/21 19:49:45 david_hall Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jdesktop.databuffer.io.schema;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jdesktop.databuffer.DataColumn;
import org.jdesktop.databuffer.DataRelation;
import org.jdesktop.databuffer.DataSet;
import org.jdesktop.databuffer.DataTable;
import org.jdesktop.databuffer.provider.sql.JDBCDataConnection;
import org.jdesktop.databuffer.provider.sql.SQLDataProvider;


/**
 * An <CODE>JDBCDataSetSchemaReader</CODE> instantiates a {@link org.jdesktop.databuffer.DataSet} from
 * a schema stored in an XML file; the schema is read from the JDBC metadata classes (see
 * {@link java.sql.DatabaseMetaData} and {@link java.sql.ResultSetMetaData}), and the accuracy
 * of the schema depends on the quality of the JDBC driver used.
 * <P>Each instance of <CODE>JDBCDataSetSchemaReader</CODE> works against a single JDBCDataConnection
 * connected to through a JDBC driver to a JDBC datasource (presumably a relational database).
 * Once instantiated against that JDBCConnection, the reader
 * methods (e.g. {@link #readDataSet()}) may be used to load the <CODE>DataSet</CODE>.
 * <CODE>DataSetSchemaReader</CODE> classes do not load data, only the <CODE>DataSet</CODE> schema.
 * Typical usage:
 *
 * <CODE>
 * JDBCDataConnection jdbcConn =  new JDBCDataConnection("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:testDB", "sa", "");
 * JDBCDataSetSchemaReader reader = new JDBCDataSetSchemaReader(jdbcConn);
 * DataSet dataSet = reader.readDataSet();
 * </CODE>
 *
 * <P>You can also use the one-line methods in DataSetUtility, such as 
 * {@link org.jdesktop.databuffer.util.DataSetUtility#readDataSetFromJDBC(JDBCDataConnection)}.
 *
 * @author Adam Barclay
 * @author Patrick Wright
 */
public class JDBCDataSetSchemaReader implements DataSetSchemaReader {
    /** The JDBCDataConnection from which we read schema metadata. */
    private JDBCDataConnection jdbcConn;
    
    /** The catalog name from which we read schema data, if supplied, may be null. */
    private String catalog;
    
    /** The schema name from which we read schema data, if supplied, may be null. */
    private String schema;
    
    /**
     * Instantiates a new <CODE>JDBCDataSetSchemaReader</CODE> for a JDBCDataConnection to a JDBC data source,
     * presumably a relational database, using the default catalog and schema as understood by the JDBC driver (e.g. null).
     * The data connection cannot be changed once the reader is instantiated. The connection
     * will be opened as necessary to read the metadata, and returned to its orignal connection state after reading. As the JDBC
     * connections are not necessarily thread-safe, calling classes should synchronize around the schema loading process.
     * See class documentation for more details.
     *
     * @param jdbcConn A {@link org.jdesktop.databuffer.provider.sql.JDBCDataConnection}.
     */
    public JDBCDataSetSchemaReader(JDBCDataConnection jdbcConn) {
        this(jdbcConn, null, null);
    }
    
    /**
     * Instantiates a new <CODE>JDBCDataSetSchemaReader</CODE>, for a JDBCDataConnection to a JDBC data source,
     * presumably a relational database, for a given catalog and schema in that database.
     * The data connection cannot be changed once the reader is instantiated. The connection
     * will be opened as necessary to read the metadata, and returned to its orignal connection state after reading. As the JDBC
     * connections are not necessarily thread-safe, calling classes should synchronize around the schema loading process.
     * See class documentation for more details.
     *
     * @param catalog Name of the catalog to read the schema from. The meaning of "catalog" is RDBMS-dependent;
     * consult the documentation for your data source and JDBC driver.
     *
     * @param schema Name of the schema to read the DataSet schema from. The meaning of "schema" is RDBMS-dependent;
     * consult the documentation for your data source and JDBC driver.
     *
     * @param jdbcConn A {@link org.jdesktop.databuffer.provider.sql.JDBCDataConnection}.
     */
    public JDBCDataSetSchemaReader(JDBCDataConnection jdbcConn, String catalog, String schema)  {
        this.jdbcConn = jdbcConn;
        this.catalog = catalog;
        this.schema = schema;
    }
    
    
    /**
     * Instantiates a new {@link org.jdesktop.databuffer.DataSet} from the <CODE>JDBCDataConnection</CODE>
     * specified in the constructor. If the schema contains multiple <CODE>DataTables</CODE>
     * or <CODE>DataRelations</CODE>, all of them are loaded
     * from the schema into the new <CODE>DataSet</CODE>. Relations are read for a table using the
     * {@link java.sql.DatabaseMetaData#getImportedKeys(String catalog, String schema, String tableName)}. For a
     * relational database, this would mean a foreign key constraint on the table. If such metadata does not exist
     * for table relations, you will need to create them yourself after instantiating the <CODE>DataSet</CODE>.
     * This method is probably not thread-safe for multiple threads accessing the same <CODE>JDBCDataConnection</CODE>
     * and underlying <CODE>java.sql.Connection</CODE>.
     *
     * @return A new <CODE>DataSet</CODE> instantiated from the <CODE>JDBCDataConnection</CODE>
     * specified for the implementing class, including all tables and relations in the schema.
     *
     * @throws org.jdesktop.databuffer.io.schema.SchemaReaderException If an error occurred while loading the schema.
     */
    public DataSet readDataSet() throws SchemaReaderException {
        boolean connectState = jdbcConn.isConnected();
        if ( !connectState ) jdbcConn.setConnected(true);
        
        DataSet dataSet = null;
        try {
            Connection conn = jdbcConn.getConnection();
            DatabaseMetaData dbMetaData = conn.getMetaData();
            
            String[] typeArray = {"TABLE"};
            ResultSet tableResultSet = dbMetaData.getTables(null, null, "%", typeArray);
            List<String> tables = DataSetIOUtility.extractColumn(tableResultSet, "TABLE_NAME");
            tableResultSet.close();
            String[] array = (String[])tables.toArray(new String[tables.size()]);
            
            dataSet = readDataSet(array);
        } catch (SchemaReaderException e) {
            throw e;
        } catch (Exception e) {
            throw new SchemaReaderException("Could not read schemas to create DataSet", e);
        } finally {
            jdbcConn.setConnected(connectState);
        }
        return dataSet;
    }
    
    /**
     * Instantiates a new {@link org.jdesktop.databuffer.DataSet} from the <CODE>JDBCDataConnection</CODE>
     * specified in the constructor, for the tables and columns given in the <CODE>tableNames</CODE> parameter.
     * from the schema into the new <CODE>DataSet</CODE>. Relations are read for a table using the
     * {@link java.sql.DatabaseMetaData#getImportedKeys(String catalog, String schema, String tableName)}. For a
     * relational database, this would mean a foreign key constraint on the table. If such metadata does not exist
     * for table relations, you will need to create them yourself after instantiating the <CODE>DataSet</CODE>.
     * This method is probably not thread-safe for multiple threads accessing the same <CODE>JDBCDataConnection</CODE>
     * and underlying <CODE>java.sql.Connection</CODE>.
     *
     * @param tableNames One or more table names to load from the schema. Each name can be either a table, or a
     * table and column, dot-separated. If no columns are specified, all columns in the table are
     * read from the schema; if columns are listed, only those columns are loaded. <CODE>DataRelations</CODE>
     * for those tables and columns loaded from the schema are also instantiated automatically through
     * {@link #addRelations(org.jdesktop.databuffer.DataSet, String...)}.
     *
     * @return A new <CODE>DataSet</CODE> instantiated from the <CODE>JDBCDataConnection</CODE>
     * specified for the implementing class, including only the tables and columns listed in the
     * <CODE>tableNames</CODE> parameter.
     *
     * @throws org.jdesktop.databuffer.io.schema.SchemaReaderException If an error occurred while loading the schema.
     */
    public DataSet readDataSet(String... tableNames) throws SchemaReaderException{
        boolean connectState = jdbcConn.isConnected();
        if ( !connectState ) jdbcConn.setConnected(true);
        
        DataSet dataSet = new DataSet();
        try {
            addTables(dataSet, tableNames);
            
            addRelations(dataSet, tableNames);
        } catch (SchemaReaderException e) {
            throw e;
        } catch (Exception e) {
            throw new SchemaReaderException("Could not read schemas to create DataTables", e);
        } finally {
            jdbcConn.setConnected(connectState);
        }
        return dataSet;
    }
    
    
    /**
     * Appends one or more {@link org.jdesktop.databuffer.DataTable} to a {@link org.jdesktop.databuffer.DataSet}
     * from the schema represented by this reader. If the table, by name, is found in the <CODE>DataSet</CODE>,
     * the table is skipped; if you want to re-add a table (for example, to pick up changes in table structure),
     * drop the table from the <CODE>DataSet</CODE> before calling this method.
     *
     * @return A <CODE>List</CODE> of the table names that were actually found. You can check this to
     * verify that all tables requested were loaded.
     *
     * @param dataSet The <CODE>DataSet</CODE> to which to add the tables.
     *
     * @param tableNames One or more table names to load from the schema and add to the <CODE>DataSet</CODE>.
     * Each name can be either a table, or a table and column, dot-separated.
     * If no columns are specified, all columns in the table are read from the schema;
     * if columns are listed, only those columns are loaded. <CODE>DataRelations</CODE>
     * for those tables and columns are not loaded from the schema; to that end, use
     * {@link #addRelations(DataSet, String...)}.
     *
     * @throws org.jdesktop.databuffer.io.schema.SchemaReaderException If an error occurred while loading the schema.
     */
    public List<String> addTables(DataSet dataSet, String... tableNames) throws SchemaReaderException {
        List<String> loadedTables = new ArrayList<String>(tableNames.length);
        boolean connectState = jdbcConn.isConnected();
        if ( !connectState ) jdbcConn.setConnected(true);
        
        try {
            Connection conn = jdbcConn.getConnection();
            DatabaseMetaData dbMetaData = conn.getMetaData();
            
            // Used to store the list of tables that are to be retrieved, along
            // with the list of columns (or explictly null if all columns should
            // be included)
            Map<String, Set<String>> tables = new HashMap<String, Set<String>>(5);
            
            for (String name : tableNames) {

⌨️ 快捷键说明

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