如何在Spring中访问数据源?

时间:2009-06-05 23:43:33

标签: java spring

我看了this post,但我不明白如何使用ThreadLocalDataSourceLookupAbstractRoutingDataSource访问请求。我阅读了每篇文章,但它仍然无效。

如何访问我的请求的dataSource参数并动态创建与他们的连接?

2 个答案:

答案 0 :(得分:1)

我认为这就像你联系到的答案一样:

警告:这些都没有编译过。这些都没有经过测试。

每个请求运行一次CurrentRequestFilter。它负责将当前请求存储在稍后将使用的ThreadLocal中。

public class CurrentRequestFilter extends OncePerRequestFilter {

    private ThreadLocal<HttpServletRequest> currentRequest;

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
        currentRequest.set(request);
        filterChain.doFilter(request, response);
    }

    public ThreadLocal<HttpServletRequest> getCurrentRequest() {
        return currentRequest;
    }

    public void setCurrentRequest(ThreadLocal<HttpServletRequest> currentRequest) {
        this.currentRequest = currentRequest;
    }

}

CurrentRequestDataSource可以访问与ThreadLocal相同的CurrentRequestFilter

public class CurrentRequestDataSource extends AbstractRoutingDataSource {

    private ThreadLocal<HttpServletRequest> currentRequest;

    @Override
    protected DataSource determineTargetDataSource() {
        HttpServletRequest request = currentRequest.get();

        String url = ...;
        String username = ...;
        String password = ...;
        DataSource dataSource = ...;

        return dataSource;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return null;
    }

    public ThreadLocal<HttpServletRequest> getCurrentRequest() {
        return currentRequest;
    }

    public void setCurrentRequest(ThreadLocal<HttpServletRequest> currentRequest) {
        this.currentRequest = currentRequest;
    }
}

然后,您将配置您的bean定义:

<bean id="currentRequest" class="java.lang.ThreadLocal"/>

<bean id="currentRequestFilter" class="CurrentRequestFilter">
    <property name="currentRequest" ref="currentRequest"/>
</bean>

<bean id="dataSource" class="CurrentRequestDataSource">
    <property name="currentRequest" ref="currentRequest"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

然后,您必须确保在CurrentRequestFilter文件中注册了web.xml

<filter>
    <filter-name>Current Request Filter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>currentRequestFilter</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>Current Request Filter</filter-name>
    <servlet-name>Name_Of_Your_Servlet</servlet-name>
</filter-mapping>

同样,这些都没有经过测试,但希望它可以提供一些指导。

答案 1 :(得分:0)

我不确定您的意思是什么,或者请求是什么。你想写一个网络应用程序吗?这是一个HttpRequest吗?您是否根据请求确定了所需的数据源?

根据这些问题的答案,您可能不需要动态访问数据源。

如果您有多个数据源,每个数据源都提供不同类型的请求,我建议将数据源注入服务对象,这些对象会注入到为特定URL选择的Web控制器中。您将能够以这种方式改变数据源,并且没有什么比Web层中的URL映射更有趣。

在不了解您的用例的情况下,我猜你已经过度复杂了,因为你是Spring的新手并且还不知道如何正确使用它。没有任何侮辱,只是猜测。

更新:

“我无法改变它” - 在假设之前,你至少应该与客户讨论它。这是一个坏主意。加密参数不会保存您。

您最好创建一个工厂,Controller可以使用它来实例化注入了您需要的所有数据源的工厂。将数据源存储在地图中,只需来回传递一个密钥即可获取数据源。 Controller已经可以访问请求;保护用户不必知道有关数据库的所有细节;你使查找成为一个简单的密钥(我仍然不喜欢)。

如果看起来太难了,你可能不应该这样做。有更简单的方法。反思它。