OFBiz实体引擎开发烹调书 (三)

* 如何为SELECT SUM(QUANTITY - CANCEL_QUANTITY) AS QUANTITY之类的语句设置别名

  <alias entity-alias="OI" name="quantity" function="sum">
      <complex-alias operator="-">
          <complex-alias-field entity-alias="OI" field="quantity" default-value="0"/>
          <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0"/>
      </complex-alias>
  </alias> 
 


  SELECT SUM(COALESCE(OI.QUANTITY,'0') - COALESCE(0I.CANCEL_QUANTITY)) AS QUANTITY在结果集包含默认值是一个好的习惯,否则如果有一项为null,那么最终相减的结果就也为null了.
  操作符可以为任何你当前使用数据库所支持的SQL操作符,比如算术运算符+, -, * 和/ 或者字符串连接符 ||.

  你可以增加function=""标签来完成在complex-alias-field中的min, max, sum, avg, count, count-distinct, upper 及lower集合运算.  示例, 以上的定义可以用另一种方法表示为:

  <alias entity-alias="OI" name="quantity">
      <complex-alias operator="-">
          <complex-alias-field entity-alias="OI" field="quantity" default-value="0" function="sum"/>
          <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0" function="sum"/>
      </complex-alias>
  </alias>



  即为SELECT (SUM(COALESCE(OI.QUANTITY,'0')) - SUM(COALESCE(OI.CANCEL_QUANTITY,'0'))) AS QUANTITY查询结果集

* 我讨厌OFBiz的实体引擎,我要自己的JDBC连接!
  好的,以下是你获得JDBC连接的方法:

import org.ofbiz.entity.jdbc.ConnectionFactory;

String helperName = delegator.getGroupHelperName("org.ofbiz");    // gets the helper (localderby, localmysql, localpostgres, etc.) for your entity group org.ofbiz
Connection conn = ConnectionFactory.getConnection(helperName); 
Statement statement = conn.createStatement();
statement.execute("SELECT * FROM PARTY");
ResultSet results = statement.getResultSet();

//  通过普通JDBC 的结果集来操作

//Alternatively, you can use the SQLProcessor like this:

SQLProcessor sqlproc = new SQLProcessor(helperName);
sqlproc.prepareStatement("SELECT * FROM PARTY");
ResultSet rs1 = sqlproc.executeQuery();

ResultSet rs2 = sqlproc.executeQuery("SELECT * FROM PRODUCT");



你可以查看framework/webtools/webapp/webtools/WEB-INF/actions/entity/EntitySQLProcessor.bsh了解它的使用

在以下网址你可以获得相关JavaDoc的内容:
http://www.opentaps.org/javadocs/version-1.0/framework/api/org/ofbiz/entity/jdbc/SQLProcessor.html
http://www.opentaps.org/javadocs/version-1.0/framework/api/org/ofbiz/entity/jdbc/ConnectionFactory.html

  *** 请先考虑以下内容: 你放弃数据库的无关性意味着你在某些方法将无法与框架或共它程序相共通.你确定你要这么做吗?

获得更好的做法,请访问 http://www.opentaps.org/docs/index.php/Using_the_Query_Tool

* 关于时间比较方法的一些警告

在你用 GREATER_THAN比较一个 Timestamp类型数据时, 你有可能获得相同的时间数据:

delegator.findByAnd("XXX", UtilMisc.toList(new EntityExpr("fromDate", EntityOperator.GREATER_THAN, "2007-12-31 23:59:59.998")));


有可能包含fromDate=2007-12-31 23:59:59.998的数据.  (此种情况发生于PostgreSQL 8.1并且GenericDAO 类生成的SQL代码是'FROM_DATE > ' so 所以我也不明白发生这个问题的原因.) 所以确保安全的方法是, 增加1秒到需要比较的时间中然后使用 GREATER_THAN_EQUAL_TO方法

delegator.findByAnd("XXX", UtilMisc.toList(new EntityExpr("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, "2008-01-01 00:00:00.998")));



* 警告: 在空集合中使用EntityOperator.IN

请小心如果使用EntityOperator.IN去判断一个非空集合在一个空集合中的包含项,你有可能获得一个语法错误: 在Derby或者其它一些不为人知的数据库中可能会出错.
所以建议你能在使用EntityOperator.IN之间,通常执行UtilValidate.isNotEmpty方法来判断一下结果集是否为空

* 警告: delegator.getNextSubSeqId 不能确保唯一性

很多实体有很多合成的主键.示例OrderItem's 主键是orderId + orderItemSeqId.  InventoryItemDetail's 主键是inventoryItemId +inventoryItemSeqId.  通常, delegator.getNextSubSeqId 通常是获得一个序列值,但是在多线程的访问下有可能无法确保生成的值的唯一性.  此段内容在
http://issues.apache.org/jira/browse/OFBIZ-1636 中有相关文档记录.

当前, 如果有可能多个线程尝试同时写入实体组合键时,可以使用delegator.getNextSeqId来替代getNextSubSeqId.  (此问题不会发生于OrderItem, 因为它只使用单线程写入, 但有可能发生于 InventoryItemDetail, 它使用多线程来创建库存记录项.)


完>>

本文档译自ofbiz 4.0 cookbooks,本人翻译,欢迎转载,请注明出处.

你可能感兴趣的:(多线程,sql,jdbc,PostgreSQL,Derby)