如何在BatchJob中使用AOT Query?
前言:过去构建BatchJob,Dialog中的过滤条件是通过在Batch类中设置dialog()方法,生成需要过滤条件的下拉框。但今天遇到一个项目,需要提前在AOT中创建相关Query,添加数据源,然后通过设置queryRun()方法,在Dialog中生成一个Filter的控件进行数据过滤。
目录
一、项目简介
需要构建一个Batch Job,来达到一个功能:将指定的系统已有的仓库添加到如上图所示的Form中,即向InventItemLocation插入一条记录。
二、创建AOT Query
向Query中插入两个数据源:InventTable提供ItemId,InventLocation提供InventLocationId(即warehouse)。并且将InventLocation数据源Join入InventTable,因为两个数据源之间没有关系,可以不设置relation,这样可通过Query得到相应的笛卡儿积。
三、创建Batch类
由于需要在Dialog中构造一个Filter控件,用于过滤数据,所以需要用到两个方法queryRun()和initParmDefault().
首先需要定义QueryRun的类变量:
private QueryRun queryRun;
1、queryRun()与initParmDefault()
public QueryRun queryRun()
{
return queryRun;
}
public void initParmDefault()
{
//你需要在此方法中初始化QueryRun的引用,让它指向你在AOT中创建的Query对象
//DECInventWarehouseQuery为AOT Query
Query query = new Query(queryStr(DECInventWarehouseQuery));
queryRun = new QueryRun(query);
super();
}
通过这两个方法,可以在run()方法之前初始化queryRun对象,从而得到:通过前台Form的Filter控件,已经过滤好数据的Query:
从上图得知,获取到的item number为1.0.00261,warehouse为10SCCC-QC。
注意!当在BatchJob中使用AOT Query一定要重写canRunInNewSession()方法:
protected boolean canRunInNewSession()
{
return this.isInBatch();
}
2、Run()方法主要逻辑
public void run()
{
InventItemLocation lInventItemLocation;
RecordInsertList lRecordInsertList;
InventDim lInventDim;
InventDim newInventDim;
while(queryRun.next())
{
//获取已经过滤的数据源:InventTable和InventLocation
gInventTable = queryRun.get(tableNum(InventTable));
gInventLocation = queryRun.get(tableNum(InventLocation));
//使用findOrCreate()方法创建InventDim记录
//注意!InventDim记录只能使用此方法创建记录
selectedItemId = gInventTable.ItemId;
newInventDim.InventLocationId = gInventLocation.InventLocationId;
newInventDim = InventDim::findOrCreate(newInventDim);
//使用newInventDim的inventDimId、前台选择的ItemId->selectedItemId,查询在lInventItemLocation是否有符合条件的记录
select firstonly lInventItemLocation
where lInventItemLocation.ItemId == selectedItemId
&& lInventItemLocation.inventDimId == newInventDim.inventDimId;
//如果没有这条记录,那么就插入这条记录
if (!lInventItemLocation)
{
//RecordInsertList类可用于批量插入记录,使用方法如下:
lRecordInsertList = new RecordInsertList(tableNum(InventItemLocation), true, true, true, false, true, lInventItemLocation);
lInventItemLocation.ItemId = selectedItemId;
lInventItemLocation.inventDimId = newInventDim.inventDimId;
lRecordInsertList.add(lInventItemLocation);
//RecordInsertList类提供了将多条记录批量插入数据库的功能
//但如果将insertDatabase()的调用放在while()循环内,那么每一次循环都插入一次,这样便没有达到该类提供的预期的效果,可以将这个调用放在循环外
//lRecordInsertList.insertDatabase();
}
}
//将调用放在此处,便可将lRecordInsertList中已经存储的一条或多条记录批量插入数据库
lRecordInsertList.insertDatabase();
}
四、结论
个人对AOT Query的使用以及Batch类的执行流程以及作用了解的不够透彻,所以开发过程遇到了不少问题。以及对于一个需求的逻辑不能快速且正确的梳理出来,这是一个很大的问题,需要后期的不断练习!
2022年3月26日- 对run()方法进行一个逻辑上的修改,具体修改请看上述代码: