处理动态数据库连接

时间:2016-11-03 07:33:35

标签: java hibernate jdbc spring-jdbc

我的应用程序要求是动态创建数据库连接。数据库连接详细信息在编译时是未知的,仅在运行时提供给应用程序。处理一个请求只需要一个连接,连接范围仅限于请求执行周期。相同的用户可能会也可能不会使用数据库连接详细信息发布新请求。我们可以有数百个这样的用户,因此如果假设所有用户同时发布请求,我的应用程序将不得不创建数百个这样的数据库连接。

根据这种情况,我有以下问题/需要澄清 -

  1. 连接池在此处不起作用,因为数据库连接是     动态?
  2. 在这种情况下,创建数据库连接的最佳方法是什么?纯JDBC连接在这里最好?
  3. 为每个请求创建hibernate会话工厂,只是为了创建单个连接会导致开销?或者我们可以这样做吗?
  4. 处理这种情况的其他可能的好方法是什么?
  5. 编辑: 我的应用程序是更大的Web应用程序的一个组件。这个更大的Web应用程序在云上有自己的存储。任何用户都可以在此存储上创建沙箱。因此,在发出数据加载请求时,用户必须传递凭据。

    我是新来的冬眠和春天。请帮我决定最好的架构。

1 个答案:

答案 0 :(得分:0)

I think you might find the Open Session in View模式对您的用例感兴趣的内容。您只需要压缩private SessionFactory sf;字段并在每次调用时构建一个新字段。

或者如果你有一个大堆并且很有可能同一个用户会多次调用,你可以实现某种静态HashMap,将给定用户与给定的SessionFactory相关联,并在已经存在的情况下重用它。

没有关于你的问题:

  1. 除非您自己实施,否则无法实现Connexion Pooling。但在考虑之前,问问自己同一个用户是否有可能同时需要多个连接。
  2. 我认为我建议的解决方案是最差的,只要您需要hibernate支持来管理您的实体
  3. 它会导致开销,并且除了在框架中深入攻击可能存在不良副作用之外没有任何办法。例如,您可以想象使用ThreadLocal为每个线程(从tomcat管理的池)分配SessionFactory,然后在每次调用时,设置对应于用户的数据源,请参阅下面的代码
  4. 您必须先提供有关您的申请及其内部的更多详细信息,然后才能(或许)就此提出建议。
  5. 以下是我在3中谈到的代码。请记住这是糟糕的设计。我也采取了一些快捷方式,以便迅速理解这一伎俩。不知道它是否真的有用,但你可以尝试一下

    public class HibernateSessionRequestFilter implements Filter {
    
        private static Logger log = LoggerFactory.getLogger(HibernateSessionRequestFilter.class);
        private static ThreadLocal<LocalSessionFactoryBean> lsfbth = new ThreadLocal<LocalSessionFactoryBean>();
        private static final Map<Object, DataSource> datasourceMap = new HashMap<>();
    
        public void init(FilterConfig filterConfig) throws ServletException {
            log.debug("Initializing filter...");
            LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
            lsfb.setHibernateProperties(null); // TODO: add correct values
            lsfbth.set(lsfb);
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
                ServletException {
    
            LocalSessionFactoryBean lsfb = lsfbth.get();
            String credentials = null; //TODO: get user login from request
            DataSource dataSource = datasourceMap.get(credentials);
            if( dataSource==null){
                // TODO: build datasource here
                datasourceMap.put(credentials, dataSource);
            }
            lsfb.setDataSource(dataSource);
            SessionFactory sf = lsfb.getObject();