欢迎来到天天文库
浏览记录
ID:45920162
大小:90.30 KB
页数:9页
时间:2019-11-19
《J2EE应用下基于AOP的抓取策略》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、J2EE应用下基于AOP的抓取策略 如何通过最精简的SQL查询获取所需的数据很多时候这可不是轻而易举的事情默认情况下O/RMapping工具会按需加载数据除非你改变了其默认设置延迟加载行为保证了依赖的数据只有在真正请求时才会被加载进来这样就可以避免创建无谓的对象有时我们的业务并不会使用到依赖的那些组件这时延迟加载就派上用场了同时也无需加载那些用不上的组件了 典型情况下我们的业务很清楚需要些数据但由于使用了延迟加载在执行大量Select查询时数据库的性能会降低因为业务所需的数据并不是一下子获得的这样对于那些需要支持大量请求的应用来说可能会产生瓶颈(可伸缩性问题)来看个例子吧假设某
2、个业务流程想要得到一个Person及其Address信息我们将Address组件配置成延迟加载这样要想得到所需的数据就需要更多的SQL查询也就是说首先查询Person然后再查询Address这增加了数据库与应用之间的通信成本解决办法就是在一个单独的查询中将Person和Address都得到因为我们知道这两个组件都是业务流程所需的如果在DAO/Repository及底层Service开发特定于业务的FetchingAPI对于那些拥有不同数据集的相同领域对象来说我们就得编写不同的API进行抓取并组装了这么做会使Repository及底层Service过于膨胀最终变成维护的梦魇延迟抓取的另一个问
3、题就是在获取到请求的数据前要一直打开数据库连接否则应用就会抛出一个延迟加载异常说明:如果在查询中使用预先抓取来获取二级缓存中的数据时我们将无法解决上面提出的问题对于Hibernate来说如果我们使用预先抓取来获取二级缓存中的数据那么它将从数据库而不是缓存中去获取数据怕是二级缓存中已经存在该数据这就说明Hibernate也没有解决这个问题从而表明我们不应该在查询中通过预先抓取来获得二级缓存中的对象对于那些可以让我们调节查询以获取缓存对象的O/RMapping工具来说如果缓存中有对象就会从缓存中获取否则采取预先抓取的方式这就解决了上面提到的事务/DB连接问题因为在查询的执行过程中会同时获取缓存
4、中的数据而不是按需读取(也就是延迟加载)通过下面的示例代码来了解一下延迟加载所面对的问题及解决办法考虑如下场景:某领域中有3个实体分别是Employee、Department及Dependent这三个实体之间的关系如下:Employee有0或多个dependents Department有0或多个employees Employee属于0或1个department 我们要执行三个操作:获取employee的详细信息 获取employee及其dependent的详细信息 获取employee及其department的详细信息 以上三个操作需要获取并呈现不同
5、的数据使用延迟加载有如下弊端:如果对实体employee所关联的dependent和department这两个实体使用延迟加载那么在操作2和3中就会生成更多的SQL查询语句 在多个查询语句的执行过程中需要保持数据库连接否则会抛出一个延迟加载异常这将导致数据出现问题 但另一方面使用预先抓取也存在如下弊端:对employee所对应的dependents和department采取预先抓取会产生不必要的数据 无法在特定的场景下对查询进行调优 在Repository/DAO或底层服务中使用特定于操作的API可以解决上述问题但却会导致如下问题:代码膨胀——不管是Service还
6、是Repository/DAO类都无法幸免 维护的梦魇——不管是Service还是Repository/DAO层只要有新的操作都需要增加新的API 代码重复——有时底层服务需要在获取的实体上增加某些业务逻辑与之类似还要在数据返回前检查DAO/Repository层的查询响应以验证数据可用性 为了解决上面这些问题Repository/DAO层需要根据不同的业务情况执行不同的查询来获取实体就像Aspect类所定义的那样我们可以根据特定的操作使用不同的抓取机制来覆盖Repository/DAO类所定义的默认抓取模式所有的抓取模式类都实现了相同的接口 Repository类
7、使用了上述的抓取模式来执行查询如下代码所示:publicEmployeefindEmployeeById(intemployeeId){ Listemployee=hibernateTemplate.find(fetchingStrategy.queryEmployeeById(), newInteger(employeeId)); if(employee.size()==0) returnnul
此文档下载收益归作者所有