以前的项目用的是SSH 而且都版本较老 嵌入activiti升级了很多jar. 遇到了很多麻烦的问题. activiti内置的ORM是MYBATIES 我们项目用的HIbernate 想去更换Activiti和本项目内的ORM显然不可能. 于是就把他们的Execution和task映射成了 配置文件.现在最让人头痛的就是以前的查询都是用HIbernate Criteria写的.废话不多说了.
我们引入activiti的初衷是为了解决一个数据大问题. 比如从1000W条数据取状态为新增的业务数据,这很没效率,查询超慢.于是就想这么做.
select b.* from Executioin e left join Task t on t.execution_id = e.id left join business b on b.id = t.business_key where ..... 这样以Execution做为主表链接效率会高很多.因为Execution表比较小.
现在问题来了 就是 Hibenate Criteria查询 实现上边的语句.
1. 首先我们要有 Execution 和task的HIbernate配置文件和实体类,自己做一下
然后Execution内需要有一个一对一的关系.和一个业务表的多对一关系
<one-to-one name="task" cascade="all" property-ref="executionId" /> -- 这是双向的
<many-to-one name="business1" column="BUSINESS_KEY_" unique="true"></many-to-one> 这个是单项的
这样做的话就是 如果你有很多业务对象套在Execution里 就还需要用Criteria查 就必须再在这里多配置一个business2. 当然都是懒加载的 这里是一个梗.
2. 使用Hibernate的criteria
Criteria criteria = protocolDetailsDao.createCriteria(Execution.class,"exe");
criteria.createAlias("business1", "_this");
criteria.createAlias("task", "task");
产生的语句为
select
*
from
( select
*****
from
ACT_RU_EXECUTION this_
inner join
ACT_RU_TASK task2_
on this_.ID_=task2_.EXECUTION_ID_
inner join
Business this1_
on this_.BUSINESS_KEY_=this1_.ID
where .....
跟预想的差不多 以小表为主。
3. 返回结果集
我希望他只返回Business,可是他并没有找到Criteria 的配置方法. 这里我遇到了分页的问题.
如果criteria .list() 返回的是Execution对象 里边包含有Business和Task对象,这样可以接受,可是如果分页的时候
int totalProperty = (Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
他的结果集会变成[task,business,execution] 这样的数组形式返回,这也不是我想要的所以可以在上边代码后边加上
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
4. 封装业务对象返回数据
从Execution内取出Business对象返回。
如果有更好的方法请多多指教.