为了账号安全,请及时绑定邮箱和手机立即绑定

Spring JdbcTemplate - 如何为实现多租户添加每个查询?

Spring JdbcTemplate - 如何为实现多租户添加每个查询?

白板的微信 2021-10-17 15:38:48
设置我有一个使用 Spring 4.3、JdbcTemplate、Hibernate 5 和 MySQL 8 的应用程序。我在每个模式的 hibernate 中实现了多租户,其中我使用 hibernates 多租户机制切换模式 -MultiTenantConnectionProvider并且基本上在那里做:connection.createStatement().execute("USE " + databaseNamePrefix + tenantIdentifier); 这有效。现在我的应用程序的报告部分JdbcTemplate用于查询数据库。现在我想在 JdbcTemplate 执行的每个查询之前发出这个USE tenantIdentifier语句。题我如何为 JdbcTemplate 执行的每个查询添加一些 SQL 或语句?我试过的我查看了 JdbcTemplate,唯一发现的是设置一个NativeJdbcExtractor. 我已经尝试了下面的代码,但他正在通过这些方法甚至没有登录。@Bean@DependsOn("dataSource")public JdbcTemplate jdbcTemplate() {  JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());  jdbcTemplate.setNativeJdbcExtractor(new SimpleNativeJdbcExtractor(){     @Override     public Connection getNativeConnection(Connection con) throws SQLException {        LOGGER.info("getNativeConnection");        System.out.println("aaa");        return super.getNativeConnection(con);     }     @Override     public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException {        System.out.println("aaa");        LOGGER.info("getNativeConnectionFromStatement");        return super.getNativeConnectionFromStatement(stmt);     }  });  return jdbcTemplate;}向 Spring 添加功能请求:https : //jira.spring.io/browse/SPR-17342编辑:我查看了 Spring 5,他们删除了 JdbcExtractor 的东西,所以这绝对是错误的路径。
查看完整描述

3 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

不要创建 jdbc 模板 bean。相反,每次需要执行查询时,您都可以使用实体管理器工厂来创建 jdbc 模板的新实例。这种方法对我有用。


public class JdbcQueryTemplate {


    public JdbcTemplate getJdbcTemplate(EntityManagerFactory emf) {

        EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) emf;

        return new JdbcTemplate(info.getDataSource());

    }


    public NamedParameterJdbcTemplate getNamedJdbcTemplate(EntityManagerFactory emf) {

        EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) emf;

        return new NamedParameterJdbcTemplate(info.getDataSource());

    }

}

然后使用该类进行查询。


public class Test{


  @Autowired

  private EntityManagerFactory entityManagerFactory;


  public List<Entity> executeQuery() {

      return new JdbcQueryTemplate().getNamedJdbcTemplate(entityManagerFactory)

              .query("query", new BeanPropertyRowMapper<>(Entity.class));

  }

}


查看完整回答
反对 回复 2021-10-17
?
ITMISS

TA贡献1871条经验 获得超8个赞

没有一种简单的方法可以做到这一点,JdbcTemplate因为有些方法非常通用,例如execute(ConnectionCallback<T> action)方法允许直接访问java.sql.Connection对象。

DataSource为每个租户拥有一个单独的bean 并在 Spring 中使用合格的自动装配来解决这个问题会更容易。

拥有每个租户java.sql.Connection将允许在USE tenantIdentifier打开新数据库连接时执行语句(一些池库支持开箱即用)。作为MySQL USE 语句文档,这可以在每个会话中完成一次:

USE db_name 语句告诉 MySQL 使用 db_name 数据库作为后续语句的默认(当前)数据库。数据库将保持默认状态,直到会话结束或发出另一个 USE 语句。


查看完整回答
反对 回复 2021-10-17
  • 3 回答
  • 0 关注
  • 283 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信