Spring - 初始化后你可以重新编译StoredProcedure吗?

时间:2015-09-25 11:22:48

标签: java spring stored-procedures

我有一个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();
    }
}

3 个答案:

答案 0 :(得分:0)

使用 org.springframework.jdbc.core.simple.SimpleJdbcCall 而不是 org.springframework.jdbc.object.StoredProcedure 。 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;
}

答案 1 :(得分: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实现之间的切换将隐藏在此适配器中。我仍然不明白你是否希望这个开关对所有代码都是全局的,或仅在某些情况下。

答案 2 :(得分: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

暂时搁置这个问题,看看是否有更好的解决方案。