猿问

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

设置


我有一个使用 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 的东西,所以这绝对是错误的路径。


白板的微信
浏览 285回答 3
3回答

沧海一幻觉

不要创建 jdbc 模板 bean。相反,每次需要执行查询时,您都可以使用实体管理器工厂来创建 jdbc 模板的新实例。这种方法对我有用。public class JdbcQueryTemplate {&nbsp; &nbsp; public JdbcTemplate getJdbcTemplate(EntityManagerFactory emf) {&nbsp; &nbsp; &nbsp; &nbsp; EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) emf;&nbsp; &nbsp; &nbsp; &nbsp; return new JdbcTemplate(info.getDataSource());&nbsp; &nbsp; }&nbsp; &nbsp; public NamedParameterJdbcTemplate getNamedJdbcTemplate(EntityManagerFactory emf) {&nbsp; &nbsp; &nbsp; &nbsp; EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) emf;&nbsp; &nbsp; &nbsp; &nbsp; return new NamedParameterJdbcTemplate(info.getDataSource());&nbsp; &nbsp; }}然后使用该类进行查询。public class Test{&nbsp; @Autowired&nbsp; private EntityManagerFactory entityManagerFactory;&nbsp; public List<Entity> executeQuery() {&nbsp; &nbsp; &nbsp; return new JdbcQueryTemplate().getNamedJdbcTemplate(entityManagerFactory)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .query("query", new BeanPropertyRowMapper<>(Entity.class));&nbsp; }}

ITMISS

没有一种简单的方法可以做到这一点,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 语句。
随时随地看视频慕课网APP

相关分类

Java
我要回答