基于geotools24.0的创建自动增长主键id字段的方法

基于geotools24.0的创建自动增长主键id字段的方法

原始引入的包中有bug,一直返回fid主键的问题

protected String findPrimaryKeyColumnName(SimpleFeatureType featureType) {
    
    
        String[] suffix = new String[] {
    
    "", "_1", "_2"};
        String[] base = new String[] {
    
    "fid", "id", "gt_id", "ogc_fid"};

        for (String b : base) {
    
    
            //O:
            for (String s : suffix) {
    
    
                String name = b + s;
                for (AttributeDescriptor ad : featureType.getAttributeDescriptors()) {
    
    
                    if (ad.getLocalName().equalsIgnoreCase(name)) {
    
    
                        return name; //continue O;
                    }
                }
                //return name;
            }
        }

        // practically should never get here, but just fall back and fail later
        return "fid";
    }

下面为修改后创建自动增长主键id字段的方法
主要修改两处:
一、findPrimaryKeyColumnName方法的修改
二、createTableSQL方法有主键id字段,不能重复添加字段
修改后代码

//
    private DataStore m_pgDatastore = null;

    public  boolean initPgDatastore(String dbtype, String host, Integer port, String database, String userName, String password) {
    
    
        boolean success =false;
        if(m_pgDatastore==null) {
    
    
                try {
    
    
                    if(m_pgDatastore==null) {
    
    
                        Map<String, Object> params = new HashMap<String, Object>();
                        params.put(PostgisNGDataStoreFactory.DBTYPE.key, "postgis"); //需要连接何种数据库,postgis or mysql
                        params.put(PostgisNGDataStoreFactory.HOST.key, host);//ip地址
                        params.put(PostgisNGDataStoreFactory.PORT.key, port);//端口号
                        params.put(PostgisNGDataStoreFactory.DATABASE.key, database);//需要连接的数据库
                        params.put(PostgisNGDataStoreFactory.SCHEMA.key, "public");//架构
                        params.put(PostgisNGDataStoreFactory.USER.key, userName);//需要连接数据库的名称
                        params.put(PostgisNGDataStoreFactory.PASSWD.key, password);//数据库的密码
                        //获取存储空间
                        m_pgDatastore= DataStoreFinder.getDataStore(params);
                    }
                    success = true;
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                    this.logger.error(e.getMessage());
                } finally {
    
    
                }

        }
        return success;
    }

    public  boolean initPgDatastore(DbConfig sdeCfg)
    {
    
    
        return this.initPgDatastore(sdeCfg.getDbType(),sdeCfg.getHost(),sdeCfg.getPort(),sdeCfg.getDatabase(),sdeCfg.getUsername(),sdeCfg.getPassword());
    }

    public JDBCDataStore getJDBCDataStore() {
    
    
       return (JDBCDataStore) this.m_pgDatastore;
    }


    public boolean close()
    {
    
    
        if(m_pgDatastore!=null)
        {
    
    
            m_pgDatastore.dispose();
            m_pgDatastore=null;
        }
        return true;
    }
    //创建表结构
    public void createSchema(final SimpleFeatureType featureType) throws IOException {
    
    
        /*
        if (entry(featureType.getName()) != null) {
            String msg = "Schema '" + featureType.getName() + "' already exists";
            throw new IllegalArgumentException(msg);
        }*/

        // execute the create table statement
        // TODO: create a primary key and a spatial index
        Connection cx = this.createConnection();

        try {
    
    
            String sql = createTableSQL(featureType, cx);
            //LOGGER.log(Level.FINE, "Create schema: {0}", sql);

            Statement st = cx.createStatement();

            try {
    
    
                st.execute(sql);
            } finally {
    
    
                this.closeSafe(st);
            }

            this.getJDBCDataStore().dialect.postCreateTable(this.getJDBCDataStore().getDatabaseSchema(), featureType, cx);
        } catch (Exception e) {
    
    
            String msg = "Error occurred creating table";
            throw (IOException) new IOException(msg).initCause(e);
        } finally {
    
    
            this.closeSafe(cx);
        }
    }

    protected String createTableSQL(SimpleFeatureType featureType,Connection cx) throws Exception {
    
    
        // figure out the names and types of the columns
        String[] columnNames = new String[featureType.getAttributeCount()];
        String[] sqlTypeNames = null;
        Class[] classes = new Class[featureType.getAttributeCount()];

        // figure out which columns can not be null
        boolean[] nillable = new boolean[featureType.getAttributeCount()];

        for (int i = 0; i < featureType.getAttributeCount(); i++) {
    
    
            AttributeDescriptor attributeType = featureType.getDescriptor(i);

            // column name
            columnNames[i] = attributeType.getLocalName();

            // column type
            classes[i] = attributeType.getType().getBinding();

            // can be null?
            nillable[i] = attributeType.getMinOccurs() <= 0 || attributeType.isNillable();

            // eventual options
        }

        sqlTypeNames = getSQLTypeNames(featureType.getAttributeDescriptors(), cx);
        for (int i = 0; i < sqlTypeNames.length; i++) {
    
    
            if (sqlTypeNames[i] == null) {
    
    
                String msg = "Unable to map " + columnNames[i] + "( " + classes[i].getName() + ")";
                throw new RuntimeException(msg);
            }
        }

        return createTableSQL(
                featureType.getTypeName(),
                columnNames,
                sqlTypeNames,
                nillable,
                findPrimaryKeyColumnName(featureType),
                featureType);
    }

    private String createTableSQL(
            String tableName,
            String[] columnNames,
            String[] sqlTypeNames,
            boolean[] nillable,
            String pkeyColumn,
            SimpleFeatureType featureType)
            throws SQLException {
    
    
        // build the create table sql
        StringBuffer sql = new StringBuffer();
        this.getJDBCDataStore().dialect.encodeCreateTable(sql);

        this.getJDBCDataStore().encodeTableName(tableName, sql, null);
        sql.append(" ( ");

        // primary key column
        if (pkeyColumn != null) {
    
    
            this.getJDBCDataStore().dialect.encodePrimaryKey(pkeyColumn, sql);
            sql.append(", ");
        }

        // normal attributes
        for (int i = 0; i < columnNames.length; i++) {
    
    
            if(pkeyColumn!=null && columnNames[i].equals(pkeyColumn)==true)
            {
    
       //跳过主键字段,上面已添加主键字段
                continue;
            }
            // the column name
            this.getJDBCDataStore().dialect.encodeColumnName(null, columnNames[i], sql);
            sql.append(" ");

            // some sql dialects require varchars to have an
            // associated size with them
            int length = -1;
            if (sqlTypeNames[i].toUpperCase().startsWith("VARCHAR")) {
    
    
                if (featureType != null) {
    
    
                    AttributeDescriptor att = featureType.getDescriptor(columnNames[i]);
                    length = this.findVarcharColumnLength(att);
                }
            }

            // only apply a length if one exists (i.e. to applicable varchars)
            if (length == -1) {
    
    
                this.getJDBCDataStore().dialect.encodeColumnType(sqlTypeNames[i], sql);
            } else {
    
    
                this.getJDBCDataStore().dialect.encodeColumnType(sqlTypeNames[i] + "(" + length + ")", sql);
            }

            // nullable
            if (nillable != null && !nillable[i]) {
    
    
                sql.append(" NOT NULL ");
            }

            // delegate to dialect to encode column postamble
            if (featureType != null) {
    
    
                AttributeDescriptor att = featureType.getDescriptor(columnNames[i]);
                this.getJDBCDataStore().dialect.encodePostColumnCreateTable(att, sql);
            }

            // sql.append(sqlTypeNames[i]);
            if (i < (sqlTypeNames.length - 1)) {
    
    
                sql.append(", ");
            }
        }

        sql.append(" ) ");

        // encode anything post create table
        this.getJDBCDataStore().dialect.encodePostCreateTable(tableName, sql);

        return sql.toString();
    }

    private Integer findVarcharColumnLength(AttributeDescriptor att) {
    
    
        for (Filter r : att.getType().getRestrictions()) {
    
    
            if (r instanceof PropertyIsLessThanOrEqualTo) {
    
    
                PropertyIsLessThanOrEqualTo c = (PropertyIsLessThanOrEqualTo) r;
                if (c.getExpression1() instanceof Function
                        && ((Function) c.getExpression1())
                        .getName()
                        .toLowerCase()
                        .endsWith("length")) {
    
    
                    if (c.getExpression2() instanceof Literal) {
    
    
                        Integer length = c.getExpression2().evaluate(null, Integer.class);
                        if (length != null) {
    
    
                            return length;
                        }
                    }
                }
            }
        }

        return this.getJDBCDataStore().dialect.getDefaultVarcharSize();
    }

    private String[] getSQLTypeNames(List<AttributeDescriptor> descriptors, Connection cx)
            throws SQLException {
    
    
        // figure out what the sql types are corresponding to the feature type
        // attributes
        int[] sqlTypes = new int[descriptors.size()];
        String[] sqlTypeNames = new String[sqlTypes.length];

        for (int i = 0; i < descriptors.size(); i++) {
    
    
            AttributeDescriptor ad = descriptors.get(i);
            Class clazz = ad.getType().getBinding();
            Integer sqlType = this.getJDBCDataStore().dialect.getSQLType(ad);

            if (sqlType == null) {
    
    
                sqlType = this.getJDBCDataStore().getMapping(clazz);
            }

            if (sqlType == null) {
    
    
                sqlType = Types.OTHER;
            }

            sqlTypes[i] = sqlType;

            // if this a geometric type, get the name from teh dialect
            // if ( attributeType instanceof GeometryDescriptor ) {
    
    
            if (Geometry.class.isAssignableFrom(clazz)) {
    
    
                String sqlTypeName = this.getJDBCDataStore().dialect.getGeometryTypeName(sqlType);

                if (sqlTypeName != null) {
    
    
                    sqlTypeNames[i] = sqlTypeName;
                }
            }

            // check types previously read from DB
            String sqlTypeDBName = this.getJDBCDataStore().getDBsqlTypesCache().get(sqlType);
            if (sqlTypeDBName != null) {
    
    
                sqlTypeNames[i] = sqlTypeDBName;
            }
        }
        // GEOT-6347 if all sql type names have been found in dialect dont
        // go to database
        boolean allTypesFound = !ArrayUtils.contains(sqlTypeNames, null);
        if (!allTypesFound) {
    
    
            //LOGGER.log(Level.WARNING, "Fetching fields from Database");
            // figure out the type names that correspond to the sql types from
            // the database metadata
            DatabaseMetaData metaData = cx.getMetaData();
            
            ResultSet types = metaData.getTypeInfo();

            try {
    
    
                while (types.next()) {
    
    
                    int sqlType = types.getInt("DATA_TYPE");
                    String sqlTypeName = types.getString("TYPE_NAME");

                    for (int i = 0; i < sqlTypes.length; i++) {
    
    
                        // check if we already have the type name from the dialect
                        if (sqlTypeNames[i] != null) {
    
    
                            continue;
                        }

                        if (sqlType == sqlTypes[i]) {
    
    
                            sqlTypeNames[i] = sqlTypeName;
                            // GEOT-6347
                            // cache the sqlType which required going to database for sql types
                            this.getJDBCDataStore().getDBsqlTypesCache().putIfAbsent(sqlType, sqlTypeName);
                        }
                    }
                }
            } finally {
    
    
                this.getJDBCDataStore().closeSafe(types);
            }
        }

        // apply the overrides specified by the dialect
        Map<Integer, String> overrides = getSqlTypeToSqlTypeNameOverrides();
        for (int i = 0; i < sqlTypes.length; i++) {
    
    
            String override = overrides.get(sqlTypes[i]);
            if (override != null) sqlTypeNames[i] = override;
        }

        return sqlTypeNames;
    }

    protected final Connection createConnection() {
    
    
        try {
    
    
            //LOGGER.fine("CREATE CONNECTION");

            Connection cx = this.getJDBCDataStore().getDataSource().getConnection();

            // isolation level is not set in the datastore, see
            // http://jira.codehaus.org/browse/GEOT-2021

            // call dialect callback to initialize the connection
            this.getJDBCDataStore().dialect.initializeConnection(cx);

            // if there is any lifecycle listener use it
            if (connectionLifecycleListeners.size() > 0) {
    
    
                List<ConnectionLifecycleListener> locals =
                        new ArrayList<ConnectionLifecycleListener>(connectionLifecycleListeners);
                cx = new LifecycleConnection(this.getJDBCDataStore(), cx, locals);
            }
            return cx;
        } catch (SQLException e) {
    
    
            throw new RuntimeException("Unable to obtain connection: " + e.getMessage(), e);
        }
    }
    protected List<ConnectionLifecycleListener> connectionLifecycleListeners =
            new CopyOnWriteArrayList<ConnectionLifecycleListener>();
    /*
     * search feature type looking for suitable unique column for primary key.
     */
    protected String findPrimaryKeyColumnName(SimpleFeatureType featureType) {
    
    
        String[] suffix = new String[] {
    
    "", "_1", "_2"};
        String[] base = new String[] {
    
    "fid", "id", "gt_id", "ogc_fid"};

        for (String b : base) {
    
    
            //O:
            for (String s : suffix) {
    
    
                String name = b + s;
                for (AttributeDescriptor ad : featureType.getAttributeDescriptors()) {
    
    
                    if (ad.getLocalName().equalsIgnoreCase(name)) {
    
    
                        return name; //continue O;
                    }
                }
                //return name;
            }
        }

        // practically should never get here, but just fall back and fail later
        return "fid";
    }

    protected HashMap<Integer, String> sqlTypeToSqlTypeNameOverrides;

    public Map<Integer, String> getSqlTypeToSqlTypeNameOverrides() {
    
    
        if (sqlTypeToSqlTypeNameOverrides == null) {
    
    
            sqlTypeToSqlTypeNameOverrides = new HashMap<Integer, String>();
            ((JDBCDataStore)this.m_pgDatastore).dialect.registerSqlTypeToSqlTypeNameOverrides(sqlTypeToSqlTypeNameOverrides);
        }

        return sqlTypeToSqlTypeNameOverrides;
    }

    public void closeSafe(Statement st) {
    
    
        if (st == null) {
    
    
            return;
        }

        try {
    
    
            st.close();
        } catch (SQLException e) {
    
    
            String msg = "Error occurred closing statement";
            /*
            //LOGGER.warning(msg);

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.log(Level.FINER, msg, e);
            }*/
        }
    }

    /**
     * Utility method for closing a connection.
     *
     * <p>This method closed the connection "safely" in that it never throws an exception. Any
     * exceptions that do occur are logged at {@link Level#FINER}.
     *
     * @param cx The connection to close.
     */
    public void closeSafe(Connection cx) {
    
    
        if (cx == null) {
    
    
            return;
        }

        try {
    
    
            //            System.out.println("Closing connection " + System.identityHashCode(cx));
            cx.close();
            //LOGGER.fine("CLOSE CONNECTION");
        } catch (SQLException e) {
    
    
            String msg = "Error occurred closing connection";
            /*
            LOGGER.warning(msg);

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.log(Level.FINER, msg, e);
            }*/
        }
    }

猜你喜欢

转载自blog.csdn.net/hsg77/article/details/134319357