public interface ShardableEntity { public String getIdentifier();}public class ContactEntity implements ShardableEntity { public String getIdentifier(){ return this._id; } //other code omitted is the same with previous post}映射文件ContactEntity.hbm.xml與上一篇文章中的一樣
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/hbshards</property> <property name="connection.username">root</property> <property name="connection.password">dev</property> <property name="connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> <property name="hbm2ddl.auto">validate</property> <property name="hibernate.connection.shard_id">0</property> <property name="hibernate.shard.enable_cross_shard_relationship_checks">false</property> <mapping resource="ContactEntity.hbm.xml" /></session-factory></hibernate-configuration>shard1.hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/hbshards2</property> <property name="connection.username">root</property> <property name="connection.password">dev</property> <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> <property name="hibernate.connection.shard_id">1</property> <property name="hibernate.shard.enable_cross_shard_relationship_checks">false</property></session-factory></hibernate-configuration>其中shard0.hibernate.cfg.xml作為主要的配置文件,針對(duì)每個(gè)shard創(chuàng)建的SessionFactory對(duì)象,除了數(shù)據(jù)庫(kù)連接信息的配置之外,都來(lái)自shard0.hibernate.cfg.xml
import java.util.List;import java.util.ArrayList;import org.hibernate.shards.strategy.resolution.ShardResolutionStrategy;import org.hibernate.shards.strategy.selection.ShardResolutionStrategyData;import org.hibernate.shards.ShardId;/* * a simple ShardResolutionStrategy implementation for our ContactEntity */public class MyShardResolutionStrategy implements ShardResolutionStrategy { private List<ShardId> _shardIds; public MyShardResolutionStrategy(List<ShardId> shardIds){ this._shardIds = shardIds; } public List selectShardIdsFromShardResolutionStrategyData( ShardResolutionStrategyData arg0){ List ids = new ArrayList(); String id = (String)arg0.getId(); if(id==null || id.isEmpty()) ids.add(this._shardIds.get(0)); else{ //our shard selection is identified by the //first char(number) in contact id //0-4 => shards0, 5-9 => shards1 Integer i = new Integer(id.substring(0, 1)); ids.add(this._shardIds.get(i/5)); } return ids; }}ShardSelectionStrategy接口的實(shí)現(xiàn):
import java.util.List;import org.hibernate.shards.ShardId;import org.hibernate.shards.strategy.selection.ShardSelectionStrategy;/* * a simple ShardSelectionStrategy implementation for our ContactEntity */public class MyShardSelectionStrategy implements ShardSelectionStrategy { private List<ShardId> _shardIds; public MyShardSelectionStrategy(List<ShardId> shardIds){ this._shardIds=shardIds; } public ShardId selectShardIdForNewObject(Object obj) { if(obj instanceof ShardableEntity) { String id = ((ShardableEntity)obj).getIdentifier(); if(id==null || id.isEmpty()) return this._shardIds.get(0); Integer i = new Integer(id.substring(0, 1)); //our shard selection is identified by the //first char(number) in contact id //0-4 => shards0, 5-9 => shards1 return this._shardIds.get(i/5); } //for non-shardable entities we just use shard0 return this._shardIds.get(0); }}接下來(lái)就是怎么使用hibernate shards的測(cè)試代碼了:
import java.util.Iterator;import java.util.List;import java.util.ArrayList;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.shards.*;import org.hibernate.shards.cfg.*;import org.hibernate.shards.strategy.*;import org.hibernate.shards.strategy.access.*;import org.hibernate.shards.strategy.resolution.*;import org.hibernate.shards.strategy.selection.*;項(xiàng)目結(jié)構(gòu)圖:
public class Main { public static void main(String[] args) { HibernateShardsTest(args); } private static SessionFactory createSessionFactory() { //加載主配置文件,為每個(gè)shard創(chuàng)建SessionFactory對(duì)象時(shí)將 //以他作為原型 Configuration prototypeCfg = new Configuration() .configure("shard0.hibernate.cfg.xml"); //每個(gè)shard的配置文件 List<ShardConfiguration> shardCfgs = new ArrayList<ShardConfiguration>(); shardCfgs.add(buildShardConfig("shard0.hibernate.cfg.xml")); shardCfgs.add(buildShardConfig("shard1.hibernate.cfg.xml")); //數(shù)據(jù)切片策略的工廠對(duì)象 ShardStrategyFactory strategyFactory = buildShardStrategyFactory(); ShardedConfiguration shardedConfig = new ShardedConfiguration( prototypeCfg, shardCfgs, strategyFactory); //返回一個(gè)ShardedSessionFactory對(duì)象 return shardedConfig.buildShardedSessionFactory(); } private static ShardStrategyFactory buildShardStrategyFactory() { ShardStrategyFactory factory = new ShardStrategyFactory() { //測(cè)試用的自定義數(shù)據(jù)切片策略的工廠類 public ShardStrategy newShardStrategy(List<ShardId> shardIds) { ShardSelectionStrategy ss = new MyShardSelectionStrategy(shardIds); ShardResolutionStrategy rs = new MyShardResolutionStrategy(shardIds); ShardAccessStrategy as = new SequentialShardAccessStrategy(); return new ShardStrategyImpl(ss, rs, as); } }; return factory; } private static ShardConfiguration buildShardConfig(String configFile) { Configuration config = new Configuration().configure(configFile); return new ConfigurationToShardConfigurationAdapter(config); } private static void HibernateShardsTest(String[] args){ String loginId = "RicCC@cnblogs.com"; String password = "123"; if(args!=null && args.length==2){ loginId = args[0]; password = args[1]; } SessionFactory factory = null; try{ factory = createSessionFactory(); ShardsTestCreate(factory); ShardsTestLogin(factory, loginId, password); ShardsTestDelete(factory); }catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); }finally{ if(factory!=null) factory.close(); } } private static void ShardsTestCreate(SessionFactory factory){ Session session = null; Transaction transaction = null; System.out.println("===Create Contacts==="); try{ session = factory.openSession(); transaction = session.beginTransaction(); session.save(new ContactEntity("01111111","RicCC@cnblogs.com" , "123", "Richie", "RicCC@cnblogs.com")); session.save(new ContactEntity("91111111","a@cnblogs.com" , "123", "AAA", "a@cnblogs.com")); session.save(new ContactEntity("81111111","b@cnblogs.com" , "123", "BBB", "b@cnblogs.com")); session.save(new ContactEntity("31111111","c@cnblogs.com" , "123", "CCC", "c@cnblogs.com")); transaction.commit(); }catch(Exception e){ if(transaction!=null) transaction.rollback(); System.out.println(e.getMessage()); e.printStackTrace(); }finally{ if(session!=null) session.close(); } } private static void ShardsTestLogin(SessionFactory factory , String loginId, String password){ Session session = null; ContactEntity c = null; System.out.println("\n===Login Test==="); try{ session = factory.openSession(); List contacts = session.createQuery("from ContactEntity where LoginId=:loginId") .setString("loginId", loginId) .list(); if(contacts.isEmpty()) System.out.println("Contact \"" + loginId + "\" not found!"); else{ c = (ContactEntity)contacts.get(0); if(c.getPassword().equals(password)) System.out.println("Contact \"" + loginId + "\" login successful"); else System.out.println("Password is incorrect (should be: " + c.getPassword() + ", but is: " + password + ")"); } System.out.println("\n===Get Contact by Id==="); c = (ContactEntity)session.get(ContactEntity.class, "81111111"); System.out.println(c.toString()); c = (ContactEntity)session.get(ContactEntity.class, "31111111"); System.out.println(c.toString()); }catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); }finally{ if(session!=null) session.close(); } } private static void ShardsTestDelete(SessionFactory factory){ Session session = null; Transaction transaction = null; System.out.println("\n===Delete Contacts==="); try{ session = factory.openSession(); transaction = session.beginTransaction(); List contacts = session.createQuery("from ContactEntity").list(); Iterator it = contacts.iterator(); while(it.hasNext()){ session.delete(it.next()); } transaction.commit(); }catch(Exception e){ if(transaction!=null) transaction.rollback(); System.out.println(e.getMessage()); e.printStackTrace(); }finally{ if(session!=null) session.close(); } }}
聯(lián)系客服