当前位置:首页 >> 计算机软件及应用 >>

ofbiz开发培训系列(后台部分)


Ofbiz 基础培训手册(后台部分)

历史记录

版本 V0.1

日期 2014-03-27

更改记录 草稿

审核

作者 刘伟东

一、 说明
1. 编写目的

本文档以案例的形式,让技术人员在没有指导的情况下来学习怎么使用 Ofbiz 的工 具类、服务引擎和实体引擎等。 还可以对 Ofbiz 开发人员编写的代码进行规范。

2.

面向的读者

? ?

有了一定 Java 基础、准备从事 Ofbiz 开发、并已经了解 Ofbiz 基础结构的人; 已经在从事 Ofbiz 的开发人员

二、 辅助工具类
在实际的项目开发过程中,总是离不开对数据的检查、计算等处理,Ofbiz 平台提供了 丰富、成熟的工具类用来完成这些处理。这些工具类包括:字符串处理、日期的计算、数据 的检查、 输出数据的格式化等。 这些工具类的功能, 已经覆盖了开发过程中的绝大部分处理, 并且处理的方法也已经很成熟。 在实际的项目开发过程中, 除非平台提供的工具类无法实现特殊的业务处理需求, 否则, 不要开发个自的工具类, 这对于保证系统运行的可靠以及日后的维护都非常重要。 掌握这些 工具类的使用,是每个开发人员必备的基本技能。

1.

数据检查工具类

类名: com.ofbiz.base.util.ext.UtilValidate 数据检测工具类的 Demo 类名为: com.ofbiz.demo.tools.UtilValidateDemo

检查一个字符串是否为空字符串

/**

* 检查一个字符串是否为空字符串 */ public static void runFirstDeom(){ String firstStr String thirdStr = "ABC"; = null;

String secondStr = "";

if( UtilValidate.isEmpty(firstStr)){ System.out.println("参数["+firstStr+"] 是一个空字符串!"); }else{ System.out.println("参数["+firstStr+"] 不是一个空字符串!"); } if( UtilValidate.isEmpty(secondStr)){ System.out.println("参数["+ secondStr +"] 是一个空字符串!"); }else{ System.out.println("参数["+ secondStr +"] 不是一个空字符串!"); } if( UtilValidate.isEmpty(thirdStr)){ System.out.println("参数["+ thirdStr +"] 是一个空字符串!"); }else{ System.out.println("参数["+ thirdStr +"] 不是一个空字符串!"); } }

结果:
参数[ABC] 不是一个空字符串! 参数[] 是一个空字符串! 参数[null] 是一个空字符串!

检测一个字符串是否不是空字符串

/** * 检查一个字符串是否为非空字符串 */ public static void runSecondDemo(){ String firstStr String thirdStr = "ABC"; = null;

String secondStr = "";

if( UtilValidate.isNotEmpty(firstStr)){ System.out.println("参数["+ firstStr +"] 是一个非空字符串!"); }else{ System.out.println("参数["+ firstStr +"] 不是一个非空字符串!"); } if( UtilValidate.isNotEmpty(secondStr)){ System.out.println("参数["+ secondStr +"] 是一个非空字符串!"); }else{ System.out.println("参数["+ secondStr +"] 不是一个非空字符 串!"); } if( UtilValidate.isNotEmpty( thirdStr )){ System.out.println("参数["+ thirdStr +"] 是一个非空字符串!"); }else{ System.out.println("参数["+ thirdStr +"] 不是一个非空字符串!"); } }

结果:
参数[ABC] 是一个非空字符串! 参数[] 不是一个非空字符串! 参数[null] 不是一个非空字符串!

检查一个字符串是否为整数

/** * 检查一个字符串是否为整数 */ public static void runThirdDemo(){ String firstStr String thirdStr String fifthStr String sixthStr = "101"; = "-100"; = ""; = null;

String secondStr = "101.2"; String fourthStr = "ABC";

//验证方法 isInteger() System.out.println("验证方法: isInteger(String arg) 用来检查一个字 符串是否为一个正整数或零或零");

if( UtilValidate.isInteger(firstStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+firstStr+"] 是一个正整数或零;"); }else{ System.out.println("验证方式[isInteger()] 字符串 ["+firstStr+"] 不是一个正整数或零;"); } if( UtilValidate.isInteger(secondStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+secondStr+"] 是一个正整数或零;"); }else{ System.out.println("验证方式[isInteger()] 字符串 ["+secondStr+"] 不是一个正整数或零;"); } if( UtilValidate.isInteger(thirdStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+thirdStr+"] 是一个正整数或零;"); }else{ System.out.println("验证方式[isInteger()] 字符串 ["+thirdStr+"] 不是一个正整数或零;"); } if( UtilValidate.isInteger(fourthStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+fourthStr+"] 是一个正整数或零;"); }else{ System.out.println("验证方式[isInteger()] 字符串 ["+fourthStr+"] 不是一个正整数或零;"); } if( UtilValidate.isInteger(fifthStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+fifthStr+"] 是一个正整数或零;"); }else{ System.out.println("验证方式[isInteger()] 字符串 ["+fifthStr+"] 不是一个正整数或零;"); } if( UtilValidate.isInteger(sixthStr) ){ System.out.println("验证方式[isInteger()] 字符串 ["+sixthStr+"] 是一个正整数或零;"); }else{

System.out.println("验证方式[isInteger()] 字符串 ["+sixthStr+"] 不是一个正整数或零;"); } //验证方法 isSignedInteger() System.out.println("验证方法: isSignedInteger(String arg) 用来检 查一个字符串是否为一个整数(包括正/负/零)"); if( UtilValidate.isSignedInteger(firstStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+firstStr+"] 是一个整数;"); }else{ System.out.println("验证方式[isSignedInteger()] 字符串 ["+firstStr+"] 不是一个整数;"); } if( UtilValidate.isSignedInteger(secondStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+secondStr+"] 是一个整数;"); }else{ System.out.println("验证方式[isSignedInteger()] 字符串 ["+secondStr+"] 不是一个整数;"); } if( UtilValidate.isSignedInteger(thirdStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+thirdStr+"] 是一个整数;"); }else{ System.out.println("验证方式[isSignedInteger()] 字符串 ["+thirdStr+"] 不是一个整数;"); } if( UtilValidate.isSignedInteger(fourthStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+fourthStr+"] 是一个整数;"); }else{ System.out.println("验证方式[isSignedInteger()] 字符串 ["+fourthStr+"] 不是一个整数;"); } if( UtilValidate.isSignedInteger(fifthStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+fifthStr+"] 是一个整数;"); }else{

System.out.println("验证方式[isSignedInteger()] 字符串 ["+fifthStr+"] 不是一个整数;"); } if( UtilValidate.isSignedInteger(sixthStr) ){ System.out.println("验证方式[isSignedInteger()] 字符串 ["+sixthStr+"] 是一个整数;"); }else{ System.out.println("验证方式[isSignedInteger()] 字符串 ["+sixthStr+"] 不是一个整数;"); } }

结果:
验证方法: isInteger(String arg) 用来检查一个字符串是否为一个正整数或零或零 验证方式[isInteger()] 字符串[101] 是一个正整数或零; 验证方式[isInteger()] 字符串[101.2] 不是一个正整数或零; 验证方式[isInteger()] 字符串[-100] 不是一个正整数或零; 验证方式[isInteger()] 字符串[ABC] 不是一个正整数或零; 验证方式[isInteger()] 字符串[] 是一个正整数或零; 验证方式[isInteger()] 字符串[null] 是一个正整数或零; 验证方法: isSignedInteger(String arg) 用来检查一个字符串是否为一个整数(包括正 /负/零) 验证方式[isSignedInteger()] 字符串[101] 是一个整数; 验证方式[isSignedInteger()] 字符串[101.2] 不是一个整数; 验证方式[isSignedInteger()] 字符串[-100] 是一个整数; 验证方式[isSignedInteger()] 字符串[ABC] 不是一个整数; 验证方式[isSignedInteger()] 字符串[] 是一个整数; 验证方式[isSignedInteger()] 字符串[null] 是一个整数;

检查一个字符串是否为双精度型(Double)

/** * 检查一个字符串是否为Double, 可以在把一个字符串转换成BigDecimal前对字符串 进行检查 */ public static void runFourthDemo(){ String firstStr String thirdStr = "101"; = "-100.32";

String secondStr = "101.2"; String fourthStr = "ABC";

String fifthStr String sixthStr

= ""; = null;

//验证方法 isSignedDouble() System.out.println("验证方法: isSignedDouble(String arg) 用来检查 一个字符串是否为一个数字(包括正/负/零)"); if( UtilValidate.isSignedDouble(firstStr)){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+firstStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串 ["+firstStr+"] 不是一个数字;"); } if( UtilValidate.isSignedDouble(secondStr) ){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+secondStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串 ["+secondStr+"] 不是一个数字;"); } if( UtilValidate.isSignedDouble(thirdStr) ){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+thirdStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串 ["+thirdStr+"] 不是一个数字;"); } if( UtilValidate.isSignedDouble(fourthStr) ){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+fourthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串 ["+fourthStr+"] 不是一个数字;"); } if( UtilValidate.isSignedDouble(fifthStr) ){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+fifthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串

["+fifthStr+"] 不是一个数字;"); } if( UtilValidate.isSignedDouble(sixthStr) ){ System.out.println("验证方式[isSignedDouble()] 字符串 ["+sixthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isSignedDouble()] 字符串 ["+sixthStr+"] 不是一个数字;"); } //验证方法 is() System.out.println("验证方法: isSignedInteger(String arg) 用来检 查一个字符串是否为一个数字(包括正/负/零)"); /** * UtilValidate.isDouble(s, allowNegative, allowPositive, minDecimal, maxDecimal) * 该方法的入参的含义分别为: * * * * 内. * 如果允许一个字符串为整数, 则需要把 minDecimal 设置为 0 ,含义是:没有小数位. */ if( UtilValidate.isDouble(firstStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+firstStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+firstStr+"] 不是一个数字;"); } if( UtilValidate.isDouble(secondStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+secondStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+secondStr+"] 不是一个数字;"); } s : 需要判断的字符串 是否允许该字符串为负数 是否允许该字符串为正数 allowNegative : allowPositive :

minDecimal,maxDecimal : 共同来控制该字符串对应的小数位数, 例如:

minDecimal = 2、maxDecimal = 4 就要求该字符串对应的小数位必须在[2,4]的闭区间

if( UtilValidate.isDouble(thirdStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+thirdStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+thirdStr+"] 不是一个数字;"); } if( UtilValidate.isDouble(fourthStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+fourthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+fourthStr+"] 不是一个数字;"); } if( UtilValidate.isDouble(fifthStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+fifthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+fifthStr+"] 不是一个数字;"); } if( UtilValidate.isDouble(sixthStr, true, true, 0, 5) ){ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+sixthStr+"] 是一个数字;"); }else{ System.out.println("验证方式[isDouble(s,true,true,0,5)] 字符 串["+sixthStr+"] 不是一个数字;"); } }

结果:
验证方法: isSignedDouble(String arg) 用来检查一个字符串是否为一个数字(包括正/ 负/零) 验证方式[isSignedDouble()] 字符串[101] 是一个数字; 验证方式[isSignedDouble()] 字符串[101.2] 是一个数字; 验证方式[isSignedDouble()] 字符串[-100.32] 是一个数字; 验证方式[isSignedDouble()] 字符串[ABC] 不是一个数字; 验证方式[isSignedDouble()] 字符串[] 是一个数字; 验证方式[isSignedDouble()] 字符串[null] 是一个数字; 验证方法: isSignedInteger(String arg) 用来检查一个字符串是否为一个数字(包括正 /负/零)

验证方式[isDouble(s,true,true,0,5)] 字符串[101] 是一个数字; 验证方式[isDouble(s,true,true,0,5)] 字符串[101.2] 是一个数字; 验证方式[isDouble(s,true,true,0,5)] 字符串[-100.32] 是一个数字; 验证方式[isDouble(s,true,true,0,5)] 字符串[ABC] 不是一个数字; 验证方式[isDouble(s,true,true,0,5)] 字符串[] 是一个数字; 验证方式[isDouble(s,true,true,0,5)] 字符串[null] 是一个数字;

2.

实体工具类 类名:com.ofbiz.entity.util.EntityUtil 实体工具类的 Demo 类名为: com.ofbiz.demo.tools. EntityUtil Demo 从集合 List<GenericValue>中取出第一个元素

/** * 从集合List<GenericValue>中取出第一个元素 */ public static void runFirstDemo(){ //制作List<GenericValue>,用于测试 GenericValue firstGV = GenericValue.NULL_VALUE; GenericValue secondGV GenericValue thirdGV = GenericValue.NULL_VALUE; = GenericValue.NULL_VALUE;

List<GenericValue> firstList = FastList.newInstance(); firstList.add(firstGV); List<GenericValue> secondList = FastList.newInstance(); secondList.add(firstGV); secondList.add(secondGV); secondList.add(thirdGV); GenericValue temp = EntityUtil.getFirst(firstList); System.out.println("从firstList中取得的第一个元素: " + temp); temp = EntityUtil.getFirst(secondList); System.out.println("从secondList中取得的第一个元素: " + temp); }

结果

从firstList中取得的第一个元素: [null-entity-value] 从 secondList 中取得的第一个元素: [null-entity-value]

从集合 List<GenericValue>中取出唯一一个元素

/** * 从集合List<GenericValue>中取出唯一一个元素 */ public static void runSecondDemo(){ //制作List<GenericValue>,用于测试 GenericValue firstGV = GenericValue.NULL_VALUE; GenericValue secondGV GenericValue thirdGV = GenericValue.NULL_VALUE; = GenericValue.NULL_VALUE;

List<GenericValue> firstList = FastList.newInstance(); firstList.add(firstGV); List<GenericValue> secondList = FastList.newInstance(); secondList.add(firstGV); secondList.add(secondGV); secondList.add(thirdGV); GenericValue temp = EntityUtil.getOnly(firstList); System.out.println("从firstList中取得的唯一一个元素: " + temp); try{ temp = EntityUtil.getOnly(secondList); System.out.println("从secondList中取得的唯一一个元素: " + temp); }catch(Exception e){ e.printStackTrace(); } }

结果:
从firstList中取得的唯一一个元素: [null-entity-value] java.lang.IllegalArgumentException: Passed List had more than one value. at com.ofbiz.entity.util.EntityUtil.getOnly(EntityUtil.java:89) at com.ofbiz.demo.tools.EntityUtilDemo.runSecondDemo(EntityUtilDemo.java :71) at

com.ofbiz.demo.tools.EntityUtilDemo.main(EntityUtilDemo.java:20)

3.

日期或时间工具类 类名:com.ofbiz.base.util.ext.UtilDateTime 日期或时间工具类的 Demo 类名为: com.ofbiz.demo.tools. UtilDateTimeDemo

取得当前的时间戳
/** * 取得当前时间戳 */ public static void runFirstDemo(){ //取得当前时间戳 Timestamp currentTime = UtilDateTime.nowTimestamp(); //打印当前时间 System.out.println("当前时间:" + currentTime ); }

结果
/** * 取得当前时间戳 */ public static void runFirstDemo(){ //取得当前时间戳 Timestamp currentTime = UtilDateTime.nowTimestamp(); //打印当前时间 System.out.println("当前时间:" + currentTime ); };

根据一个时间戳, 取得当天最早一个时点.
/** * 根据一个时间戳, 取得当天最早一个时点. */ public static void runSecondDemo(){

//取得当前时间戳 Timestamp currentTime = UtilDateTime.nowTimestamp(); //打印当前时间 System.out.println("当前时间:" + currentTime ); Timestamp changedTime = UtilDateTime.getDayStart(currentTime); System.out.println("改变后的时间:" + changedTime ); }

结果:
当前时间:2013-04-11 11:31:52.656 改变后的时间:2013-04-11 00:00:00.0

根据一个时间戳, 取得当天最后一个时点
/** * 根据一个时间戳, 取得当天最后一个时点. */ public static void runThirdDemo(){ //取得当前时间戳 Timestamp currentTime = UtilDateTime.nowTimestamp(); //打印当前时间 System.out.println("当前时间:" + currentTime ); Timestamp changedTime = UtilDateTime.getDayEnd(currentTime); System.out.println("改变后的时间:" + changedTime ); }

结果
当前时间:2013-04-11 11:33:15.046 改变后的时间:2013-04-11 23:59:59.999999999

根据指定格式在 Timestamp 和字符串之间转换一个时间的类型
/** * 根据指定格式在Timestamp和字符串之间转换一个时间的类型

*/ public static void runFourthDemo(){ //取得当前时间戳 Timestamp currentTime = UtilDateTime.nowTimestamp(); String firstFormat = "yyyyMMdd"; String secondFormat = "yyyy:MM:dd"; //把一个时间戳根据指定的格式转成字符串 String firstTimeStr = UtilDateTime.toDateString(currentTime, firstFormat); System.out.println("根据格式["+firstFormat+"] 显示日期 : " + firstTimeStr); String secondTimeStr = secondFormat); System.out.println("根据格式["+secondFormat+"] 显示日期 : " + secondTimeStr); //把一个字符串根据指定的格式转成时间戳 try { Timestamp firstDate = UtilDateTime.stringToTimeStamp(firstTimeStr, firstFormat, TimeZone.getDefault(), Locale.getDefault()); System.out.println("根据格式["+firstFormat+"] 显示日期 : " + firstDate); } catch (ParseException e) { e.printStackTrace(); } try { Timestamp secondDate = UtilDateTime.stringToTimeStamp(secondTimeStr, secondFormat, TimeZone.getDefault(), Locale.getDefault()); System.out.println("根据格式["+secondFormat+"] 显示日期 : " + secondDate); } catch (ParseException e) { e.printStackTrace(); } } UtilDateTime.toDateString(currentTime,

结果: 根据格式[yyyyMMdd] 显示日期 : 20130411 根据格式[yyyy:MM:dd] 显示日期 : 2013:04:11 根据格式[yyyyMMdd] 显示日期 : 2013-04-11 00:00:00.0 根据格式[yyyy:MM:dd] 显示日期 : 2013-04-11 00:00:00.0

4.

属性文件工具类 类名:com.ofbiz.base.util.UtilProperties 属性文件工具类的Demo类名为: com.ofbiz.demo.tools. UtilPropertiesDemo 从属性文件中获取所有的属性
/** * 从属性文件中获取所有的属性 */ public static void runFirstDemo(){ Properties values = UtilProperties.getProperties(FILE_NAME); System.out.println("显示该文件下的所有属性:"); for( Entry<Object, Object> one : values.entrySet()){

System.out.println("属性【"+ one.getKey()+"】= " + one.getValue()); } }

结果:
显示该文件下的所有属性: 属性【age】= 24 属性【name】= 张三

从属性文件中获取指定的属性值
/** * 从属性文件中获取指定的属性值 */ public static void runSecondDemo(){ String name = UtilProperties.getPropertyValue( FILE_NAME , "name");

String weight "weight");

= UtilProperties.getPropertyValue( FILE_NAME ,

System.out.println("属性【name】= " + name); System.out.println("属性【weight】= " + weight); }

结果:
属性【name】= 张三 属性【weight】=

从属性文件中获取指定的属性值,如果无法找到指定的属性,以默认值作为返 回值
/** * 从属性文件中获取指定的属性值,如果无法找到指定的属性,以默认值作为返回值 */ public static void runThirdDemo(){ String name = UtilProperties.getPropertyValue( FILE_NAME , "name"); String weight "weight", "100"); System.out.println("属性【name】= " + name); System.out.println("属性【weight】= " + weight); } = UtilProperties.getPropertyValue( FILE_NAME ,

结果
属性【name】= 张三 属性【weight】= 100

三、 服务引擎
1. 获得服务引擎对象

A.

在服务内部怎么获得服务引擎

在服务内部,我们可以从服务的输入参数【DispatchContext dctx】中得到我们想要的 服务引擎。具体方法如下:
public static Map<String,Object> pdateUomAfterQuery(DispatchContext dctx, Map<String,Object> context){ //获取服务引擎 LocalDispatcher dispatcher = dctx.getDispatcher(); //...... return ReturnMapUtil.getSuccessMap(); }

B.

在服务外部怎么获得服务引擎

在服务外部,我们需要自己通过静态方法【GenericDispatcher.getLocalDispatcher】取得。 具体方法如下: GenericDelegator delegator = GenericDelegator.getGenericDelegator("default"); LocalDispatcher dispatcher = GenericDispatcher.getLocalDispatcher("defualt", delegator);

2.

执行服务

A.

以同步的方式执行服务 1) 在 com.ofbiz.demo.dispatcher.DispatcherRunDemoService 类中编写服务 【test】,内容如下:

public static Map<String,Object> test( DispatchContext dctx, Map<String,Object> context ){ String message = (String) context.get("message"); System.out.println("我被运行 -> 消息: " + message );

try { Thread.sleep(5000); //休眠5秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("我被运行 -> 消息: " + message ); return ServiceUtil.returnSuccess(); }

2) 在 com.ofbiz.demo.dispatcher.DispatcherRunDemoService 类中编写服务 【runSynchronizationService】,内容如下:
/** * 同步调用服务 * @param dctx * @param context * @return */ public static Map<String,Object> runSynchronizationService( DispatchContext dctx, Map<String,Object> context ){ //获取服务引擎 LocalDispatcher dispatcher = dctx.getDispatcher(); System.out.println("开始同步运行test服务 " );

Map<String,Object> input = FastMap.newInstance(); input.put("message", "同步调用"); try { dispatcher.runSync("test", input); } catch (GenericServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("完成同步运行test服务 return ServiceUtil.returnSuccess(); } " );

3) 在 servicedef 文件夹下的 services_dispatcher_run_demo.xml 中把这两个方法配 制成服务
<!-- 同步调用服务 刘伟东 2013.03.31 --> <service name="runSynchronizationService" engine="java"

location="com.ofbiz.demo.dispatcher.DispatcherRunDemoService" invoke="runSynchronizationService"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service> <!-- 测试服务的同步或异步运行 刘伟东 2013.03.31 --> <service name="test" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherRunDemoService" invoke="test"> <attribute name="message" type="String" mode="IN" optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

B.

以异步的方式执行服务

1) 使用已经写好的服务【test】位置在 com.ofbiz.demo.dispatcher.DispatcherRunDemoService 类中 2) 在 com.ofbiz.demo.dispatcher.DispatcherRunDemoService 类中编写服务 【runAsynchronismService】,内容如下:
/** * 异步调用服务 * @param dctx * @param context * @return */ public static Map<String,Object> runAsynchronismService( DispatchContext dctx, Map<String,Object> context ){ //获取服务引擎 LocalDispatcher dispatcher = dctx.getDispatcher(); System.out.println("开始异步运行test服务 " );

Map<String,Object> input = FastMap.newInstance(); input.put("message", "异步调用"); try { dispatcher.runAsync("test", input); } catch (GenericServiceException e) {

// TODO Auto-generated catch block e.printStackTrace(); } System.out.println("完成异步运行test服务 return ServiceUtil.returnSuccess(); } " );

3) 在 servicedef 文件夹下的 services_dispatcher_run_demo.xml 中把这两个方法配 制成服务
<!-- 异步调用服务 刘伟东 2013.03.31 --> <service name="runAsynchronismService" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherRunDemoService" invoke="runAsynchronismService"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

3.

服务返回结果

A.

返回成功结果

1) 在 com.ofbiz.demo.dispatcher.DispatcherReturnDemoService 类中编写服务 【returnSuccess】,内容如下:
/** * 返回成功结果 * @param dctx * @param context * @return */ public static Map<String,Object> returnSuccess( DispatchContext dctx, Map<String,Object> context ){ //填写服务执行的代码 //....... String message = "执行成功"; //当程序执行成功时, 返回成功结果集 Map<String,Object> result = ReturnMapUtil.getSuccessMap(); result.put("message", message);

return result; }

2) 在 servicedef 文件夹下的 services_dispatcher_return_demo.xml 中把这两个方法 配制成服务
<!-- 返回成功服务 刘伟东 2013.03.31 --> <service name="returnSuccess" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherReturnDemoService" invoke="returnSuccess"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

B.

返回失败结果

1) 在 com.ofbiz.demo.dispatcher.DispatcherReturnDemoService 类中编写服务 【returnError】,内容如下:
/** * 返回失败结果 * @param dctx * @param context * @return */ public static Map<String,Object> returnError( DispatchContext dctx, Map<String,Object> context ){

//填写服务执行的代码 //....... String message = "执行失败"; boolean errorFlag = true; //返回结果 Map<String,Object> result = null; if( errorFlag ){ //当程序执行失败时, 返回成功结果集 result = ReturnMapUtil.getErrorMap("errorCode"); //这里的 errorCode需要用具体的错误编码来替换 result.put("message", message);

}else{ //当程序执行成功时, 返回成功结果集 result = ReturnMapUtil.getSuccessMap(); result.put("message", message); } return result; }

2) 在 servicedef 文件夹下的 services_dispatcher_return_demo.xml 中把这两个方法 配制成服务
<!-- 返回失败服务 刘伟东 2013.03.31 --> <service name="returnError" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherReturnDemoService" invoke="returnError"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

C.

在服务内部捕获异常后怎么转成失败结果返回

1) 在 com.ofbiz.demo.dispatcher.DispatcherReturnDemoService 类中编写服务 【catchError】,内容如下:
/** * 捕获异常结果 * @param dctx * @param context * @return */ public static Map<String,Object> catchError( DispatchContext dctx, Map<String,Object> context ){ //填写服务执行的代码 try{ //假设执行的代码中有回抛出异常的情况, 我们需要捕获这个异常 int a = 8 ; int b = 0 ; int i = a / b; }catch(Exception e){

//则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0000); } //当程序执行失败时, 返回成功结果集 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_dispatcher_return_demo.xml 中把这两个方法 配制成服务
<!-- 捕获异常结果 刘伟东 2013.03.31 --> <service name="catchError" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherReturnDemoService" invoke="catchError"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

D.

调用一个服务后怎么判断该服务是否执行成功

1) 在 com.ofbiz.demo.dispatcher.DispatcherReturnDemoService 类中编写服务 【checkResult】,内容如下:
/** * 调用一个服务后怎么判断该服务是否执行成功 * @param dctx * @param context * @return */ public static Map<String,Object> checkResult( DispatchContext dctx, Map<String,Object> context ){

//获取服务引擎 LocalDispatcher dispatcher = dctx.getDispatcher();

//.....

//其它代码 //....... //调用服务 Map<String,Object> output = null; try{ Map<String,Object> input = FastMap.newInstance(); output = dispatcher.runSync("returnSuccess", input); }catch(Exception e){ //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0000); } //检查该服务是否已经执行成功, 如果没有执行成功,则把错误结果直接返回给上层 调用者. if( !ServiceUtil.isSuccess(output) ){ return output; } //..... //其它代码 //....... //当程序执行成功时, 返回成功结果集 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_dispatcher_return_demo.xml 中把这两个方法 配制成服务
<!-- 返回失败服务 刘伟东 2013.03.31 --> <service name="returnError" engine="java" location="com.ofbiz.demo.dispatcher.DispatcherReturnDemoService" invoke="returnError"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

E.

怎么把一个服务的失败返回结果转成业务异常类抛出

1) 在 com.ofbiz.demo.dispatcher.DispatcherReturnDemoService 类中编写一个方法 【checkResult】,内容如下:
/** * 怎么把一个服务的失败返回结果转成业务异常类抛出(这个仅仅是一个方法, 不是一个 服务) * @param dctx * @param context * @return */ public static void returnInMethod( LocalDispatcher dispatcher ) throws BusinessException{ //..... //其它代码 //....... //调用服务 Map<String,Object> output = null; try{ Map<String,Object> input = FastMap.newInstance(); output = dispatcher.runSync("returnSuccess", input); }catch(Exception e){ //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把异常类型转成指定类型,并抛出 throw new BusinessException(e,DemoErrorMapping.BASE0000); } //检查该服务是否已经执行成功, 如果没有执行成功,把返回结果转成业务异常类抛 出 if( !ServiceUtil.isSuccess(output) ){ throw new BusinessException(output); } //..... //其它代码 //....... }

四、 实体引擎
1. 获得实体引擎对象

A.

在服务内部怎么获得实体引擎对象

在服务内部,我们可以从服务的输入参数【DispatchContext dctx】中得到我们想要的 实体引擎。具体方法如下:
public static Map<String,Object> createUomOneDemo(DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //...... return ReturnMapUtil.getSuccessMap(); }

B.

在服务外部怎么获得实体引擎对象

在服务外部,我们需要自己通过静态方法【GenericDelegator.getGenericDelegator】取得。 具体方法如下: GenericDelegator delegator = GenericDelegator.getGenericDelegator("default"); 2. 插入操作

A.

通用查收操作

编写一个服务 createUomOneDemo,该服务的作用是在表 Uom 中增加一条记 录,其中字段 uomId 的值为“BaseLineProduct” 、字段 abbreviation 的值为“BLP” 、 字段 description 的值为“基线产品” 1) 在 com.ofbiz.demo.delegator.DelegatorCreateDemoService 中编写 createUomOneDem()方法, 在这个方法中把”基线产品”的信息添加到数据库
/** * * 编写一个服务createUomOneDemo, * 该服务的作用是在表Uom中增加一条记录,其中:

* *

字段uomId的值为“BaseLineProduct”、 字段abbreviation的值为“BLP”、

* 字段description的值为“基线产品” * @param dctx * @param context * @return */ public static Map<String,Object> createUomOneDemo( DispatchContext dctx, Map<String,Object> context) { //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //创建一条Uom记录的对象 GenericValue oneUom = delegator.makeValue("Uom"); //向其中加入每个字段对应的数据 oneUom.setString("uomId","BaseLineProduct"); oneUom.setString("abbreviation", "BLP"); oneUom.setString("description", "基线产品"); try { //保存到数据库的Uom表中 oneUom.create(); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 Return ReturnMapUtil.getErrorMap( DemoErrorMapping.BASE0001,oneUom.toString()) ; } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_delegator_create_deom.xml 中把这个方法配 制成服务
<!-- 向Uom表中增加一条基线产品信息的记录 刘伟东 2013.03.31 --> <service name="createUomOneDemo" engine="java" location="com.ofbiz.demo.delegator.DelegatorDemoService" invoke="createUomOneDemo"> <attribute name="returnCode" type="Map" mode="OUT"

optional="true" /> </service>

3) 在 ServiceUi 文件夹下的 servicesUi_delegatordeom.xml 中把这个服务配置成 ServiceUi 接口
<!-- 向Uom表中增加一条基线产品信息的记录 刘伟东 2013.03.31 --> <service name="createUomOneDemo" title="添加基线产品信息" />

B.

自动产生主键的插入操作

编写一个服务 createUomTwoDemo,该服务的作用是在表 Uom 中增加一条记 录 , 其中字段 uomId 要求自动生成、字段 abbreviation 的值为“ Cashm ” ,字段 description 的值为“现金管理系统” 1) 在 com.ofbiz.demo.delegator.DelegatorCreateDemoService 中编写 createUomTwoDemo()方法, 在这个方法中把”基线产品”的信息添加到数据库
/** * * 编写一个服务createUomTwoDemo, * 该服务的作用是在表Uom中增加一条记录,其中: * * 字段uomId要求自动生成、 字段abbreviation的值为“Cashm”,

* 字段description的值为“现金管理系统” * @param dctx * @param context * @return */ public static Map<String,Object> createUomTwoDemo( DispatchContext dctx, Map context) { //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //创建一条Uom记录的对象 GenericValue oneUom = delegator.makeValue("Uom"); //向其中加入每个字段对应的数据 String uomId = delegator.getNextSeqId("Uom"); //该方法用 于自动创建一个实体的主键编号, 这里创建了Uom表的主键(uomId)的编号 oneUom.setString("uomId",uomId); oneUom.setString("abbreviation", "Cashm");

oneUom.setString("description", "现金管理系统"); try { //保存到数据库的Uom表中 oneUom.create(); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap( DemoErrorMapping.BASE0001,oneUom.toString()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); } }

2) 在 servicedef 文件夹下的 services_delegator_create_deom.xml 中把这个方法配 制成服务
<!-- 向Uom表中增加一条现金管理系统信息的记录 刘伟东 2013.03.31 --> <service name="createUomTwoDemo" engine="java" location="com.ofbiz.demo.delegator.DelegatorDemoService" invoke="createUomTwoDemo"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

3.

删除操作

A.

根据主键进行删除

编写一个服务 deleteUomByPrimaryKey,该服务的作用是在表 Uom 中根据主键 uonId = BaseLineProduct , 删除基线产品信息。 1) 在 com.ofbiz.demo.delegator.DelegatorDeleteDemoService 中编写 deleteUomByPrimaryKey()方法, 在这个方法中删除“基线产品信息” 。
/** * 按主键进行删除

* @param dctx * @param context * @return */ public static Map<String,Object> deleteUomByPrimaryKey( DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //TODO 在这里考虑的不是很全面, 还需要讨论一下: 1) MiscMap方式 delegator.makePKSingle方法 Map<String,Object> pkFields = FastMap.newInstance(); pkFields.put("uomId", "BaseLineProduct"); //这里删除前面创建的基 线产品信息 GenericPK primaryKey = delegator.makePK("Uom", pkFields); try { //执行按主键删除操作 delegator.removeByPrimaryKey(primaryKey); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0002,primaryKey.toStri ng()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); } 2)

2) 在 servicedef 文件夹下的 services_delegator_delete_deom.xml 中把这个方法配 制成服务
<!-- 从Uom表中删除基线产品信息的记录 刘伟东 2013.04.05 --> <service name="deleteUomByPrimaryKey" engine="java" location="com.ofbiz.demo.delegator.DelegatorDeleteDemoService" invoke="deleteUomByPrimaryKey"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

B.

根据多条件进行删除

编写一个服务 updateUomByMoreField,该服务的作用是在表 Uom 中根据条件 abbreviation(缩写) = “Cashm” 和 description(描述) = “现金管理系统” ,删除现金管理 系统的信息. 1) 在 com.ofbiz.demo.delegator.DelegatorDeleteDemoService 中编写 updateUomByMoreField()方法, 在这个方法中删除现金管理系统信息
/** * 按多条件进行删除, 并且这些条件是'与' 的关系, 一般是当删除条件为非主键时使 用 * @param dctx * @param context * @return */ public static Map<String,Object> deleteUomByOtherFields(DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //TODO 在这里考虑的不是很全面, 还需要讨论一下: MiscMap方式

//这里删除前面创建的现金管理系统信息 Map<String,Object> deleteFields = FastMap.newInstance(); deleteFields.put("abbreviation", "Cashm"); deleteFields.put("description", "现金管理系统"); try { //根据设定的条件执行删除操作 delegator.removeByAnd("Uom", deleteFields); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0002,deleteFields.toSt ring()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap();

}

2) 在 servicedef 文件夹下的 services_delegator_delete_deom.xml 中把这个方法配 制成服务
<!-- 从Uom表中删除现金管理系统信息的记录 刘伟东 2013.04.05 --> <service name="deleteUomByOtherFields" engine="java" location="com.ofbiz.demo.delegator.DelegatorDeleteDemoService" invoke="deleteUomByOtherFields"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

C.

根据一个字段有多个值时进行删除

编写一个服务 deleteUomByMoreValues, 该服务的作用是在表 Uom 中根据条件 abbreviation = BLP 或 Cashm 时删除其中符合条件的信息。 1) 在 com.ofbiz.demo.delegator.DelegatorDeleteDemoService 中编写 deleteUomByMoreValues()方法, 在这个方法中删除符合条件的信息。
/** * 根据一个字段的多个值,删除记录 * @param dctx * @param context * @return */ public static Map<String,Object> deleteUomByMoreValues(DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //这里删除前面创建的"基线产品信息"和"现金管理系统信息" Map<String,Object> deleteFields = FastMap.newInstance(); deleteFields.put("abbreviation", "BLP"); deleteFields.put("abbreviation", "Cashm"); //收集删除条件 EntityCondition deleteBLPCon

=

EntityCondition.makeCondition("abbreviation", EntityOperator.EQUALS, "BLP"); EntityCondition deleteCashmCon "Cashm"); EntityCondition deleteCondition = EntityCondition.makeCondition(deleteBLPCon, EntityOperator.OR, deleteCashmCon); try { System.err.println("删除条件: " + deleteCondition.toString()); //根据设定的条件执行删除操作 delegator.removeByCondition("Uom", deleteCondition); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0002,deleteCondition.t oString()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); } = EntityCondition.makeCondition("abbreviation", EntityOperator.EQUALS,

2) 在 servicedef 文件夹下的 services_delegator_delete_deom.xml 中把这个方法配 制成服务
<!-- 从Uom表中删除基线产品信息和现金管理系统信息的记录 --> <service name="deleteUomByMoreValues" engine="java" location="com.ofbiz.demo.delegator.DelegatorDeleteDemoService" invoke="deleteUomByMoreValues"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service> 刘伟东 2013.04.05

3) 在 ServiceUi 文件夹下的 servicesUi_delegatordeom.xml 中把这个服务配置成 ServiceUi 接口
<!-- 从Uom表中删除基线产品信息和现金管理系统信息的记录 --> <service name="deleteUomByMoreValues" title="删除基线产品信息和现金管 刘伟东 2013.04.05

理系统信息的记录" />

D.

根据时间段进行删除

编写一个服务 deleteUomByDate, 该服务的作用是在表 Uom 中根据输入的时间 段删除符合条件的数据,输入的日期格式为:yyyymmdd。 1) 在 com.ofbiz.demo.delegator.DelegatorDeleteDemoService 中编写 deleteUomByDate()方法, 在这个方法中删除符合条件的信息
/** * 删除一个时间段内的数据 * @param dctx * @param context * @return */ public static Map<String,Object> deleteUomByDate(DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //从输入参数中取出开始日期和结束日期 String beginDateStr = (String) context.get("beginDate"); String endDateStr = (String) context.get("endDate");

//设置查询条件: 记录时间 大于 beginDate ,记录时间 小于 endDate List<EntityCondition> conList = FastList.newInstance(); //如果传入的开始日期不为空,则设置删除条件: 删除的记录不能早于开始日期 if( UtilValidate.isNotEmpty(beginDateStr)){ try { //先把开始日期的字符串转成Timestamp格式 Timestamp beginDate = UtilDateTime.stringToTimeStamp(beginDateStr, InnerConstant.DATE_FORMAT, TimeZone.getDefault(), Locale.CHINA); //再把整个日期的时间部分设置成 00:00:00.000 beginDate = UtilDateTime.getDayStart(beginDate); //设置查询条件: 记录时间 大于 beginDate EntityCondition startDateCon = EntityCondition.makeCondition("createdStamp", EntityOperator.GREATER_THAN_EQUAL_TO, beginDate); conList.add(startDateCon); } catch (ParseException e) { //则把错误信息以Error级别打印到日志文件中

Debug.logError(e, module); return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0003,beginDateStr,e.ge tMessage()); } } //如果传入的结束日期不为空, 则设置删除条件: 删除的记录不能晚于结束日期 if( UtilValidate.isNotEmpty(endDateStr)){ try { //先把结束日期的字符串转成Timestamp格式 Timestamp endDate = UtilDateTime.stringToTimeStamp(endDateStr, InnerConstant.DATE_FORMAT, TimeZone.getDefault(), Locale.CHINA); System.err.println(endDate.toString()); //再把结束日期的时间部分设置成: 23:59:59.999 endDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp()); //设置查询条件: 记录时间 小于 endDate EntityCondition endTimeCon = EntityCondition.makeCondition("createdStamp", EntityOperator.LESS_THAN_EQUAL_TO, endDate); conList.add(endTimeCon); } catch (ParseException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0004,endDateStr,e.getM essage()); } } EntityCondition deleteCondition = EntityCondition.makeCondition(conList, EntityOperator.AND); try { //根据设定的条件执行删除操作 delegator.removeByCondition("Uom", deleteCondition); } catch (GenericEntityException e) { //则把错误信息以Error级别打印到日志文件中 Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0002,deleteCondition.t oString());

} //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_delegator_delete_deom.xml 中把这个方法配 制成服务
<!-- 从Uom表中删除一段日期内的记录 刘伟东 2013.04.05 --> <service name="deleteUomByDate" engine="java" location="com.ofbiz.demo.delegator.DelegatorDeleteDemoService" invoke="deleteUomByDate"> <attribute name="beginDate" type="String" mode="IN" optional="true" /> <attribute name="endDate" type="String" mode="IN" optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

4.

修改操作

A.

根据一个字段进行修改

编写一个服务 updateUomByOneField,该服务的作用是在表 Uom 中根据主键 abbreviation = Cashm, 把现金管理系统的描述信息由“现金管理系统”为“修改后 的现金管理系统” 。 1) 在 com.ofbiz.demo.delegator.DelegatorUpdateDemoService 中编写 updateUomByOneField()方法, 在这个方法中修改现金管理系统的描述信息。
/** * 根据一个字段进行修改(这个条件字段可以是主键, 也可以不是主键) * @param dctx * @param context * @return */

public static Map<String,Object> updateUomByOneField( DispatchContext dctx, Map<String,Object> context ){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //添加需要修改的字段 Map<String,Object> updateFields = FastMap.newInstance(); updateFields.put("description", "修改后的现金管理系统"); 除前面创建的基线产品信息 /*.... 如果有其它字段需要修改, 还可以继续把要修改的值放到updateFields 中.*/ //设置修改条件 EntityCondition updateCon = EntityCondition.makeCondition("abbreviation", EntityComparisonOperator.EQUALS,"Cashm"); try { //执行按条件修改操作 delegator.storeByCondition("Uom", updateFields, updateCon); } catch (GenericEntityException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0005,updateCon.toStrin g(),e.getMessage()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); } //这里删

2) 在 servicedef 文件夹下的 services_delegator_update_deom.xml 中把这个方法配 制成服务
<!-- 根据一个字段在Uom表中修改现金管理系统的描述信息 --> <service name="updateUomByOneField" engine="java" location="com.ofbiz.demo.delegator.DelegatorUpdateDemoService" invoke="updateUomByOneField"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> 刘伟东 2013.04.07

</service>

B.

根据多条件进行修改

编写一个服务 updateUomByMoreField ,该服务的作用是在表 Uom 中根据 abbreviation= BLP 和 description = 基线产品, 修改基线产品的 uomTypeId 属性为 OTHER_MEASURE。 1) 在 com.ofbiz.demo.delegator.DelegatorUpdateDemoService 中编写 updateUomByMoreField()方法, 在这个方法中修改基线产品信息的 uomTypeId 属性。
/** * 根据多个字段进行修改(这个条件字段可以是主键, 也可以不是主键) * @param dctx * @param context * @return */ public static Map<String,Object> updateUomByMoreField( DispatchContext dctx, Map<String,Object> context ){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //添加需要修改的字段 Map<String,Object> updateFields = FastMap.newInstance(); updateFields.put("uomTypeId", "OTHER_MEASURE"); 创建的基线产品信息 /*.... 如果有其它字段需要修改, 还可以继续把要修改的值放到updateFields 中.*/ //设置修改条件 List<EntityCondition> updateConList = FastList.newInstance(); updateConList.add( EntityCondition.makeCondition("abbreviation", EntityComparisonOperator.EQUALS,"BLP") ); updateConList.add( EntityCondition.makeCondition("description", EntityComparisonOperator.EQUALS,"基线产品") ); /*.... 如果有其它的修改条件, 还可以继续把修改条件放到updateConList中*/ //这里删除前面

EntityCondition updateCondition = EntityCondition.makeCondition(updateConList, EntityOperator.AND); try { //执行按条件修改操作 delegator.storeByCondition("Uom", updateFields, updateCondition); } catch (GenericEntityException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0005,updateCondition.t oString(),e.getMessage()); } //把表示成功的信息返回给服务调用者 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_delegator_update_deom.xml 中把这个方法配 制成服务
<!-- 根据多个字段在Uom表中修改现金管理系统的描述信息 --> <service name="updateUomByMoreField" engine="java" location="com.ofbiz.demo.delegator.DelegatorUpdateDemoService" invoke="updateUomByMoreField"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service> 刘伟东 2013.04.07

C.

对一个已经查询出的记录进行修改

编写一个服务 updateUomAfterQuery ,该服务的作用是先根据主键 uonId = BaseLineProduct 查询出基线产品信息, 再把其中的描述信息由 “基线产品” 改为 “修 改后的基线产品” 。 1) 在 com.ofbiz.demo.delegator.DelegatorUpdateDemoService 中编写 updateUomAfterQuery()方法, 在这个方法中先查询基线产品信息,再修改 其描述属性。

/** * 对已经查询出的记录进行修改 * @param dctx * @param context * @return */ public static Map<String,Object> updateUomAfterQuery( DispatchContext dctx, Map<String,Object> context ){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //获取服务引擎 LocalDispatcher dispatcher = dctx.getDispatcher(); //先调用查询服务从Uom表中查询出基线产品信息 Map<String,Object> queryInput = FastMap.newInstance(); Map<String,Object> queryOutput = null; try { queryOutput = dispatcher.runSync("queryUomByPrimaryKey", queryInput); } catch (GenericServiceException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0007,e.getMessage()); } //根据返回Map检查服务是否执行成功 if( !ServiceUtil.isSuccess(queryOutput)){ return queryOutput; } //从返回结果中取出查询到的基线产品信息 GenericValue oneUom = (GenericValue) queryOutput.get("oneUom"); //修改基线产品信息中的描述 oneUom.setString("description", "修改后的基线产品信息"); //保存 try { oneUom.store(); } catch (GenericEntityException e) {

Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0008,e.getMessage()); } //返回 return ReturnMapUtil.getSuccessMap(); }

2) 在 servicedef 文件夹下的 services_delegator_update_deom.xml 中把这个方法配 制成服务
<!-- 对已经查询出的基线产品记录进行修改 刘伟东 2013.04.07 --> <service name="updateUomAfterQuery" engine="java" location="com.ofbiz.demo.delegator.DelegatorUpdateDemoService" invoke="updateUomAfterQuery"> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

5.

查询操作

A.

根据主键查询

编写一个服务 ,该服务的作用是在 Uom 表中,根据主键 uomId = “BaseLineProduct” ,查询出基线产品的信息(编号、缩写、描述) 1) 在 com.ofbiz.demo.delegator.DelegatorQueryDemoService 中编写 queryUomByPrimaryKey ()方法, 在这个方法中查询基线产品信息。
/** * 按主键进行查询 * @param dctx * @param context * @return */ public static Map<String,Object> queryUomByPrimaryKey( DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator();

//设置查询条件 //TODO 在这里考虑的不是很全面, 还需要讨论一下: MiscMap方式 Map<String,Object> queryCon = FastMap.newInstance(); queryCon.put("uomId", "BaseLineProduct"); //执行查询操作 GenericValue oneUom = null; try { oneUom = delegator.findOne("Uom", queryCon, true); } catch (GenericEntityException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0006,queryCon.toS tring(),e.getMessage()); } //返回结果 Map<String,Object> output = ReturnMapUtil.getSuccessMap(); output.put("oneUom", oneUom); return output; }

2) 在 servicedef 文件夹下的 services_delegator_query_deom.xml 中把这个方法配 制成服务
<!-- 根据主键在Uom表中查询基线产品信息 刘伟东 2013.04.07 --> <service name="queryUomByPrimaryKey" engine="java" location="com.ofbiz.demo.delegator.DelegatorQueryDemoService" invoke="queryUomByPrimaryKey"> <attribute name="oneUom" type="com.ofbiz.entity.GenericValue" mode="OUT" optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

B.

根据多条件查询

在 Uom 表中, 根据缩写 【abbreviation】 = “Cashm” 和 描述 【description】 =“现金管理系统” 查询所有的现金管理系统信息。

1) 在 com.ofbiz.demo.delegator.DelegatorQueryDemoService 中编写 queryUomByMoreValue ()方法, 在这个方法中查询现金管理系统信息
/** * 根据多个条件进行查询 * @param dctx * @param context * @return */ public static Map<String,Object> queryUomByMoreValue(DispatchContext dctx, Map<String,Object> context){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //设置查询条件 Map<String,Object> queryCondition = FastMap.newInstance(); queryCondition.put("abbreviation", "Cashm"); queryCondition.put("description", "现金管理系统"); List<GenericValue> resultList = null; try { resultList = delegator.findByAnd("Uom",queryCondition); } catch (GenericEntityException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0006,queryCondition.to String(),e.getMessage()); } //返回结果 Map<String,Object> output = ReturnMapUtil.getSuccessMap(); output.put("resultList", resultList); return output; }

2) 在 servicedef 文件夹下的 services_delegator_query_deom.xml 中把这个方法配 制成服务
<!-- 根据多个条件查询现金管理系统信息 刘伟东 2013.04.07 --> <service name="queryUomByMoreValue" engine="java" location="com.ofbiz.demo.delegator.DelegatorQueryDemoService" invoke="queryUomByMoreValue"> <attribute name="resultList" type="List" mode="OUT"

optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

C.

对多张表进行关联查询

编写一个服务,查询个人信息,这些个人信息存放在 3 个表中,他们之间是通 过 PartyId 管理在一起的。 这三张表分别为: Party 、 UserLogin 和 Person , 其中: Party 表中保存有 partyId(当事人编号) 、partyTypeId(当事人类型) ; UserLogin 表中保存有 userLoginId(登陆编号) 、password(密码) ; Person 表中保存有 firstName(用户姓名) 、 birthDate(生日) 1) 在 com.ofbiz.demo.delegator.DelegatorQueryDemoService 中编写 queryMoreTable ()方法, 在这个方法中查询个人信息
/** * 多表联合查询 * @param dctx * @param context * @return */ public static Map<String,Object> queryMoreTable( DispatchContext dctx, Map<String,Object> context ){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); // 使用动态视图查询批处理信息 // dynamic view entity DynamicViewEntity dve = new DynamicViewEntity(); //当事人表 dve.addMemberEntity("Party", "Party"); dve.addAliasAll("Party", null); // Party表中的字段全部显示,并且都不 设置前缀 //登陆信息表 dve.addMemberEntity("UL", "UserLogin"); dve.addAlias("UL", "userLoginId"); dve.addAlias("UL", "currentPassword"); dve.addAlias("UL", "ulEnabled", "enabled", null, null, null, null); // 重命名

// 左外连接 dve.addViewLink("Party", "UL", Boolean.TRUE, UtilMisc.toList(new ModelKeyMap("partyId", "partyId"))); //个人信息表 dve.addMemberEntity("Person", "Person"); dve.addAlias("Person", "name", "firstName", null, null, null, null); // 重命名 dve.addAlias("Person", "birthDate"); dve.addAlias("Person", "createdStamp"); // 内连接 dve.addViewLink("Party", "Person", Boolean.FALSE, UtilMisc.toList(new ModelKeyMap("partyId", "partyId"))); // 取得查询条件 EntityCondition conditions = EntityCondition.makeCondition("partyTypeId", EntityOperator.EQUALS, "PERSON"); EntityFindOptions opts = new EntityFindOptions(); opts.setResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE); //该 字段的设置, 在采用分页查询时才会用到, 因为结果集类型为这个值时,游标才可以向回滚动. List<GenericValue> personInfos = FastList.newInstance(); int personCount 作数据的.和数据库中的结果集功能类似 try { personIterator = delegator.findListIteratorByCondition(dve, conditions, null, null, null, opts); //查询出符合条件的记录的总个数 personIterator.last(); 索引,就是记录的总个数 //把游标移动到最开始位置 personIterator.beforeFirst(); GenericValue onePerson = null; while ( personIterator.hasNext() ) { onePerson = personIterator.next(); personInfos.add(onePerson); //因为这是个测试程序,为了防止数据溢出,我查询出20条件就不查询了,下面的 是检查代码,如果记录已经有20条时,跳出循环. //在正常使用时,我们一般会分页的方式来解决大数据量问题 if( personInfos.size() >= 20){ //让游标移动到最后 personCount = personIterator.currentIndex(); //取出此时的游标 = 0; EntityListIterator personIterator = null; //实体集合迭代器, 用来操

break; } } } catch (GenericEntityException e) { Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0009,e.getMessage()); } finally { // 关闭迭代器(一定要记得关闭哦,不然就死定了) if (UtilValidate.isNotEmpty(personIterator)) { try { personIterator.close(); } catch (GenericEntityException e) { Debug.logError(e, module); } } } //返回 Map<String, Object> result = FastMap.newInstance(); result.put("personInfos", personInfos); result.put("personCount", personCount); return result; }

2) 在 servicedef 文件夹下的 services_delegator_query_deom.xml 中把这个方法配 制成服务
<!-- 从多张表中查询个人信息 刘伟东 2013.04.07 --> <service name="queryMoreTable" engine="java" location="com.ofbiz.demo.delegator.DelegatorQueryDemoService" invoke="queryMoreTable"> <attribute name="personInfos" type="List" mode="OUT" optional="true" /> <attribute name="personCount" type="Integer" mode="OUT" optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>

D.

分页查询

在 Uom 表中,根据缩写【abbreviation】= “Cashm” 和 描述【description】 = “现金管理系统” 查询现金管理系统信息, 每次只需要显示用户指定的记录数据。 用户会使用 startIndex(起始行号)和 count(显示个数)来控制显示哪些数 据。 1) 在 com.ofbiz.demo.delegator.DelegatorQueryDemoService 中编写 queryUomByPage ()方法, 在这个方法中采用分页的方式来查询现金管理系 统信息
/** * 操作分页方式进行查询 * @param dctx * @param context * @return */ public static Map<String,Object> queryUomByPage(DispatchContext dctx, Map<String,Object> context ){ //取得实体引擎实例 GenericDelegator delegator = dctx.getDelegator(); //取得 int startIndex = (Integer) context.get("startIndex"); int count = (Integer) context.get("count"); //设置查询条件 List<EntityCondition> queryConList = FastList.newInstance(); queryConList.add( EntityCondition.makeCondition("abbreviation", EntityComparisonOperator.EQUALS,"Cashm") ); queryConList.add( EntityCondition.makeCondition("description", EntityComparisonOperator.EQUALS,"现金管理系统") ); /*.... 如果有其它的查询条件, 还可以继续把查询条件放到updateConList中*/ EntityCondition queryCondition = EntityCondition.makeCondition(queryConList, EntityOperator.AND); List<GenericValue> resultList = null; try { resultList = delegator.findList("Uom", queryCondition, null, null, null, true, startIndex, count); } catch (GenericEntityException e) {

Debug.logError(e, module); //把指定的错误码对应的描述信息返回给服务调用者 return ReturnMapUtil.getErrorMap(DemoErrorMapping.BASE0006,queryCondition.to String(),e.getMessage()); } //返回结果 Map<String,Object> output = ReturnMapUtil.getSuccessMap(); output.put("resultList", resultList); return output; }

2) 在 servicedef 文件夹下的 services_delegator_query_deom.xml 中把这个方法配 制成服务
<!-- 采用分页方式查询现金管理系统信息 刘伟东 2013.04.07 --> <service name="queryUomByPage" engine="java" location="com.ofbiz.demo.delegator.DelegatorQueryDemoService" invoke="queryUomByPage"> <attribute name="startIndex" type="Integer" mode="IN" optional="false" /> <attribute name="count" type="Integer" mode="IN" optional="false" /> <attribute name="resultList" type="List" mode="OUT" optional="true" /> <attribute name="returnCode" type="Map" mode="OUT" optional="true" /> </service>


赞助商链接
相关文章:
更多相关标签: