Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在运行时创建多个架构连接?_Java_Oracle_Jdbc_Ibatis_Jdbc Odbc - Fatal编程技术网

Java 如何在运行时创建多个架构连接?

Java 如何在运行时创建多个架构连接?,java,oracle,jdbc,ibatis,jdbc-odbc,Java,Oracle,Jdbc,Ibatis,Jdbc Odbc,我有一个项目名称下拉列表,并根据所选的值生成一个模式下拉列表 生成架构列表后,会有一个“选择文件”选项,其中会选择一个脚本名,该脚本名将在多个架构上运行 项目列表值和架构列表值都存储在数据库中。数据库中还有另一个存储架构凭据的表 我想知道如何在这些多个模式上创建连接,以及如何在从该模式下拉列表中选择的多个模式中运行脚本 我已经使用iBatis框架使用scriptrunner方法在一个模式中执行了代码 表1:ProjectName PROJECT_PK, PROJECT_CODE, PROJECT

我有一个项目名称下拉列表,并根据所选的值生成一个模式下拉列表

生成架构列表后,会有一个“选择文件”选项,其中会选择一个脚本名,该脚本名将在多个架构上运行

项目列表值和架构列表值都存储在数据库中。数据库中还有另一个存储架构凭据的表

我想知道如何在这些多个模式上创建连接,以及如何在从该模式下拉列表中选择的多个模式中运行脚本

我已经使用iBatis框架使用
scriptrunner
方法在一个模式中执行了代码

表1:
ProjectName

PROJECT_PK,
PROJECT_CODE,
PROJECT_NAME
COMPONENT_PK,
COMPONENT_CODE,
COMPONENT_NAME,
PROJECT_PK
表2:
ComponentName

PROJECT_PK,
PROJECT_CODE,
PROJECT_NAME
COMPONENT_PK,
COMPONENT_CODE,
COMPONENT_NAME,
PROJECT_PK
表3:
SchemaName
(此表包含其他架构的凭据)

表4:
项目详细信息

PROJECT_DETAIL_PK,
COMPONENT_PK,
SCHEMA_PK
表5:
组件详细信息

COMPONENT_DETAILS_PK,
PROJECT_PK,
SCHEMA_PK
我附加的情景图像


我建议您创建一个“超级模式”,在每个其他模式上都有适当的授权,并为这个“超级模式”创建您的JDBC连接。这将使您需要对sql脚本进行一些修改—您需要使用一些标记来编写它,以便轻松地替换模式,例如

ALTER TABLE ${SCHEMA_MARKER}.INVOICES ADD CLIENT_ADRRESS Varchar2(35);
您的java代码将用它代替您所针对的模式。通过一些想象,您可以扩展这个想法,在所有模式上执行批量DDL脚本

顺便说一下,我从你的问题中了解到,你有许多具有相同结构的模式。我曾经被迫与这样一个遗留结构一起工作,因此我知道在公司结构中有很多动力;尽管如此,我还是建议你重新设计这样的系统。例如,在超级模式上创建物化视图时,复制模式结构,但在每个表主键中都有一个新字段(这个新字段将填补空白,使任何人都可以首先在许多模式中分离数据)


这肯定会使您的查询缓存受到的影响小得多,并且会使需要处理“分布式”数据的任何新软件的开发变得更容易。

在Oracle中,模式基本上就是用户。因此,要在模式
SX
中创建表
FOO
,只需以用户
SX
身份登录并执行
create table FOO(…)
(不指定模式)。Oracle中的user==模式约定将确保这一点有效

要以用户身份登录
SX
,请抓住您的
数据源
,并使用而不是默认的
getConnection()

另一种方法是在脚本中添加占位符,首先处理该占位符以生成有效的SQL。请参见Jorge_B的答案以获取示例


最后,您可以使用
ALTER SESSION
(请参阅)更改默认模式。这种方法的问题是,当使用带有
数据源的web容器时,必须在关闭连接之前还原架构-在这种情况下,连接永远不会真正关闭,因此,下一段请求连接的代码将得到一个意外的默认模式->难以找到的错误。

下面是DAO类,用于在运行时在同一数据库上创建多个模式连接

我们需要在运行时输入模式名,并在某个servlet中调用它

模式详细信息(即用户名、密码、主机Id、端口Id和SID)将存储在数据库表中,通过这些表将创建连接

创建的连接存储在列表中,可在以后使用

此处的凭证DTO是映射到数据库中的数据库表的对象,然后

Connection conn=DBUtil.getConnection(constants.DB_DS_NAME);
        Statement stmt=null;
        stmt=conn.createStatement();
        ResultSet rs= null;
        Connection [] con=new Connection[schemaname.length];
        int i,j;
        String [] url=new String[schemaname.length];
        String [] username=new String[schemaname.length];
        String [] password=new String[schemaname.length];
        List<CredentialDTO> creDTOlist=new ArrayList<CredentialDTO>();
        String query1="insert into dba_project_master VALUES(9,'abc','abc','abc','abc',40)";
        String query2="CREATE TABLE EMP(EMPNO NUMBER(4,0) NOT NULL ENABLE,ENAME VARCHAR2(10 BYTE),JOB VARCHAR2(9 BYTE), SAL NUMBER(7,2),DEPTNO NUMBER(2,0))";

        try
        {
            for(i=0;i<schemaname.length;i++){
                String query=" select * from dba_schema_details where schema_name="+DBUtil.enquoteString(schemaname[i]);
                rs=stmt.executeQuery(query);

                while(rs.next()){
                    CredentialDTO creDTO=new CredentialDTO();
                    creDTO.setSCHEMA_PK(rs.getString("SCHEMA_PK"));
                    creDTO.setSCHEMA_NAME(rs.getString("SCHEMA_NAME"));
                    creDTO.setPASSWORD(rs.getString("PASSWORD"));
                    creDTO.setORACLE_SID(rs.getString("ORACLE_SID"));
                    creDTO.setHOST_NAME(rs.getString("HOST_NAME"));
                    creDTO.setPORT_ID(rs.getString("PORT_ID"));
                    creDTOlist.add(creDTO);
                }
            }
                System.out.println("creDTOlist size:"+creDTOlist.size());
                //create URL for the schema name
                int m=creDTOlist.size();
                Iterator<CredentialDTO> LItr= creDTOlist.iterator();
                String [] username1=new String[m];
                String [] password1=new String[m];
                i=0;
                while(LItr.hasNext()){

                    System.out.println("iteration "+i); 
                    CredentialDTO temp = LItr.next();
                    String URL="jdbc:oracle:thin:@"+temp.getHOST_NAME()+":"+temp.getPORT_ID()+":"+temp.getORACLE_SID();
                    System.out.println("URL:"+URL);
                    username1[i]=temp.getSCHEMA_NAME();
                    System.out.println("iteartion "+i+" username="+username1[i]);
                    password1[i]=temp.getPASSWORD();
                    System.out.println("iteartion "+i+" password="+password1[i]);
                    Class.forName("oracle.jdbc.OracleDriver");
                    con[i]=DriverManager.getConnection(URL, username1[i], password1[i]);
                    System.out.println("Connection Name:" +con[i]);
                    Statement st1=con[i].createStatement();
                    con[i].setAutoCommit(false);
                    st1.addBatch(query1);
                    st1.addBatch(query2);
                    int [] update=st1.executeBatch();
                    i++;
                }
            }
            catch(Exception ex){
                    ex.printStackTrace();
            }finally
        {
            if (conn != null) try{conn.close();} catch(SQLException ignore) {}
            if (stmt!= null) try{stmt.close();} catch(SQLException ignore) {}
            if (rs != null) try{rs.close();} catch(SQLException ignore) {}
        }
        return creDTOlist;

    }

}
Connection conn=DBUtil.getConnection(constants.DB\u DS\u NAME);
语句stmt=null;
stmt=conn.createStatement();
结果集rs=null;
Connection[]con=新连接[schemaname.length];
int i,j;
String[]url=新字符串[schemaname.length];
String[]用户名=新字符串[schemaname.length];
String[]password=新字符串[schemaname.length];
List creDTOlist=new ArrayList();
字符串query1=“插入dba_项目_主值(9,'abc','abc','abc',40)”;
String query2=“创建表EMP(EMPNO编号(4,0)非空启用、ENAME VARCHAR2(10字节)、作业VARCHAR2(9字节)、SAL编号(7,2)、DEPTNO编号(2,0))”;
尝试
{

对于(i=0;i使用DDL作为“下拉列表”的简写是令人困惑的,因为在广泛理解为“数据定义语言”的数据库上下文中,尤其是在这里,您讨论的是模式。(还不清楚针对所选架构运行的SQL脚本是DML还是DDL,尽管这可能不太重要,但给人的印象是它们将是DDL)。很抱歉造成混淆,但我在括号中写道DDL在这里表示dropdownlist。sql脚本可能包含DML、DDL或DCL中的任何一种。存储架构密码似乎不是一个好主意;当您阅读这些密码时,您的连接方式是什么,或者任何人都可以看到它们?始终以对所有架构具有权限的同一用户的身份连接,似乎更安全、更安全更简单;在执行每个脚本之前,您可以这样做?不过,该用户必须具有在不同模式中运行DDL的特权。