【问题标题】:can we connect with two DataBase Schemas with spring data jpa using same repository , model我们可以使用相同的存储库,模型连接两个带有 spring data jpa 的数据库模式吗
【发布时间】:2019-11-12 09:38:24
【问题描述】:

我想连接到同一数据库服务器上的两个数据库模式,因为我只想使用一组模型和 JPA 存储库,两个数据源连接到两个不同的模式。但到目前为止我还没有能够找到一种我们可以重用现有模型和存储库的方法,现在我已经创建了两组具有不同模式的模型和存储库。有没有一种方法可以重用模型和存储库?

但到目前为止,我无法找到一种方法来重用现有模型和存储库,目前我已经创建了两组具有不同架构的模型和存储库

注意:

我能够通过两个数据源连接到两个模式,因此不需要多租户支持,唯一的事情是在连接到两个单独的模式时,我正在创建模型(实体)和 JPA 存储库两次,即使表在两种模式,是否都有删除代码重复的方法

【问题讨论】:

  • 例如:我有一个实体类 EMP 来表示表 emp_records,其中包含 id、age、name、salary 和一个扩展 JPA 存储库的存储库。现在我有两个数据库模式 orderManagment 和 new_orderManagment 。两个模式都有名为 emp_records 的表,所以我可以与共享相同实体存储库的两个模式交互并避免创建相同的实体和存储库类。

标签: spring spring-data-jpa spring-data jpa-2.0 jpa-2.1


【解决方案1】:

您似乎需要多租户支持。每个架构的租户

您需要 TenantInterceptor 来解析tenantId,例如来自会话或 JWT 令牌。以及返回所需提供者的 MultiTenantConnectionProvider。

来自Multi-Tenancy Implementation for Spring Boot + Hibernate Projects的一些代码

@Component
public class TenantInterceptor extends HandlerInterceptorAdapter {

    @Autowired  
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.header}")
    private String tokenHeader;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String authToken = request.getHeader(this.tokenHeader);
        String tenantId = jwtTokenUtil.getTenantIdFromToken(authToken);
        TenantContext.setCurrentTenant(tenantId);
        return true;
    }

    @Override
    public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
        TenantContext.clear();
    }
}

@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {

    @Autowired
    private DataSource dataSource;

    @Override
    public Connection getAnyConnection() throws SQLException {
        return dataSource.getConnection();
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        connection.close();
    }

    @Override
    public Connection getConnection(String tenantIdentifie) throws SQLException {
        String tenantIdentifier = TenantContext.getCurrentTenant();
        final Connection connection = getAnyConnection();
        try {
            if (tenantIdentifier != null) {
                connection.createStatement().execute("USE " + tenantIdentifier);
            } else {
                connection.createStatement().execute("USE " + DEFAULT_TENANT_ID);
            }
        }
        catch ( SQLException e ) {
            throw new HibernateException(
                    "Problem setting schema to " + tenantIdentifier,
                    e
            );
        }
        return connection;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        try {
            connection.createStatement().execute( "USE " + DEFAULT_TENANT_ID );
        }
        catch ( SQLException e ) {
            throw new HibernateException(
                   "Problem setting schema to " + tenantIdentifier,
                    e
            );
        }
        connection.close();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean isUnwrappableAs(Class unwrapType) {
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> unwrapType) {
        return null;
    }

    @Override
    public boolean supportsAggressiveRelease() {
        return true;
    }
}

【讨论】:

  • 感谢您的回复,但实际上我能够通过两个数据源连接到两个模式,因此不需要多租户支持唯一的事情是在连接到两个单独的模式时我正在创建模型(实体) 和 JPA 存储库两次,即使两个模式中的表相同,是否有一个删除代码重复
猜你喜欢
  • 1970-01-01
  • 2015-07-06
  • 2017-12-30
  • 2021-06-25
  • 1970-01-01
  • 2012-07-10
  • 2016-03-26
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多