Hibernate 框架接入 Sharding-jdbc 分库分表

由于项目使用的是 guice 框架,所以都需要手动配置引入 Hibernate ORM,这个时候需要使用到分库分表的组件 Sharding-jdbc 组件。

对于 spring、springboot 官方都有示例可以参考,但是对于这种直接用 Hibernate 框架,同时 sharding-jdbc 也没有对于这种原生框架扩展支持,现在使用基本上都是使用 jpa 了。

下面基于 hibernate 的 hibernate.connection.provider_class 来做实现,其实也可以理解为在 springboot 为 ORM 框架提供的 DataSource,所以这里就可以想到,将 Sharding-jdbc 当作是 Hibernate 连接池,Hibernate 用 Sharding-jdbc 执行 SQL,这个时候 Sharding-jdbc 可以根据规则对 SQL 进行。

由于 Shrading-jdbc 官方并没有实现 Hibernate 的 ConnectionProvider ,所以先实现这个类,我这边参考了官方实现的 c3p0,以及 druid 官方实现。

1、自定义 ShardingSphereConnectionProvider 实现 ConnectionProvider。

public class ShardingSphereConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
    private static final long serialVersionUID = 1026193803901107611L;

    private ShardingDataSource dataSource;

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

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

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

    @Override
    public void configure(Map map) {
        try {
            Map dataSourceMap = (Map) map.get(ConfigKeys.DATA_SOURCE_MAP.name());
            ShardingRuleConfiguration shardingRuleConfig = (ShardingRuleConfiguration) map.get(ConfigKeys.SHARDING_RULE_CONFIG.name());
            Properties props = (Properties) map.get(ConfigKeys.PROPS.name());
            this.dataSource = new ShardingDataSource(dataSourceMap, new ShardingRule(shardingRuleConfig, dataSourceMap.keySet()), props);
        } catch (SQLException var3) {
            throw new IllegalArgumentException("config error", var3);
        }
    }

    @Override
    public void stop() {
        try {
            this.dataSource.close();
        } catch (Exception ex) {
        }
    }

    @Override
    public boolean isUnwrappableAs(Class aClass) {
        return this.dataSource.isWrapperFor(aClass);
    }

    @Override
    public  T unwrap(Class aClass) {
        try {
            return this.dataSource.unwrap(aClass);
        } catch (SQLException se) {
            logger.error(se);
        }
        return null;
    }

    public enum ConfigKeys {
        DATA_SOURCE_MAP,
        SHARDING_RULE_CONFIG,
        PROPS;
    }

}

2、从上面实现可以看到,创建 ShardingDataSource 是需要三个参数,分别是分库分表配置规则类、数据源集合以及属性配置,可以参考官方文档去了解。

        Map settings = new HashMap<>(16);
        settings.put(Environment.DIALECT, "org.hibernate.dialect.SQLServer2012Dialect");
        settings.put(Environment.CONNECTION_PROVIDER, new ShardingJdbcConnectionProvider());
        //设置hibernate的querycahce大小
        if(CustomerAssetConfig.getCurrent().isUseHibernateCacheSize()){
            settings.put(Environment.QUERY_PLAN_CACHE_MAX_SIZE, 64);
            settings.put(Environment.QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE, 32);
            settings.put(Environment.QUERY_PLAN_CACHE_MAX_SOFT_REFERENCES, 1024);
            settings.put(Environment.QUERY_PLAN_CACHE_MAX_STRONG_REFERENCES,64);
        }

        settings.put(ShardingSphereConnectionProvider.ConfigKeys.SHARDING_RULE_CONFIG.name(), getShardingRuleConfig());
        settings.put(ShardingSphereConnectionProvider.ConfigKeys.DATA_SOURCE_MAP.name(), createDataSourceMap());
        settings.put(ShardingSphereConnectionProvider.ConfigKeys.PROPS.name(), new Properties());

        StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();

        registryBuilder.applySettings(settings);

        StandardServiceRegistry registry = registryBuilder.build();

        MetadataSources sources = new MetadataSources(registry);

        for (Class entityClass : this.getEntityClasses(domainPackageName)) {
            sources.addAnnotatedClass(entityClass);
        }

        Metadata metadata = sources.getMetadataBuilder().build();

        return metadata.getSessionFactoryBuilder().build();

 将自己定义的 sharding-jdbc 规则三个数据放到 settings 中即可,getShardingRuleConfig()、createDataSourceMap()和new Properties()定义好配置类即可。

你可能感兴趣的:(sharding,java,hibernate,java,中间件,后端,hibernate)