【问题标题】:Database per-user connection for spring hibernate春季休眠的数据库每用户连接
【发布时间】:2016-07-09 17:11:19
【问题描述】:

我正在开发一个 Spring JPA/Hibernate 项目,该项目必须使用数据库用户的连接来实现持久性。

事实上,每个用户都有自己的 Oracle 数据库连接,我必须在应用程序中使用它才能知道谁访问和写入我的数据库。

如何在 Hibernate 中使用不同的数据库连接,而不是使用单个应用程序连接(在 applicationContext 数据源中)?

【问题讨论】:

标签: java spring hibernate jpa


【解决方案1】:

阅读AbstractRoutingDataSource 和我的老问题 AbstractRoutingDataSource change map in runtime
会话监听器:

public class SessionListener implements HttpSessionListener {
    @Autowired
    DataSourceMap dataSourceMap;
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("tworzenie sesji");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId());
        dataSourceMap.removeSource(httpSessionEvent.getSession().getId());
    }
}

路由:

@Component
public class CustomRoutingDataSource extends AbstractRoutingDataSource{
    @Autowired
    DataSourceMap dataSources;
    @Override
    protected Object determineCurrentLookupKey() {
        //setDataSources(dataSources);
        afterPropertiesSet();
        System.out.println("test");
        if( SecurityContextHolder.getContext().getAuthentication()!=null) {
            HttpServletRequest request = ((ServletRequestAttributes)
                    RequestContextHolder.getRequestAttributes()).getRequest();
            return request.getSession().getId();
        }

        return "auth";
    }
    @Autowired
    public void setDataSources(DataSourceMap dataSources) {
        System.out.println("data adding");
        setTargetDataSources(dataSources.getDataSourceMap());
    }

}

地图:

@Component
@Scope(value = "singleton")
public class DataSourceMap {
    private Map<Object,Object> dataSourceMap;
    public DataSourceMap()
    {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("org.h2.Driver");
        dataSourceBuilder.url("jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
        dataSourceBuilder.username("sa");
        dataSourceBuilder.password("");
        dataSourceMap=new HashMap<Object,Object>();
        dataSourceMap.put("auth",dataSourceBuilder.build());
    }
    public void addDataSource(String session,DataSource dataSource)
    {
        this.dataSourceMap.put(session,dataSource);
    }
    public Map<Object,Object> getDataSourceMap()
    {
        return dataSourceMap;
    }
    public void removeSource(String session)
    {
        dataSourceMap.remove(session);
    }
}

【讨论】:

  • 谢谢,我已经阅读了这篇文章,但我有一些问题要让它工作。你有帮助我的代码/项目示例吗?谢谢。
  • 感谢@seti,它有效!但是我和你有同样的问题,会话关闭时我无法关闭数据源池。我使用 sessionDestroyed 方法删除了 dataSourceMap 中的数据源,但数据库中的连接仍然处于活动状态。
  • 我添加了 10 个月前的旧代码。您将用户数据库存储在数据库中还是现在所有数据库都在运行时?
  • 有效!我只是使用OracleDataSource 而不是dataSourceBuilder,因为连接池有一些问题。现在好了。谢谢,我应该为你救我的所有时间买一杯饮料;)
  • 我不能,因为我没有足够的“声誉”......我认为将数据源与 sessionregistery 映射比 http 请求 sessionId 更好
猜你喜欢
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 2016-12-14
  • 2012-12-05
相关资源
最近更新 更多