- 浏览: 78698 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
zcqshine:
<div class="quote_title ...
Struts2+JSON 实现AJAX 返回对象和列表 -
cwj158:
假如实体类Users的属性是Float的话。没办法格式化为js ...
Struts2+JSON 实现AJAX 返回对象和列表 -
zzd:
用你的方法以后,一直报找不到action, ,这是为什么
Struts2+JSON 实现AJAX 返回对象和列表 -
zcqshine:
<div class="quote_title ...
Struts2+JSON 实现AJAX 返回对象和列表 -
lghjbxc:
假如实体类Users的属性是Float的话。没办法格式化为js ...
Struts2+JSON 实现AJAX 返回对象和列表
当一个大型应用试图在一个单一的数据库表增加TB的数据时,性能经常会下降,对所有数据编索引对数据的读写都会很耗时,显然,如果我们根据某种策略将单一的表数据存储到不同的数据库表中,将会大大提高性能,切分将是一个令人振奋的可选方法。
切分分为纵向切分和横向切分,纵向切分就是将数据库表为单元进行切分,不同的数据存储到不同的数据库中,例如:有数据库表A,B,其中A存储在数据库A中,B存储在数据库中。
横向切分,将同一个表的数据进行切分,表中的数据分别存储到不同的数据库中,例如:同一个数据库表,亚洲的数据存储在数据库A中,其它洲的存储在数据库B中。
hibernate Shards 就是一个让应用横向切分的分布式数据库解决方案,它可以让一个 Hibernate应用很简单的加入横向切分功能,以下是我在通过参考一些文摘后应用JAVA写的一个测试例子,本例子就以存储 天气预报 信息来进行,我们将要做的是将天气预报信息按洲的方式存储到对应的数据库,来达到性能的提升。
在继续本例程开始之前你需要下载:
Hibernate3.2 应用开发包:http://sourceforge.net/projects/hibernate/files/hibernate3/
Hibernate3.0 Shards 应用开发包:http://sourceforge.net/projects/hibernate/files/hibernate-shards/
Spring2.5 应用开发包:http://www.springsource.org/download
开发包准备好后我们按以下过程来开始Hibernate Shards 旅程:
1、创建数据库与数据库表:
在本示例我将使用SQL SERVER 200 来做测试
create database ASIA --亚洲相关信息数据库 create database AFRICA --非洲相关信息数据库 GO --在ASIA与AFRICA 数据库中分别创建天气预报数据表 --创建天气序报数据表 IF EXISTS(SELECT 1 FROM SYSOBJECTS WHERE NAME='WEATHER_REPORT') DROP TABLE WEATHER_REPORT GO CREATE TABLE WEATHER_REPORT ( REPORT_ID VARCHAR(50) PRIMARY KEY DEFAULT 0 NOT NULL, --预报ID CONTINENT varchar(20) not null, --所属的洲 LATITUDE FLOAT, --纬度 LONGITUDE FLOAT, --经度 TEMPERATURE INT, --温度 REPORT_TIME datetime --预报日期 )
2、创建工程
为了更切实意,我使用MYECLIPSE创建一个名为:hibernateShards JAVA 工程并将下载的相关应用包添加引用,开发可根据自身使用的工具选择
2.1、创建hibernate 相关切分配置文件shard0.hibernate.cfg.xml 和 shard1.hibernate.cfg.xml
shard0.hibernate.cfg.xml:
<!-- 切分的 hibernate 配置文件,每个数据库都应有这样一个描述文件 --> <hibernate-configuration> <session-factory name="HibernateSessionFactory0"> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <property name="connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver</property> <property name="connection.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=ASIA</property> <property name="connection.username">sa</property> <property name="connection.password">sa</property> <!-- 切分 ID,需保持一致 --> <property name="hibernate.connection.shard_id">0</property> <!-- 对跨切分关系是否进行检查,在生产环境尽量设为 false,因为检查会非常花时间 --> <property name="hibernate.shard.enable_cross_shard_relationship_checks">true</property> </session-factory> </hibernate-configuration>
shard1.hibernate.cfg.xml:
<hibernate-configuration> <session-factory name="HibernateSessionFactory0"> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <property name="connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver</property> <property name="connection.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=AFRICA</property> <property name="connection.username">sa</property> <property name="connection.password">sa</property> <!-- 切分 ID,需保持一致 --> <property name="hibernate.connection.shard_id">1</property> <!-- 对跨切分关系是否进行检查,在生产环境尽量设为 false,因为检查会非常花时间 --> <property name="hibernate.shard.enable_cross_shard_relationship_checks">true</property> </session-factory> </hibernate-configuration>
我们看到以上二个文件内容非常类似,唯一不同的是数据库名和切分ID不同
2.2、建立相关hibernate对象关系映射文件和相关持久对象
weather.hbm.xml
<hibernate-mapping package="com.hibernateshards.po"> <class name="WeatherReport" table="weather_report" dynamic-update="true" dynamic-insert="true"> <id name="reportId" column="REPORT_ID" unsaved-value="-1"> <!-- 在这里使用 UUID 来生成主键,以防止ID在插入不同的数据库中ID值重复 --> <generator class="org.hibernate.shards.id.ShardedUUIDGenerator"></generator> </id> <property name="continent" column="CONTINENT" type="string"></property> <property name="latitude" column="LATITUDE" type="float"></property> <property name="longitude" column="LONGITUDE" type="float"></property> <property name="tempErature" column="TEMPERATURE" type="int"></property> <property name="reportTime" column="REPORT_TIME" type="date"></property> </class> </hibernate-mapping>
持久对象:WeatherReport.java
/** * 天气预报相关信息对象 * * @date 2010-10-23下午06:38:21 * * @author ChenTao */ public class WeatherReport { private BigInteger reportId; private String continent; private Float latitude; private Float longitude; private Integer tempErature; private Date reportTime; // getter 和 setter 方法略..... }
2.3、定义切分选策略和创建SessionFactory 对象
WeatherShardSelectionStrategy.java
/** * * 切分选择策略,根据自已定义 * * @date 2010-10-23下午06:58:04 * * @author ChenTao */ public class WeatherShardSelectionStrategy implements ShardSelectionStrategy{ /** * 选择策略: * 如果持久化对象是一个 WeatherReport,那么其所在的洲被确定,因此选择了一个切分。在这种情况下, * 有两个切分:0 和 1,其中切分 0 中包含 亚洲 相关天气预报,切分 1 中包含除亚洲之外所有的洲天气预报。 * 当然在这里可以将每个洲都定义,但这里只做一个测试应用,只描述其操作流程 * */ public ShardId selectShardIdForNewObject(Object obj) { if(obj instanceof WeatherReport){ WeatherReport weatherReport = (WeatherReport) obj; return this.continentShardId(weatherReport.getContinent()); } throw new IllegalArgumentException(); } /** * 根据洲来获取切分 * * @param continent * @return */ private ShardId continentShardId(String continent){ if(Constants.CONTINENT_ASIA.equals(continent)){ return new ShardId(0); } else { return new ShardId(1); } } }
// 创建SessionFactory
ShardedSessionFactoryBuilder.java
public class ShardedSessionFactoryBuilder { private List<String> hibernateConfigurations; private List<String> resourceConfigurations; public void setHibernateConfigurations(List<String> hibernateConfigurations) { this.hibernateConfigurations = hibernateConfigurations; } public void setResourceConfigurations(List<String> resourceConfigurations) { this.resourceConfigurations = resourceConfigurations; } public SessionFactory createSessionFactory(){ Configuration propotypeConfig = this.getPrototypeConfig(this.hibernateConfigurations.get(0), this.resourceConfigurations); List<ShardConfiguration> shardConfigs = new ArrayList<ShardConfiguration>(); for(String hibernateConfig:this.hibernateConfigurations){ shardConfigs.add(this.buildShardConfig(hibernateConfig)); } ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory(); ShardedConfiguration shardedConfig = new ShardedConfiguration(propotypeConfig,shardConfigs,shardStrategyFactory); return shardedConfig.buildShardedSessionFactory(); } /** * 创建一个 Hibernate 配置 * * @param hibernateFile * hibernate 切分配置文件 * @param resourceFiles * 资源文件 * * @return */ public Configuration getPrototypeConfig(String hibernateFile,List<String> resourceFiles){ Configuration prototypeConfig = this.getConfiguration(hibernateFile); for(String res:resourceFiles){ prototypeConfig.addResource(res); } return prototypeConfig; } public Configuration getConfiguration(String hibernateFile){ return new Configuration().configure(hibernateFile); } private ShardStrategyFactory buildShardStrategyFactory(){ ShardStrategyFactory shardStrategyFactory = new ShardStrategyFactory(){ public ShardStrategy newShardStrategy(List<ShardId> shardIds){ ShardSelectionStrategy pss = new WeatherShardSelectionStrategy(); ShardResolutionStrategy prs = new AllShardsShardResolutionStrategy(shardIds); ShardAccessStrategy pas = new SequentialShardAccessStrategy(); return new ShardStrategyImpl(pss,prs,pas); } }; return shardStrategyFactory; } private ShardConfiguration buildShardConfig(String hibernateConfig){ return new ConfigurationToShardConfigurationAdapter(this.getConfiguration(hibernateConfig)); } }
2.4、定义数据访问接口和实现对象
接口定义
WeatherReportDao.java
/** * 天气预报数据操作相关接口定义 * * @date 2010-10-23下午06:38:50 * * @author ChenTao */ public interface WeatherReportDao { /** * 查询所有天气预报相关数据 * * @return * @throws HibernateException */ List<WeatherReport> findAll() throws HibernateException; /** * 根据天气预报ID进行查询 * * @param id java.lang.Integer * * @return * @throws HibernateException */ WeatherReport findById(Integer id) throws HibernateException; /** * 查据天气预报所在的洲进行查询 * * @param continent java.lang.String * * @return * @throws HibernateException */ List<WeatherReport> findByContinent(String continent) throws HibernateException; /** * 保存天气预报数据 * * @param weather com.hibernateshards.po.WeatherReport * * @throws HibernateException */ void save(WeatherReport weather) throws HibernateException; /** * 更改天气预报数据 * * @param weather com.hibernateshards.po.WeatherReport * * @throws HibernateException */ void update(WeatherReport weather) throws HibernateException; /** * 删除天气预报数据 * * @param weather com.hibernateshards.po.WeatherReport * * @throws HibernateException */ void delete(WeatherReport weather) throws HibernateException; }
真实的数据操作对象
WeatherReportDaoImpl.java
/** * 天气预报数据层交互对象,用于处理数据的查找与CURD操作 * * @date 2010-10-23下午06:28:25 * * @author ChenTao */ public class WeatherReportDaoImpl implements WeatherReportDao { private SessionFactory sessionFactory; public WeatherReportDaoImpl() { super(); } @SuppressWarnings("unchecked") public List<WeatherReport> findAll() throws HibernateException { return (List<WeatherReport>) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { return session.createQuery("from WeatherReport w") .list(); } }); } @SuppressWarnings("unchecked") public List<WeatherReport> findByContinent(final String continent) throws HibernateException { return (List<WeatherReport>) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { return session .createQuery( "from WeatherReport as weather where weather.continent=?") .setString(0, continent.trim()).list(); } }); } public WeatherReport findById(final Integer id) throws HibernateException { return (WeatherReport) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { return session .createQuery( "from WeatherReport as weather where weather.reportId=?") .setInteger(0, id).uniqueResult(); } }); } public void save(final WeatherReport weather) throws HibernateException { this.getHibernateTemplate().save(weather); } public void update(final WeatherReport weather) throws HibernateException { this.getHibernateTemplate().saveOrUpdate(weather); } public void delete(final WeatherReport weather) throws HibernateException { this.getHibernateTemplate().delete(weather); } public void setSessionFactory(final SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } private HibernateTemplate getHibernateTemplate() { return new HibernateTemplate(sessionFactory); } }
2.5、配置Spring
因为前面我们以经下载了 spring 相关开发包,我将要使用spring来加载相关配置和托管相应Bean创建和SessionFactory对象的创建
weatherSpring-config.xml
<beans> <bean id="shardedSessionFactoryBuilder" class="com.hibernateshards.shardsupport.ShardedSessionFactoryBuilder"> <property name="hibernateConfigurations"> <list> <value>shard0.hibernate.cfg.xml</value> <value>shard1.hibernate.cfg.xml</value> </list> </property> <property name="resourceConfigurations"> <list> <value>com/hibernateshards/po/weather.hbm.xml</value> </list> </property> </bean> <!-- 连接域对象 --> <bean id="sessionFactory" factory-bean="shardedSessionFactoryBuilder" factory-method="createSessionFactory"></bean> <bean id="weatherReportDao" class="com.hibernateshards.domain.WeatherReportDaoImpl"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> </beans>
2.6、测试
通过以上的流程下来所有需要实现的代码和配置都已完成,虽然写了这么多,也不知道是否真的可以实现跨数据进行数据库的CRUD操作,为了验证真实性,我写了一个测试对象进
行测试,包含对数据的CRUD 都通过测试,来看下面测试方法:
WeatherReportTest.java
/** * 对 Shards 进行测试 * * @date 2010-10-23下午06:37:56 * @author ChenTao */ public class WeatherReportTest { /** * Spring 的上下文, */ private static ApplicationContext ac; /** * 数据操作对象 */ private static WeatherReportDao weatherReportDao; public static void main(String[] args) { try { /* 加载 spring 配置 */ loadConfig(); weatherReportDao = (WeatherReportDao) getAc().getBean("weatherReportDao"); /* 亚洲,以下数据将会增加到 ASIA 数据库中 */ // save(Constants.CONTINENT_ASIA); /* 非洲,以下数据将会增加到 AFRICA 数据库中 */ // save(Constants.CONTINENT_AFRICA); /* 对数据进行修改 */ // update(); /* 对数据进行删除 */ // delete(); List<WeatherReport> weatherList = null; /* 查询所有天气预报数据,这将会扫描所有的数据库 */ weatherList = finaAll(); print(weatherList); // // 按洲查询,指定某个数据库查询,其体看配置 // weatherList = findByContinent(Constants.CONTINENT_ASIA); // print(weatherList); } catch (Exception e) { e.printStackTrace(); } } private static List<WeatherReport> finaAll() throws Exception { if (null != weatherReportDao) { return weatherReportDao.findAll(); } throw new Exception("No Data!"); } private static List<WeatherReport> findByContinent(String continent) throws Exception { if (null != weatherReportDao) { return weatherReportDao.findByContinent(continent); } throw new Exception("No Data!"); } private static void save(String continent) throws Exception { if (null != weatherReportDao) { WeatherReport weather = new WeatherReport(); weather.setContinent(continent); weather.setLatitude(30.20F); weather.setLongitude(60.10F); weather.setTempErature(28); weather.setReportTime(new java.sql.Date(new java.util.Date() .getTime())); weatherReportDao.save(weather); System.out.println("数据保存成功"); } } private static void update() throws Exception { WeatherReport weather = new WeatherReport(); weather.setReportId(BigInteger.valueOf((long)100)); weather.setContinent(Constants.CONTINENT_ASIA); weather.setLatitude(100.20F); weather.setLongitude(100.10F); weather.setTempErature(34); weather.setReportTime(new java.sql.Date(new java.util.Date() .getTime())); weatherReportDao.update(weather); System.out.println("数据修改成功"); } private static void delete() throws Exception { WeatherReport weather = new WeatherReport(); weather.setReportId(BigInteger.valueOf((long)100)); weather.setContinent(Constants.CONTINENT_ASIA); weather.setLatitude(50.20F); weather.setLongitude(60.10F); weather.setTempErature(28); weather.setReportTime(new java.sql.Date(new java.util.Date() .getTime())); weatherReportDao.delete(weather); System.out.println("数据删除成功"); } private static void loadConfig() throws Exception { loadConfig("weatherSpring-config.xml"); } private static void loadConfig(String configFile) throws Exception { ac = (new ClassPathXmlApplicationContext(configFile)); } public static ApplicationContext getAc() { return ac; } private static void print(List<WeatherReport> weatherList) { if (null != weatherList && weatherList.size() > 0) { for (WeatherReport w : weatherList) { System.out.println("预报ID:" + w.getReportId() + "=洲" + w.getContinent()); } } } }
通过以上测试我们发现,当 Continent 为 ASIA 数据插入到了 ASIA 数据库中,当Continent 为 AFRICA 数据插入到了AFRICA数据库中,同时我们在查询的时候可以查询所有的数
据,查询所有的数据在这里不建议使用,我在这里提供了findByContinent按洲查询,这样就只会读取相关洲的数据库,而避免了在读取相应洲的数据时排描所有洲的数据,增加了
应用程序的读写效率,这样对于一个大型应中,数据量大的应用是一个非常适用的一个选择。
但使用切分不足的时一定要确定应用程序的规模和数据增长量,对于一般中小型应用不建议使用横向切分,因为横向切分会带来应用的开发成本和资源成本,当应用需要改变会增加维护成本,并且需要设定应用的存储和检索的特定逻辑
需要有朋友可以下载本例程的实例代码,由于上传文件大小有限制,所以本人只上传了相应的源代码,相应的开发工具包需要读者自身下载并导入。本例程的代码本人都经过测试并成功运行,如有问题可加:63267818 群进行讨论
本例程参考文摘:
Hibernate Shards:http://docs.jboss.org/hibernate/shards/3.0/reference/en/html_single/
Hibernate Shards API Documentation
http://docs.jboss.org/hibernate/stable/shards/api/
http://www.cnblogs.com/RicCC/archive/2010/04/14/hibernate-shards-3-architecture.html
- hibernateShards.zip (11.5 KB)
- 下载次数: 65
相关推荐
### Hibernate Shards中文文档知识点概览 #### 一、体系结构(Architecture) ##### 1.1 概述 ...通过对本文档的深入研究,开发者可以更好地理解如何利用`Hibernate Shards`的功能来构建高性能的应用程序。
《Hibernate Shards:分布式数据库解决方案》 Hibernate Shards是...综上所述,Hibernate Shards是解决大规模数据存储问题的有效工具,但使用时需要权衡其带来的复杂性和性能提升,以便在实际项目中做出最佳决策。
在hibernate-shards-3.0.0.Beta2版本中,我们可以看到Hibernate Shards对数据分片策略的进一步优化和完善。 一、Hibernate Shards概述 Hibernate Shards的核心思想是将一个大型数据库分为多个较小的部分,这些部分...
本文档提供了关于数据库切分、Hibernate Shards 和 Java 开发 2.0 的详细信息,涵盖了数据库性能、可扩展性、关系数据库、NoSQL 数据库、数据存储技术、数据库管理、数据查询、数据一致性和数据安全等方面。
3. **Sharded Session**:这是Hibernate Shards对标准Hibernate Session的扩展,它在操作数据时会自动选择正确的shard进行操作。 4. **透明性**:尽管数据分布在不同的shards上,但对开发者来说,操作方式与单个...
MyBatis Shards在实现方式上完全借鉴于Hibernate Shards,目前可以认为是Hibernate Shards的一个迁移版本。 MyBatis Shards概述 MyBatis Shards采用无侵入性的方式,无需更改现有程序代码,只要根据现有业务编写...
MyBatis Shards在实现方式上完全借鉴于Hibernate Shards,目前可以认为是Hibernate Shards的一个迁移版本。 MyBatis Shards概述 MyBatis Shards采用无侵入性的方式,无需更改现有程序代码,只要根据现有业务编写合理...
Hibernate Shards则为大规模数据的分布式存储提供了数据库分区的支持,以实现负载均衡。尽管Hibernate最初是为Java平台设计的,但Nhibernate是其.NET平台的对应版本。 在使用Hibernate时,需要依赖一系列库文件,...
4. Hibernate Shards:水平数据分区框架,用于分布式数据库管理。 5. Hibernate Validator:数据完整性和验证API。 6. Hibernate Search:与Lucene集成,用于索引和查询数据。 7. Hibernate Tools:为Eclipse和Ant...
Hibernate Annotations支持使用Java注解进行对象-关系映射;Hibernate EntityManager是JPA规范的一部分,而Hibernate Validator则用于校验对象的属性。 为了开始使用Hibernate,首先需要从官网www.hibernate.org...
最后,可能会涉及一些进阶话题,比如Hibernate与JPA的比较、Shards和多数据源配置,以及如何在分布式环境中使用Hibernate等。 总的来说,《Hibernate深入浅出》是一本覆盖了Hibernate各个方面知识的全面指南,无论...
同时,Shards也考虑了性能优化,例如使用GZIP压缩和最小化CSS与JavaScript文件,减少页面加载时间。 【文件名称列表】DesignRevision-shards-ui-4313ce3 这个文件名可能代表的是Shards UI工具包的一个版本迭代,...
通过提供强大的数据持久化服务,Hibernate能够将对象模型与关系型数据库的数据结构进行高效转换。这使得开发人员能够更专注于业务逻辑而不是复杂的SQL语句编写。 #### Hibernate不同组件版本概览 根据提供的信息,...
使用ShardsVue进行开发时,你需要了解Vue.js的基本概念,如组件、指令、生命周期钩子等。同时,熟悉Bootstrap的基础知识也会有所帮助,因为ShardsVue的许多样式和组件都是基于Bootstrap设计的。 在下载的...
该补丁的文件名"Mirror.The.Lost.Shards.Update.v3.10"直接反映了其核心内容,即对《魔镜:失落碎片》的v3.10版本进行更新。从命名来看,我们可以推测这个更新可能包含了对游戏性能的优化、bug修复以及新内容的添加...
Hibernate分片 用于演示Hibernate分片的示例项目。 hibernate1.cfg.xml文件的第一个碎片 hibernate2.cfg.xml用于第二个分片 应用程序脱机启动共享ID生成,分片选择和分片解析策略。 在构建项目之前执行maven-...
这涉及到对数据的清洗、校验以及标准化等一系列过程,以保证最终数据集的准确性和可靠性。 - **数据质量控制措施:** - 建立数据验证机制,确保数据一致性与完整性。 - 实施数据标准化流程,统一数据格式与命名...