2015-09-25 65 views
0

我有一个StoredProcedure这是初始化编译。春天 - 您可以在初始化后重新编译StoredProcedure吗?

有时候逻辑要求我使用不同的存储过程。

我试过了,并且未能重置存储过程的名称。数据仍然使用原始存储过程进行检索。

有没有办法做到这一点?

这里是表示类初始化的简化版本,并试图以不同的存储过程的名称重新编译:

import org.springframework.jdbc.object.StoredProcedure; 

public class MyDAOImpl extends StoredProcedure implements MyDAO { 

    @Autowired 
    public MyDAOImpl(DataSource dataSource, String originalSPName) { 
     super(dataSource, originalSPName); // invokes StoredProcedure constructor 
     compile(); 
    } 

    public List<String> useOtherStoredProcedure(){ 
     super.setSql("otherSPName"); 
     compile(); 

     // Error: Data is still retrieved with original StoredProcedure name 
     Map<String, Object> data = this.executeSP(); 
    } 
} 
+0

为什么不创建两个'StoredProcedure'实现? – Gedrox

+0

@Gedrox我正在朝那个方向走,但宁可不走 - 长篇故事 –

+0

@Gedrox大量的共享代码和客户端代码需要能够在不改变DAO的情况下调用任一过程。这是否意味着我需要创建一个抽象类的两个实现......? (我对Java很陌生) –

回答

0

不是org.springframework.jdbc.object.StoredProcedure请使用有机.springframework.jdbc.core.simple.SimpleJdbcCall。 SimpleJdbcCall的优点是可以动态地指定模式,包和存储过程名称。请在下面找到相应的代码: -

@Autowired 
private JdbcTemplate jdbcTemplate; 

public Date getSPData() { 
SimpleJdbcCall spCall = new SimpleJdbcCall(jdbcTemplate).withSchemaName("schema") 
          .withCatalogName("catalog") 
          .withProcedureName("proc") 
          .withoutProcedureColumnMetaDataAccess() 
          .useInParameterNames("ref_id") 
          .declareParameters(
           new SqlParameter("ref_id", Types.NUMERIC), 
           new SqlOutParameter("dt", Types.DATE)); 
SqlParameterSource in = new MapSqlParameterSource() 
           .addValue("ref_id", 12345); 
Map<String, Object> out = spCall.execute(in); 
Date date = (Date) out.get("dt"); 
return date; 
} 
0

我相信这可能是你想要什么:

public class MyDAOAdapter implements MyDAO { 
    private volatile MyDAO currentDao; 
    private final MyDAO myDAOImpl1; 
    private final MyDAO myDAOImpl2; 

    @Autowired 
    public MyDAOImpl(@Qualifier("myDAOImpl1") MyDAO myDAOImpl1, @Qualifier("myDAOImpl2") MyDAO myDAOImpl2) { 
     this.myDAOImpl1 = myDAOImpl1; 
     this.myDAOImpl2 = myDAOImpl2; 
     currentDao = myDAOImpl1; 
    } 

    public void switchToFirstDao() { 
     currentDao = myDAOImpl2; 
    } 

    public void switchToSecondDao() { 
     currentDao = myDAOImpl2; 
    } 

    // do you really need this? 
    public List<String> useOtherStoredProcedure(){ 
     return myDAOImpl2.executeSP(); 
    } 

    // Delegate all the methods to current DAO selected 
    public List<String> executeSP(){ 
     return currentDao.executeSP(); 
    } 

    // implement all other methods by delegating calls to currentDao 
} 

这应该由所有的代码自动装配和两个StoredProcedure实现之间的切换将被隐藏在这个适配器内。仍然我不明白,如果你希望这个开关对所有代码都是全局的,或者只是在某些情况下。

0

我为自己的情况找到的解决方案是在SQL Studio上实现第三个存储过程,该过程充当常见访问者,并根据参数将查询路由到正确的存储过程。

CREATE PROCEDURE [dbo].[Router_SP] 
    @spNumber as INTEGER   
AS 
BEGIN 
    IF(@spNumber = 1) EXECUTE originalSPName 
    ELSE IF (@spNumber = 2) EXECUTE otherSPName 
    ELSE RETURN 'Unrecognised stored procedure' 
END 

让我们暂时解决这个问题,看看是否有更好的解决方案。