2015/4/20

周末回去想了下,hibernate、mybatis、jdbc,都行,最终定了用mybatis,谁叫它这么优雅,acvtiviti是依赖了mybatis的,就不用再引入包了;

看了配置文件,之前配置的是jpa,再配置mybatis,配置文件就显得臃肿,很乱了;用jpa吧,貌似也不赖;

再写一个Repository;

写SQL的时候用到了,知识点:

instr:instr(t.DESCRIPTION_, 'conditionCountersign') > 0

mysql查询最后一条记录,不能用orderby:

需求:要取a1的最后一条数据来关联,语句如下;

解决:不能在inner join里边用order by xxx limit 1;

折中解决:用时间来限制;a1.START_TIME_>a2.START_TIME_

select distinct RES.*, a1.ID_, a2.ID_ from ACT_HI_PROCINST RES inner join ACT_HI_ACTINST a1 on (a1.PROC_INST_ID_ = RES.PROC_INST_ID_ and a1.ACT_TYPE_ != 'endEvent')

inner join ACT_RU_TASK t on (a1.TASK_ID_=t.ID_ and instr(t.DESCRIPTION_, 'conditionCountersign') > 0)

inner join ACT_HI_ACTINST a2 on (a1.ACT_ID_=a2.ACT_ID_ and a1.START_TIME_>a2.START_TIME_ and a2.ASSIGNEE_='324')

where RES.END_TIME_ is null

and exists (select LINK.USER_ID_ from ACT_HI_IDENTITYLINK LINK where USER_ID_ = '324' and LINK.PROC_INST_ID_ = RES.ID_) order by START_TIME_ desc;

jpa映射activiti的实体,各种报错;

好麻烦,jpa要写实体,要写HQL,原来我都写好SQL了,还要转换为HQL,hibernate真麻烦;

慢慢拷贝表字段写实体,每个实体要继承原有的entity;

先写一个测试用例,跑通了再说,别连查询都查不了,就浪费时间了;贴一些主要的代码:

实体:

Repository:

测试用例:

可以哦:

那开始慢慢写实体吧,写好再改HQL;

写好了HQL,开始测试:

报错:

Caused by: java.lang.IllegalArgumentException: node to traverse cannot be null!

摸不着头脑,先精简语句,先调通上半部分的union再说;

还是一样;

问度娘;度娘说是HQL写错了,哪里错了,她也不说,真是的;

再次精简:

还是一样;

再次精简:

还是一样;

哥,多了个左括号;继续奋战;

再加SQL:

加参数,加排序,很顺利;

另一个union问题就很多,有点绝望;

换用jdbc试试;

遇到的错误:

错误代码: 1248

Every derived table must have its own alias

解决:

select count(0) as total from (xxx);后边要带别名;

select count(0) as total from (xxx) dd;

很快就写好了,原生SQL就是好;

jdbc的dao层:

    /**
* 分页查询待办工作流记录
* @param involvedUser
* @param firstResult
* @param maxResults
* @return
*/
public List<HistoricProcessInstanceEntity> qryUnfinishedByInvolvedUser(HistoricProcessInstanceQuery query){
StringBuilder sql = new StringBuilder();
sql.append(" select ");
sql.append(HistoricProcessInstanceSQLFragment.baseColumnList());
sql.append(" from (");
sql.append("(select RES.* from ACT_HI_PROCINST RES ");
sql.append("where RES.END_TIME_ is null ");
sql.append(" and (exists (select LINK.USER_ID_ from ACT_HI_IDENTITYLINK LINK where USER_ID_ = ? and LINK.PROC_INST_ID_ = RES.PROC_INST_ID_)) ");
sql.append(" and exists (select 1 from ACT_RU_TASK t where t.PROC_INST_ID_=RES.ID_ and t.ASSIGNEE_=? order by t.ID_ asc limit 1)) ");
sql.append(" union ");
sql.append(" (select distinct RES.* from ACT_HI_PROCINST RES inner join ACT_HI_ACTINST a1 on (a1.PROC_INST_ID_ = RES.PROC_INST_ID_ and a1.ACT_TYPE_ != 'endEvent') ");
sql.append(" inner join ACT_RU_TASK t on (a1.TASK_ID_=t.ID_ and instr(t.DESCRIPTION_, 'conditionCountersign') > 0) ");
sql.append(" inner join ACT_HI_ACTINST a2 on (a1.ACT_ID_=a2.ACT_ID_ and a1.START_TIME_>a2.START_TIME_ and a2.ASSIGNEE_=?) ");
sql.append(" where RES.END_TIME_ is null ");
sql.append(" and exists (select LINK.USER_ID_ from ACT_HI_IDENTITYLINK LINK where USER_ID_ = ? and LINK.PROC_INST_ID_ = RES.ID_)) ");
sql.append("order by START_TIME_ desc) dd "); List<Object> param = new ArrayList<Object>();
param.add(query.getInvolvedUser());
param.add(query.getInvolvedUser());
param.add(query.getInvolvedUser());
param.add(query.getInvolvedUser()); String countSql = PageUtils.getCountSQL(sql.toString());
logger.info("About to excute sql=\n{}\n{}", countSql, BaseUtils.printList(param));
Integer total = baseDao.getJdbcTemplate().queryForObject(countSql, param.toArray(), Integer.class);
query.setTotalRecord(total); // 分页设置
PageUtils.buildPageSqlForMysql(sql, query); logger.info(" About to excute sql=\n{}\n{}", sql.toString(), BaseUtils.printList(param));
List<HistoricProcessInstanceEntity> datas = baseDao.getJdbcTemplate().query(sql.toString(), param.toArray(), new BeanPropertyRowMapper<HistoricProcessInstanceEntity>(HistoricProcessInstanceEntity.class));
return datas;
}

启动项目测试:

严重: Servlet.service() for servlet [spring] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.NoSuchMethodError: com.sinotaiyo.srpm.activiti.DetailBuilder.BuildWorkflowDetailByEntity(Lorg/activiti/engine/impl/persistence/entity/HistoricProcessInstanceEntity;)Lcom/sinotaiyo/srpm/activiti/WorkflowDetail;] with root cause

java.lang.NoSuchMethodError: com.sinotaiyo.srpm.activiti.DetailBuilder.BuildWorkflowDetailByEntity(Lorg/activiti/engine/impl/persistence/entity/HistoricProcessInstanceEntity;)Lcom/sinotaiyo/srpm/activiti/WorkflowDetail;

方法是写好的,debug进去是用代理模式;

javap –s DetailBuilder

貌似一样的啊;

折腾了好久,用Run As Server里边的tomcat就可以,但用maven插件的方式启动就报错;

为啥呢?

优化到此为止,告一段落。

疑问:

1、jpa的注解方式写DAO层可以用原生SQL吗?HQL是这样的:

2、activiti的表字段和属性名虽然不一样,但还是可以识别,不算折磨人,为什么不能一样呢?一样不是更好吗?所有地方都可以拷贝,不用拷贝了修改,保留下划线可以理解,要是怕字段过长的话,别定那么长的字段就可以了,至少要保持一致,一致之后很多自动化的事情就好办了,比如写代码生成器;

3、设计良好的数据库,即使再复杂的查询也应该是很好写,为何这里的待办查询这么恐怖?

总结:

1、 新入职,接手已有项目,就是这么坎坷,习惯就好;

2、 论测试的重要性,一个语句测多少遍才测通啊,写测试还是非常有必要的,负责任的提现,但之前公司的开发人员,工作1年就当技术主管,代码都没写几行就主管,真心无语,还有个工作1年就封为架构师,写个JavaBean属性全是public,都只是加班积极点,爱装13,我也是醉了;

3、 排错的简单做法就是先做减法再做加法,不用开根号,呵呵简单吧

4、 能用SQL一次做完的事情就用SQL做,像下图这种,完全可以在语句里边过滤排序吧;

工作流性能优化(敢问activiti有扩展性?)(3)的更多相关文章

  1. 工作流性能优化(敢问activiti有扩展性?)(2)

    2015/4/17 粗略看了activiti的sql的,在ativity engine包里边: 没什么头绪,先用excel记录数据量少的时候本机的性能情况:   不打印hibernate的sql:一刷 ...

  2. 工作流性能优化(敢问activiti有扩展性?)(1)

    工作流待办(首页待办列表),加载缓慢,activiti本机,看了代码又是全部数据加载到内存,然后代码过滤,我为什么又说又呢? 用VisualVM做性能测试:   之前同事给的解决方案: 1.把&quo ...

  3. C#大型电商项目优化(三)——扩展性与支付

    上一篇文章引来不少非议,笔者并非对EF有看法,而是针对不同的业务场景和框架背景,挑选不同的方案.每个方案都有其优势劣势,挑选最快速,最简单的方案,是笔者的初衷. 看评论也是学习的过程,然而有些只做评价 ...

  4. 深入NGINX:我们如何设计它的性能和扩展性

    为了更好地理解设计,你需要了解NGINX是如何工作的.NGINX之所以能在性能上如此优越,是由于其背后的设计.许多web服务器和应用服务器使用简单的线程的(threaded).或基于流程的 (proc ...

  5. Java并发编程:性能、扩展性和响应

    1.介绍 本文讨论的重点在于多线程应用程序的性能问题.我们会先给性能和扩展性下一个定义,然后再仔细学习一下Amdahl法则.下面的内容我们会考察一下如何用不同的技术方法来减少锁竞争,以及如何用代码来实 ...

  6. 【Java/Android性能优5】 Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强

    本文转自:http://www.trinea.cn/android/android-imagecache/ 主要介绍一个支持图片自动预取.支持多种缓存算法.支持二级缓存.支持数据保存和恢复的图片缓存的 ...

  7. 【Java/Android性能优 4】PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强

    本文转自:http://www.trinea.cn/android/preloaddatacache/ 本文主要介绍一个支持自动向前或向后获取新数据的缓存的使用及功能.Android图片内存缓存可见I ...

  8. MySQL 复制 - 性能与扩展性的基石:概述及其原理

    原文:MySQL 复制 - 性能与扩展性的基石:概述及其原理 1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他 ...

  9. Zend server最大化应用程序的性能、扩展性和可用性

    如果我有8个小时去砍到一棵树,我会花6个小时磨斧子”——林肯(美国总统) 你可以知道? 世界页面访问量的峰值超过7000万每分钟. CloudFare公司服务器问题,导致785000站点崩溃一小时. ...

随机推荐

  1. laravel 常见操作

    1.url()

  2. uva12545 比特变换器(贪心)

    uva12545 比特变换器(贪心) 输入两个等长的串S,T(长度小于100),其中S包含字符0,1,?,T中包含0和1.有三种操作:将S中的0变为1,?变为0或1,交换S中的任意两个字符.求将S变成 ...

  3. 洛谷P3145 [USACO16OPEN]分割田地Splitting the Field

    P3145 [USACO16OPEN]分割田地Splitting the Field 题目描述 Farmer John's NN cows (3 \leq N \leq 50,0003≤N≤50,00 ...

  4. Tomcat热部署的实现原理

    Tomcat热部署机制 对于Java应用程序来说,热部署就是在运行时更新Java类文件.在基于Java的应用服务器实现热部署的过程中,类装入器扮演着重要的角色.大多数基于Java的应用服务器,包括EJ ...

  5. 【补档】Pycharm的一些配置

    新建和创建文件就不必说了吧~ 运行这里原本是灰色的,我们点旁边的三角形 点绿色+号,python Name:随便写 Script:选择一个py文件~,然后OK,就可以运行了

  6. jdb应用

    场景: 外网可以登录远程主机,但是因为安全限制,不能在外网直接访问docker应用的端口,因此不能远程调试.远程主机shell内部可以连接docker应用,也没有图形界面,没有log,考虑使用原始的j ...

  7. 【ACM】Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  8. linux 编程笔记1 crusher for linux

    1.反显示字符crusher #include <stdio.h> int main (int argc, char *argv[]) { printf("\033[7m mor ...

  9. js中的focus()聚焦

    document.getElementById("vin").focus();document.form1.name.focus() $(document).ready(funct ...

  10. ASP.NET相关

    1.委托:把一个方法当作参数传到另一个方法中 扩展方法:1.静态类 2.静态方法 3.this关键字 using System; using System.Collections.Generic; u ...