- 浏览: 572753 次
- 性别:
- 来自: 杭州
-
文章分类
- 全部博客 (478)
- lucene (45)
- oracle (19)
- nutch (2)
- blog (2)
- 垂直搜索 (19)
- java综合 (89)
- spring (15)
- Hibernate (9)
- Struts (9)
- Hadoop (16)
- Mysql (12)
- nosql (10)
- Linux (3)
- MyEclipse (4)
- Ant (1)
- 设计模式 (19)
- JBPM (1)
- JSP (1)
- HtmlParser (5)
- SVN (2)
- 插件 (2)
- 收藏 (7)
- Others (1)
- Heritrix (18)
- Solr (4)
- 主题爬虫 (31)
- 内存数据库 (24)
- 分布式与海量数据 (32)
- httpclient (14)
- Tomcat (1)
- 面试宝典 (6)
- Python (14)
- 数据挖掘 (1)
- 算法 (6)
- 其他 (4)
- JVM (12)
- Redis (18)
最新评论
-
hanjiyun:
本人水平还有待提高,进步空间很大,看这些文章给我有很大的指导作 ...
JVM的内存管理 Ⅲ -
liuxinglanyue:
四年后的自己:这种方法 不靠谱。 使用javaagent的方式 ...
计算Java对象占用内存空间的大小(对于32位虚拟机而言) -
jaysoncn:
附件在哪里啊test.NoCertificationHttps ...
使用HttpClient过程中常见的一些问题 -
231fuchenxi:
你好,有redis,memlink,mysql的测试代码吗?可 ...
MemLink 性能测试 -
guyue1015:
[color=orange][/color][size=lar ...
JAVA同步机制
HQL看起来和SQL很相似。从HQL的WHERE子句中通常可以猜到相应的SQL WHERE子句。WHERE子句中的字段决定了数据库将选择的索引。 大多数Hibernate开发者所常犯的一个错误是无论何时,当需要新WHERE子句的时候都会创建一个新的索引。因为索引会带来额外的数据更新开销,所以应该争取创建少量索引来覆盖尽可能多的查询。 范例7 有两个UI搜索器和一个后端守护进程搜索器来搜索名为iso_deals的表。第一个UI搜索器在unexpectedFlag、dealStatus、tradeDate和isold属性上有谓语。 第二个UI搜索器基于用户键入的过滤器,其中包括的内容除tradeDate和isold以外还有其他属性。开始时所有这些过滤器属性都是可选的。 鉴于这一点,我们依次使用unexpectedFlag、dealStatus、tradeDate和isold构造了一个复合索引。两个UI搜索器都能共用它。(顺序很重要,如果你的谓语以不同的顺序指定这些属性或在它们前罗列了其他属性,数据库就不会选择该复合索引。) 后端搜索器和UI搜索器区别太大,因此我们不得不为它构造另一个复合索引,依次使用isold、participantCode和transactionType。 既可以使用绑定参数构造HQL的WHERE子句,也可以使用字符串拼接的方法,该决定对性能会有一定影响。使用绑定参数的原因是让数据库一次解析SQL,对后续的重复请求复用生成好的执行计划,这样做节省了CPU时间和内存。然而,为达到最优的数据访问效率,不同的绑定值可能需要不同的SQL执行计划。 例如,一小段数据范围可能只返回数据总量的5%,而一大段数据范围可能返回数据总量的90%。前者使用索引更好,而后者则最好使用全表扫描。 建议OLTP使用绑定参数,数据仓库使用字符串拼接,因为OLTP通常在一个事务中重复插入和更新数据,只取少量数据;数据仓库通常只有少量SQL查询,有一个确定的执行计划比节省CPU时间和内存更为重要。 要是你知道你的OLTP搜索对不同绑定值应该使用相同执行计划又该怎么办呢? Oracle 9i及以后版本在第一次调用绑定参数并生成执行计划时能探出参数值。后续调用不会再探测,而是重用之前的执行计划。 你可以在数据库中进行聚合和“order by”,也可以在应用程序的服务层中事先加载所有数据然后做聚合和“order by”操作。推荐使用前者,因为数据库在这方面通常会比你的应用程序做得好。此外,这样做还能节省网络带宽,这也是一种拥有跨数据库移植性的做法。 当你的应用程序对数据聚合和排序有HQL不支持的特定业务规则时除外。 详见4.7.1节。 本地查询调优其实并不直接与HQL有关。但HQL的确可以让你直接向底层数据库传递本地查询。我们并不建议这么做,因为本地查询在数据库间不可移植。 抓取策略决定了在应用程序需要访问关联对象时,Hibernate以何种方式以及何时获取关联对象。HRD中的第20章“改善性能”对该主题作了很好的阐述,我们在此将关注它的使用方法。 不同的用户可能会有不同的数据抓取要求。Hibernate允许在两个地方定义数据抓取策略,一处是在映射元数据中,另一处是在HQL或Criteria中覆盖它。 常见的做法是基于主要的抓取用例在映射元数据中定义默认抓取策略,针对少数用例在HQL和Criteria中覆盖抓取策略。 假设pojoA和pojoB是父子关系实例。如果根据业务规则,只是偶尔需要从实体两端加载数据,那你可以声明一个延迟加载集合或代理抓取(proxy fetching)。当你需要从实体两端获取数据时,可以用立即抓取(eager fetching)覆盖默认策略,例如使用HQL或Criteria配置连接抓取(join fetching)。 另一方面,如果业务规则在大多数时候需要从实体两端加载数据,那么你可以声明立即抓取并在Criteria中设置延迟加载集合或代理抓取来覆盖它(HQL目前还不支持这样的覆盖)。 select抓取会导致N+1问题。如果你知道自己总是需要从关联中加载数据,那么就该始终使用连接抓取。在下面两个场景中,你可能会把N+1视为一种模式而非反模式。 第一种场景,你不知道用户是否会访问关联对象。如果他/她没有访问,那么你赢了;否则你仍然需要额外的N次select SQL语句。这是一种令人左右为难的局面。 第二种场景,pojoA和很多其他POJO有one-to-many关联,例如pojoB和pojoC。使用立即的内连接或外连接抓取会在结果集中将pojoA重复很多次。当pojoA中有很多非空属性时,你不得不将大量数据加载到持久层中。这种加载需要很多时间,既有网络带宽的原因,如果Hibernate的会话是有状态的,其中也会有会话缓存的原因(内存消耗和GC暂停)。 如果你有一个很长的one-to-many关联链,例如从pojoA到pojoB到pojoC以此类推,情况也是类似的。 你也许会去使用HQL中的DISTINCT关键字或Cirteria中的distinct功能或是Java的Set接口来消除重复数据。但所有这些都是在Hibernate(在持久层)中实现的,而非数据库中。 如果基于你的网络和内存配置的测试表明N+1性能更好,那么你可以使用批量抓取、subselect抓取或二级缓存来做进一步调优。 范例8 以下是一个使用批量抓取的HBM文件片段: 以下是多端pojoB生成的SQL: 问号数量与batch-size值相等。因此N次额外的关于pojoB的select SQL语句被减少到了N/10次。 如果将fetch="select"替换成fetch="subselect",pojoB生成的SQL语句就是这样的: 尽管N次额外的select减少到1次,但这只在重复运行pojoA的查询开销很低时才有好处。 如果pojoA中的pojoB集合很稳定,或pojoB有pojoA的many-to-one关联,而且pojoA是只读引用数据,那么你可以使用二级缓存来缓存pojoA以消除N+1问题(4.8.1节中有一个例子)。 除非有一张拥有很多你不需要的字段的遗留表,否则不应该使用这种抓取策略,因为它的延迟属性分组会带来额外的SQL。 在业务分析和设计过程中,你应该将不同数据获取或修改分组放到不同的领域对象实体中,而不是使用这种抓取策略。 如果不能重新设计遗留表,可以使用HQL或Criteria提供的投影功能来获取数据。 HRD第20.2节 “二级缓存”中的描述对大多数开发者来说过于简单,无法做出选择。3.3版及以后版本不再推荐使用基于“CacheProvider”的缓存,而用基于“RegionFactory”的缓存,这也让人更糊涂了。但是就算是最新的3.5参考文档也没有提及如何使用新缓存方法。 出于下述考虑,我们将继续关注于老方法: 理解该机制是做出合理选择的关键。关键的类/接口是CacheConcurrencyStrategy和它针对4中不同缓存使用的实现类,还有EntityUpdate/Delete/InsertAction。 针对并发缓存访问,有三种实现模式: 无论是锁还是事务都没影响,因为缓存自数据从数据库加载后就不会改变。 对缓存的更新发生在数据库事务完成后。缓存需要支持锁。 对缓存和数据库的更新被包装在同一个JTA事务中,这样缓存与数据库总是保持同步的。数据库和缓存都必须支持JTA。尽管缓存事务内部依赖于缓存锁,但Hibernate不会显式调用任何的缓存锁函数。 以数据库更新为例。EntityUpdateAction对于事务感知读写、“read-write”的非事务感知读写,还有“nonstrict-read-write”的非事务感知读写相应有如下调用序列: 软锁只是一种特定的缓存值失效表述方式,在它获得新数据库值前阻止其他事务读写缓存。那些事务会转而直接读取数据库。 缓存必须支持锁;事务支持则不是必须的。如果缓存是一个集群,“更新缓存”的调用会将新值推送给所有副本,这通常被称为“推(push)”更新策略。 既不需要支持缓存锁,也不需要支持事务。如果是缓存集群,“清除缓存”调用会让所有副本都失效,这通常被称为“拉(pull)”更新策略。 对于实体的删除或插入动作,或者集合变更,调用序列都是相似的。 实际上,最后两个异步调用序列仍能保证数据库和缓存的一致性(基本就是“read committed”的隔离了级别),这要归功于第二个序列中的软锁和“更新数据库”后的“更新缓存”,还有最后一个调用序列中的悲观“清除缓存”。 基于上述分析,我们的建议是: 依笔者看来,二级缓存并非一级数据源,因此使用JTA也未必合理。实际上最后两个调用序列在大多数场景下是个不错的替代方案,这要归功于它们的数据一致性保障。 范例9 以下是一个ISO收费类型的HBM文件片段: 一些用户只需要ISO收费类型本身;一些用户既需要ISO收费类型,还需要它的三个关联对象。简单起见,开发者会立即加载所有三个关联对象。如果项目中没人负责Hibernate调优,这是很常见的。 4.7.1节中讲过了最好的方法。因为所有的关联对象都是只读引用数据,另一种方法是使用延迟抓取,打开这些对象的二级缓存以避免N+1问题。实际上前一种方法也能从引用数据缓存中获益。 因为大多数项目都有很多被其他数据引用的只读引用数据,上述两种方法都能改善全局系统性能。 下表是新老两种方法中对应的主要类/接口: 新方法 老方法 RegionFactory CacheProvider Region Cache EntityRegionAccessStrategy CacheConcurrencyStrategy CollectionRegionAccessStrategy CacheConcurrencyStrategy 第一个改进是RegionFactory构建了特定的Region,例如EntityRegion和TransactionRegion,而不是使用一个通用的访问Region。第二个改进是对于特定缓存的“usage”属性值,Region要求构建自己的访问策略,而不是所有Region都一直使用CacheConcurrencyStrategy的4种实现。 要使用新方法,应该设置factory_class而非provider_class配置属性。以Ehcache 2.0为例: 其他相关的Hibernate缓存配置都和老方法一样。 新方法也能向后兼容遗留方法。如果还是只配了CacheProvider,新方法中将使用下列自说明(self-explanatory)适配器和桥隐式地调用老的接口/类: RegionFactoryCacheProviderBridge、EntityRegionAdapter、CollectionRegionAdapter、QueryResultsRegionAdapter、EntityAccessStrategyAdapter和CollectionAccessStrategyAdapter 二级缓存也能缓存查询结果。如果查询开销很大而且要重复运行,这也会很有帮助。 大多数Hibernate的功能都很适合那些每个事务都通常只处理少量数据的OLTP系统。但是,如果你有一个数据仓库或者事务需要处理大量数据,那么就另当别论了。 如果你已经在使用常规会话了,那这是最自然的方法。你需要做三件事: batch_size设置为正值会开启JDBC2的批量更新,Hibernate的建议值是5到30。基于我们的测试,极低值和极高值性能都很差。只要取值在合理范围内,区别就只有几秒而已。如果网络够快,这个结果是一定的。 第二个配置设为true,这要求JDBC驱动在executeBatch()方法中返回正确的行数。对于Oracle用户而言,批量更新时不能将其设为true。请阅读Oracle的《JDBC Developer’s Guide and Reference》中的“标准批处理的Oracle实现中的更新计数”(Update Counts in the Oracle Implementation of Standard Batching)以获得更多详细信息。因为它对批量插入来说还是安全的,所以你可以为批量插入创建单独的专用数据源。最后一个配置项是可选的,因为你可以在会话中显式关闭二级缓存。 for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
//if your hibernate.cache.use_second_level_cache is true, call the following:
session.setCacheMode(CacheMode.IGNORE);
session.save(customer);
if (i % 50 == 0) { //50, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close(); 批处理通常不需要数据缓存,否则你会将内存耗尽并大量增加GC开销。如果内存有限,那这种情况会很明显。 每次事务修改的对象数量越少就意味着会有更多数据库提交,正如4.5节所述每次提交都会带来磁盘相关的开销。 另一方面,每次事务修改的对象数量越多就意味着锁定变更时间越长,同时数据库需要更大的redo log。 无状态会话执行起来比上一种方法更好,因为它只是JDBC的简单包装,而且可以绕开很多常规会话要求的操作。例如,它不需要会话缓存,也不和任何二级缓存或查询缓存有交互。 使用DML风格的插入、更新或删除,你直接在数据库中操作数据,这和前两种方法在Hibernate中操作数据的情况有所不同。 因为一个DML风格的更新或删除相当于前两种方法中的多个单独的更新或删除,所以如果更新或删除中的WHERE子句暗示了恰当的数据库索引,那么使用DML风格的操作能节省网络开销,执行得更好。 强烈建议结合使用DML风格操作和无状态会话。如果使用有状态会话,不要忘记在执行DML前清除缓存,否则Hibernate将会更新或清除相关缓存(见下面的范例10)。 如果你的HQL或Criteria会返回很多数据,那么要注意两件事: fetch_size设置为正值将开启JDBC批量抓取特性。相对快速网络,在慢速网络中这一点更为重要。Oracle建议的经验值是10。你应该基于自己的环境进行测试。 范例10 我们有一个后台任务,分段加载大量的IsoDeal数据用于后续处理。我们还会在分段数据交给下游系统处理前将其更新为处理中状态。最大的一段有50万行数据。以下是原始代码中截取出来的一段: 包含上述代码的方法加上了Spring 2.5声明式事务的注解。加载并更新50万行数据大约花了10分钟。我们识别出了以下这些问题: 不幸的是Spring 2.5不支持Hibernate无状态会话,所以我们只能关闭二级缓存;设置fetch_size;用DML风格的更新来代替for循环,以此改善性能。 但是,执行时间还是要6分钟。将Hibernate的日志级别调成trace后,我们发现是更新会话缓存造成了延时。通过在DML更新前清除会话缓存,我们将时间缩短到了4分钟,全部都是将数据加载到会话缓存中花费的时间。 本节将向你展示如何减少SQL生成的数量。 “select抓取”策略会导致N+1问题。如果“连接抓取”策略适合你的话,你应该始终使用该策略避免N+1问题。 但是,如果“连接抓取”策略执行效果不理想,就像4.7.2节中那样,你可以使用“subselect抓取”、“批量抓取”或“延迟集合抓取”来减少所需的额外SQL语句数。 范例11 我们的ElectricityDeal与DealCharge有单向one-to-many关联,如下列HBM文件片段所示: 在“key”元素中,“not-null”和“update”对应的默认值是false和true,上述代码为了明确这些取值,将它们写了出来。 如果你想创建一个ElectricityDeal和十个DealCharge,会生成如下SQL语句: 为了消除那额外的10句更新语句,可以在那10句DealCharge插入语句中包含“DEAL_KEY”,你需要将“not-null”和“update”分别修改为true和false。 另一种做法是使用双向或many-to-one关联,让DealCharge来管理关联。 在范例11中,我们为ElectricityDeal加上了select-before-update,这会对瞬时(transient)对象或分离(detached)对象产生额外的select语句,但却能避免不必要的数据库更新。 你应该做出一些权衡,如果对象没多少属性,不需要防止不必要的数据库更新,那么就不要使用该特性,因为你那些有限的数据既没有太多网络传输开销,也不会带来太多数据库更新开销。 如果对象的属性较多,例如是一张大的遗留表,那你应该开启该特性,和“dynamic-update”结合使用以避免太多数据库更新开销。 在范例11中,如果你想删除1个ElectricityDeal和它的100个DealCharge,Hibernate会对DealCharge做100次删除。 如果将“on-delete”修改为“cascade”,Hibernate不会执行DealCharge的删除动作;而是让数据库根据ON CASCADE DELETE约束自动删除那100个DealCharge。不过,需要让DBA开启ON CASCADE DELETE约束,大多数DBA不愿意这么做,因为他们想避免父对象的意外删除级联到它的依赖对象上。此外,还要注意,该特性会绕过Hibernate对版本数据(versioned data)的常用乐观锁策略。 范例11中使用Oracle的序列作为标识符生成器。假设我们保存100个ElectricityDeal,Hibernate会将下面的SQL语句执行100次来获取下一个可用的标识符: 如果网络不是很快,那这无疑会降低效率。3.2.3及后续版本中增加了一个增强的生成器“SequenceStyleGenerator”,它带了两个优化器:hilo和pooled。尽管HRD的第5章“基础O/R映射” 讲到了这两个优化器,不过内容有限。两个优化器都使用了HiLo算法,该算法生成的标识符等于Hi值加上Lo值,其中Hi值代表组号,Lo值顺序且重复地从1迭代到最大组大小,组号在Lo值“转回到”1时加1。 假设组大小是5(可以用max_lo或increment_size参数来表示),下面是个例子: 组号取自数据库序列的下一个可用值,Hi值由Hibernate定义,是组号乘以increment_size参数值。 Hi值直接取自数据库序列的下一个可用值。数据库序列的增量应该设置为increment_size参数值。 直到内存组中的值耗尽后,两个优化器才会去访问数据库,上面的例子每5个标识值符访问一次数据库。使用hilo优化器时,你的序列不能再被其他应用程序使用,除非它们使用与Hibernate相同的逻辑。使用pooled优化器,在其他应用程序使用同一序列时则相当安全。 两个优化器都有一个问题,如果Hibernate崩溃,当前组内的一些标识符值就会丢失,然而大多数应用程序都不要求拥有连续的标识符值(如果你的数据库,比方说Oracle,缓存了序列值,当它崩溃时你也会丢失标识符值)。 如果在范例11中使用pooled优化器,新的id配置如下: 本文涵盖了大多数你在Hibernate应用程序调优时会觉得很有用的调优技巧,其中的大多数时间都在讨论那些行之有效却缺乏文档的调优主题,例如继承映射、二级缓存和增强的序列标识符生成器。 它还提到了一些Hibernate调优所必需的数据库知识。一些范例中包含了你可能遇到的问题的实际解决方案。 除此之外,值得一提的是Hibernate也可以和In-Memory Data Grid(IMDG)一起使用,例如Oracle的Coherance或GigaSpaces IMDG,这能让你的应用程序达到毫秒级别。 [1] Latest Hibernate Reference Documentation on jboss.com [2] Oracle 9i Performance Tuning Guide and Reference [3] Performance Engineering on Wikipedia [4] Program Optimization on Wikipedia [5] Pareto Principle (the 80/20 rule) on Wikipedia [6] Premature Optimization on acm.org [7] Java Performance Tuning by Jack Shirazi [8] The Law of Leaky Abstractions by Joel Spolsky [9] Hibernate’s StatisticsService Mbean configuration with Spring [11] Java VisualVM [12] Column-oriented DBMS on Wikipedia [13] Apache DBCP BasicDataSource [14] JDBC Connection Pool by Oracle [15] Connection Failover by Oracle [16] Last Resource Commit Optimization (LRCO) [17] GigaSpaces for Hibernate ORM Users Yongjun Jiao是SunGard Consulting Services的技术主管。过去10年中他一直是专业软件开发者,他的专长包括Java SE、Java EE、Oracle和应用程序调优。他最近的关注点是高性能计算,包括内存数据网格、并行计算和网格计算。 Stewart Clark是SunGard Consulting Services的负责人。过去15年中他一直是专业软件开发者和项目经理,他的专长包括Java核心编程、Oracle和能源交易。4.6 HQL调优
4.6.1 索引调优
4.1节让你使用一个集合来处理所有可能的数据搜索条件。如果这不太实际,那么你可以使用后端剖析工具来创建一个针对应用程序涉及的所有SQL的集合。基于那些搜索条件的分类,你最终会得到一个小的索引集。与此同时,还可以尝试向WHERE子句中添加额外的谓语来匹配其他WHERE子句。
后端搜索器基于isold、participantCode和transactionType属性。
经过进一步业务分析,发现第二个UI搜索器实际是基于一些隐式的unexpectedFlag和dealStatus值来选择数据的。我们还让tradeDate成为过滤器的必要属性(为了使用数据库索引,每个搜索过滤器都应该有必要属性)。4.6.2绑定参数 vs.字符串拼接
4.6.3聚合及排序
4.6.4覆盖抓取策略
4.6.5本地查询
4.7抓取策略调优
4.7.1覆盖抓取策略
4.7.2 N+1模式或是反模式?
<class name="pojoA" table="pojoA">
…
<set name="pojoBs" fetch="select" batch-size="10">
<key column="pojoa_id"/>
…
</set>
</class>
select … from pojoB where pojoa_id in(?,?,?,?,?, ?,?,?,?,?);
select … from pojoB where pojoa_id in(select id from pojoA where …);
4.7.3延迟属性抓取
4.8 二级缓存调优
4.8.1 基于CacheProvider的缓存机制
<class name="IsoChargeType">
<property name="isoId" column="ISO_ID" not-null="true"/>
<many-to-one name="estimateMethod" fetch="join" lazy="false"/>
<many-to-one name="allocationMethod" fetch="join" lazy="false"/>
<many-to-one name="chargeTypeCategory" fetch="join" lazy="false"/>
</class>
4.8.2 RegionFactory
<property name="hibernate.cache.region.factory_class">
net.sf.ehcache.hibernate.EhCacheRegionFactory
</property>
4.8.3 查询缓存
4.9批量处理调优
4.9.1使用有状态会话的非DML风格批处理
hibernate.jdbc.batch_size 30
hibernate.jdbc.batch_versioned_data true
hibernate.cache.use_second_level_cache false
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
4.9.2使用无状态会话的非DML风格批处理
然而它的用法并不简单。尤其是它的操作并不会级联到所关联的实例上;你必须自己来处理它们。4.9.3 DML风格
4.9.4批量加载
hibernate.jdbc.fetch_size 10
Query query = session.createQuery("FROM IsoDeal d WHERE chunk-clause");
query.setLockMode("d", LockMode.UPGRADE); //for Inprocess status update
List<IsoDeal> isoDeals = query.list();
for (IsoDeal isoDeal : isoDeals) { //update status to Inprocess
isoDeal.setStatus("Inprocess");
}
return isoDeals;
4.10 SQL生成调优
4.10.1 N+1抓取问题
4.10.2 Insert+Update问题
<class name="ElectricityDeal"
select-before-update="true" dynamic-update="true"
dynamic-insert="true">
<id name="key" column="ID">
<generator class="sequence">
<param name="sequence">SEQ_ELECTRICITY_DEALS</param>
</generator>
</id>
…
<set name="dealCharges" cascade="all-delete-orphan">
<key column="DEAL_KEY" not-null="false" update="true"
on-delete="noaction"/>
<one-to-many class="DealCharge"/>
</set> </class>
4.10.3 更新前执行select
4.10.4 级联删除
4.10.5 增强的序列标识符生成器
select SEQ_ELECTRICITY_DEALS.NEXTVAL from dual;
<id name="key" column="ID">
<generator class="org.hibernate.id.enhance.SequenceStyleGenerator">
<param name="sequence_name">SEQ_ELECTRICITY_DEALS</param>
<param name="initial_value">0</param>
<param name="increment_size">100</param>
<param name="optimizer ">pooled</param>
</generator>
</id>
5 总结
6 资源
关于作者
发表评论
-
Hibernate源代码分析之大纲
2010-12-03 22:02 1758大致的源代码包 1. org.hibernat ... -
Hibernate源码分析
2010-12-03 21:43 1264转:http://blog.csdn.net/idearfly ... -
浅谈Hibernate的flush机制
2010-11-30 22:14 752随着Hibernate在Java开发中的广泛应用,我们在使用H ... -
Hibernate---延迟加载和OpenSessionInView
2010-11-15 15:37 976Hibernate与延迟加载: Hib ... -
Hibernate二级缓存(转)
2010-11-15 15:36 951这两天优化一个模块,那模块的问题是有时用户量访问量大时就慢了, ... -
HibernateDaoSupport和 HibernateTemplate的选择问题!
2010-11-14 13:14 1378今天学习了一个spring和Hibernate访问Dao, ... -
加速你的Hibernate引擎(上)
2010-11-13 12:11 10121.引言 Hibernate是最流行的对象关系映射(OR ... -
hibernate配置数据库连接池的三种方法(转)
2010-11-12 21:49 694三种连接都是以连接MySQl为例。 <!-- JDBC驱 ...
相关推荐
内容概要:本文详细介绍了基于MATLAB GUI界面和卷积神经网络(CNN)的模糊车牌识别系统。该系统旨在解决现实中车牌因模糊不清导致识别困难的问题。文中阐述了整个流程的关键步骤,包括图像的模糊还原、灰度化、阈值化、边缘检测、孔洞填充、形态学操作、滤波操作、车牌定位、字符分割以及最终的字符识别。通过使用维纳滤波或最小二乘法约束滤波进行模糊还原,再利用CNN的强大特征提取能力完成字符分类。此外,还特别强调了MATLAB GUI界面的设计,使得用户能直观便捷地操作整个系统。 适合人群:对图像处理和深度学习感兴趣的科研人员、高校学生及从事相关领域的工程师。 使用场景及目标:适用于交通管理、智能停车场等领域,用于提升车牌识别的准确性和效率,特别是在面对模糊车牌时的表现。 其他说明:文中提供了部分关键代码片段作为参考,并对实验结果进行了详细的分析,展示了系统在不同环境下的表现情况及其潜在的应用前景。
嵌入式八股文面试题库资料知识宝典-计算机专业试题.zip
嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_3.zip
内容概要:本文深入探讨了一款额定功率为4kW的开关磁阻电机,详细介绍了其性能参数如额定功率、转速、效率、输出转矩和脉动率等。同时,文章还展示了利用RMxprt、Maxwell 2D和3D模型对该电机进行仿真的方法和技术,通过外电路分析进一步研究其电气性能和动态响应特性。最后,文章提供了基于RMxprt模型的MATLAB仿真代码示例,帮助读者理解电机的工作原理及其性能特点。 适合人群:从事电机设计、工业自动化领域的工程师和技术人员,尤其是对开关磁阻电机感兴趣的科研工作者。 使用场景及目标:适用于希望深入了解开关磁阻电机特性和建模技术的研究人员,在新产品开发或现有产品改进时作为参考资料。 其他说明:文中提供的代码示例仅用于演示目的,实际操作时需根据所用软件的具体情况进行适当修改。
少儿编程scratch项目源代码文件案例素材-剑客冲刺.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 转瞬即逝.zip
内容概要:本文详细介绍了基于PID控制器的四象限直流电机速度驱动控制系统仿真模型及其永磁直流电机(PMDC)转速控制模型。首先阐述了PID控制器的工作原理,即通过对系统误差的比例、积分和微分运算来调整电机的驱动信号,从而实现转速的精确控制。接着讨论了如何利用PID控制器使有刷PMDC电机在四个象限中精确跟踪参考速度,并展示了仿真模型在应对快速负载扰动时的有效性和稳定性。最后,提供了Simulink仿真模型和详细的Word模型说明文档,帮助读者理解和调整PID控制器参数,以达到最佳控制效果。 适合人群:从事电力电子与电机控制领域的研究人员和技术人员,尤其是对四象限直流电机速度驱动控制系统感兴趣的读者。 使用场景及目标:适用于需要深入了解和掌握四象限直流电机速度驱动控制系统设计与实现的研究人员和技术人员。目标是在实际项目中能够运用PID控制器实现电机转速的精确控制,并提高系统的稳定性和抗干扰能力。 其他说明:文中引用了多篇相关领域的权威文献,确保了理论依据的可靠性和实用性。此外,提供的Simulink模型和Word文档有助于读者更好地理解和实践所介绍的内容。
嵌入式八股文面试题库资料知识宝典-2013年海康威视校园招聘嵌入式开发笔试题.zip
少儿编程scratch项目源代码文件案例素材-驾驶通关.zip
小区开放对周边道路通行能力影响的研究.pdf
内容概要:本文探讨了冷链物流车辆路径优化问题,特别是如何通过NSGA-2遗传算法和软硬时间窗策略来实现高效、环保和高客户满意度的路径规划。文中介绍了冷链物流的特点及其重要性,提出了软时间窗概念,允许一定的配送时间弹性,同时考虑碳排放成本,以达到绿色物流的目的。此外,还讨论了如何将客户满意度作为路径优化的重要评价标准之一。最后,通过一段简化的Python代码展示了遗传算法的应用。 适合人群:从事物流管理、冷链物流运营的专业人士,以及对遗传算法和路径优化感兴趣的科研人员和技术开发者。 使用场景及目标:适用于冷链物流企业,旨在优化配送路线,降低运营成本,减少碳排放,提升客户满意度。目标是帮助企业实现绿色、高效的物流配送系统。 其他说明:文中提供的代码仅为示意,实际应用需根据具体情况调整参数设置和模型构建。
少儿编程scratch项目源代码文件案例素材-恐怖矿井.zip
内容概要:本文详细介绍了基于STM32F030的无刷电机控制方案,重点在于高压FOC(磁场定向控制)技术和滑膜无感FOC的应用。该方案实现了过载、过欠压、堵转等多种保护机制,并提供了完整的源码、原理图和PCB设计。文中展示了关键代码片段,如滑膜观测器和电流环处理,以及保护机制的具体实现方法。此外,还提到了方案的移植要点和实际测试效果,确保系统的稳定性和高效性。 适合人群:嵌入式系统开发者、电机控制系统工程师、硬件工程师。 使用场景及目标:适用于需要高性能无刷电机控制的应用场景,如工业自动化设备、无人机、电动工具等。目标是提供一种成熟的、经过验证的无刷电机控制方案,帮助开发者快速实现并优化电机控制性能。 其他说明:提供的资料包括详细的原理图、PCB设计文件、源码及测试视频,方便开发者进行学习和应用。
基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf
嵌入式八股文面试题库资料知识宝典-CC++笔试题-深圳有为(2019.2.28)1.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 V1.5.zip
Android系统开发_Linux内核配置_USB-HID设备模拟_通过root权限将Android设备转换为全功能USB键盘的项目实现_该项目需要内核支持configFS文件系统
C# WPF - LiveCharts Project
少儿编程scratch项目源代码文件案例素材-恐怖叉子 动画.zip
嵌入式八股文面试题库资料知识宝典-嵌⼊式⼯程师⾯试⾼频问题.zip