Hibernate Shards
A Hibernate Shards egy olyan keretrendszer, amely olyan problémákra nyújt megoldást, ahol az összes szükséges adatot nem tudjuk egy relációs adatbázisban eltárolni. Az adatok egységbe zárhatók, minimalizálva ezen műveletek komplexitását, támogatást nyújtva a horizontális particionálás megvalósítására a Hibernate Core-ban. Használata abban az esetben javasolt például, amikor túl sok adattal, vagy elosztott architektúrán kell dolgozni. Ilyen esetekben több elosztott adatbázisra lehet szükség, amely kétségkívül bonyolítja egy alkalmazás fejlesztését. A shard szó jelentése cserép, szilánk, a Hibernate Shards felfogható, mint egy keretrendszer, mely ezen külön álló szilánkokat egyesíti, hogy a fejlesztő egységként tudja kezelni őket. Legfőbb tulajdonságai
PéldaAz alábbi példa a világ minden pontjáról érkező időjárási adatokat dolgoz fel és tárol el egy relációs adatbázisban: Az adatbázissémát a következő sql definiálja: CREATE TABLE WEATHER_REPORT (
REPORT_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
CONTINENT ENUM('AFRICA', 'ANTARCTICA', 'ASIA', 'AUSTRALIA', 'EUROPE', 'NORTH AMERICA', 'SOUTH AMERICA'),
LATITUDE FLOAT,
LONGITUDE FLOAT,
TEMPERATURE INT,
REPORT_TIME TIMESTAMP
);
Egy “jelentés” modellje: public class WeatherReport {
private Integer reportId;
private String continent;
private BigDecimal latitude;
private BigDecimal longitude;
private int temperature;
private Date reportTime;
... // getters and setters
}
A <hibernate-mapping package="org.hibernate.shards.example.model">
<class name="WeatherReport" table="WEATHER_REPORT">
<id name="reportId" column="REPORT_ID">
<generator class="native"/>
</id>
<property name="continent" column="CONTINENT"/>
<property name="latitude" column="LATITUDE"/>
<property name="longitude" column="LONGITUDE"/>
<property name="temperature" column="TEMPERATURE"/>
<property name="reportTime" type="timestamp" column="REPORT_TIME"/>
</class>
</hibernate-mapping>
Hozzáférés a Az alábbi kódrészlet az időjárás jelentő alkalmazásból 3 szilánkot használ: public SessionFactory createSessionFactory() {
Configuration prototypeConfig = new Configuration().configure("shard0.hibernate.cfg.xml");
prototypeConfig.addResource("weather.hbm.xml");
List<ShardConfiguration> shardConfigs = new ArrayList<ShardConfiguration>();
shardConfigs.add(buildShardConfig("shard0.hibernate.cfg.xml"));
shardConfigs.add(buildShardConfig("shard1.hibernate.cfg.xml"));
shardConfigs.add(buildShardConfig("shard2.hibernate.cfg.xml"));
ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory();
ShardedConfiguration shardedConfig = new ShardedConfiguration(
prototypeConfig,
shardConfigs,
shardStrategyFactory);
return shardedConfig.buildShardedSessionFactory();
}
ShardStrategyFactory buildShardStrategyFactory() {
ShardStrategyFactory shardStrategyFactory = new ShardStrategyFactory() {
public ShardStrategy newShardStrategy(List<ShardId> shardIds) {
RoundRobinShardLoadBalancer loadBalancer = new RoundRobinShardLoadBalancer(shardIds);
ShardSelectionStrategy pss = new RoundRobinShardSelectionStrategy(loadBalancer);
ShardResolutionStrategy prs = new AllShardsShardResolutionStrategy(shardIds);
ShardAccessStrategy pas = new SequentialShardAccessStrategy();
return new ShardStrategyImpl(pss, prs, pas);
}
};
return shardStrategyFactory;
}
ShardConfiguration buildShardConfig(String configFile) {
Configuration config = new Configuration().configure(configFile);
return new ConfigurationToShardConfigurationAdapter(config);
}
A fenti kódrészletből kiderül, hogy valójában 4
A 3 Ezután vessünk egy pillantást a configuration és mapping fájlokra: <!-- Contents of shard0.hibernate.cfg.xml -->
<hibernate-configuration>
<session-factory name="HibernateSessionFactory0"> <!-- note the different name -->
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://dbhost0:3306/mydb</property>
<property name="connection.username">my_user</property>
<property name="connection.password">my_password</property>
<property name="hibernate.connection.shard_id">0</property> <!-- new -->
<property name="hibernate.shard.enable_cross_shard_relationship_checks">true</property> <!-- new -->
</session-factory>
</hibernate-configuration>
<!-- Contents of shard1.hibernate.cfg.xml -->
<hibernate-configuration>
<session-factory name="HibernateSessionFactory1"> <!-- note the different name -->
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://dbhost1:3306/mydb</property>
<property name="connection.username">my_user</property>
<property name="connection.password">my_password</property>
<property name="hibernate.connection.shard_id">1</property> <!-- new -->
<property name="hibernate.shard.enable_cross_shard_relationship_checks">true</property> <!-- new -->
</session-factory>
</hibernate-configuration>
A <hibernate-mapping package="org.hibernate.shards.example.model">
<class name="WeatherReport" table="WEATHER_REPORT">
<id name="reportId" column="REPORT_ID" type="long">
<generator class="org.hibernate.shards.id.ShardedTableHiLoGenerator"/>
</id>
<property name="continent" column="CONTINENT"/>
<property name="latitude" column="LATITUDE"/>
<property name="longitude" column="LONGITUDE"/>
<property name="temperature" column="TEMPERATURE"/>
<property name="reportTime" type="timestamp" column="REPORT_TIME"/>
</class>
</hibernate-mapping>
A Hibernate annotációk használata shard-okkalA fenti példában Hibernate mapping fájlokat használtunk, hogy a mapping-eket specifikáljuk, de ugyanezt megtehetjük Hibernate annotációkkal is: @Entity
@Table(name="WEATHER_REPORT")
public class WeatherReport {
@Id @GeneratedValue(generator="WeatherReportIdGenerator")
@GenericGenerator(name="WeatherReportIdGenerator", strategy="org.hibernate.shards.id.ShardedUUIDGenerator")
@Column(name="REPORT_ID")
private Integer reportId;
@Column(name="CONTINENT")
private String continent;
@Column(name="LATITUDE")
private BigDecimal latitude;
@Column(name="LONGITUDE")
private BigDecimal longitude;
@Column(name="TEMPERATURE")
private int temperature;
@Column(name="REPORT_TIME")
private Date reportTime;
... // getters and setters
}
A fenti példa az annotációk használatára egy egyszerű példa. Ezután csak pár egyszerű változtatásra van szükség a public SessionFactory createSessionFactory() {
AnnotationConfiguration prototypeConfig = new AnnotationConfiguration().configure("shard0.hibernate.cfg.xml");
prototypeConfig.addAnnotatedClass(WeatherReport.class);
List<ShardConfiguration> shardConfigs = new ArrayList<ShardConfiguration>();
shardConfigs.add(buildShardConfig("shard0.hibernate.cfg.xml"));
shardConfigs.add(buildShardConfig("shard1.hibernate.cfg.xml"));
shardConfigs.add(buildShardConfig("shard2.hibernate.cfg.xml"));
ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory();
ShardedConfiguration shardedConfig = new ShardedConfiguration(
prototypeConfig,
shardConfigs,
shardStrategyFactory);
return shardedConfig.buildShardedSessionFactory();
}
|