Jfinal如何支持自定义model类型?

天生蛋疼菊紧 发布于 2015/04/28 10:47
阅读 529
收藏 1

@JFinal 波总你好:

又来打扰你了。之前已经就一些问题与你有过沟通。

我这边需要自定义model类型,用来继承model,主要目的是引入领域模型思想。按照model进行职责隔离。

请问波总,Jfinal中如何导入领域模型呢?我尝试定义了新的实体,都是强类型的,在json to model转换的时候,用自定义的强类型model类型去承载。

但是有一个问题。属性从强类型的model需要赋值到弱类型的Record实体,才能保存。再次引入了model映射组件,尝试属性自动映射,以失败告终。

现在思路是定义一个弱类型的model,用来继承Jfinal的基础model。在json to在model的时候,指定反序列化为自定义的model,然后再直接save,省略掉很多无意义的属性赋值语句。

请问这个思路是否行得通,具体如何操作,才能使得jfinal和领域模型的思想无缝结合呢?

期待你的回复。

加载中
0
JFinal
JFinal
    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。
0
天生蛋疼菊紧
天生蛋疼菊紧

引用来自“JFinal”的评论

    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。
/**
 * 客户订单表
 * @author canyou 
 */
@TableBind(tableName = "SL_mk_Schema.CustomerOrder",pkName="COId")
public class CustomerOrder extends BaseModel<CustomerOrder>{

	private static final long serialVersionUID = 1L;
	
	public static final String TABLE_NAME = "SL_mk_Schema.CustomerOrder";
	
	/**
 	 *客户订单id
 	 */
	public static final String KEY_COID = "COId";
	/**
 	 *系统订单号(系统内使用)
 	 */
	public static final String KEY_CONO = "CONo";
	/**
 	 *客户源订单号(深联客户发给深联的订单编号)
 	 */
	public static final String KEY_COSOURCENO = "COSourceNo";
	/**
 	 *订单来源(0所有,1系统订单,2非系统订单)
 	 */
	public static final String KEY_ORDERORIGIN = "OrderOrigin";
	/**
 	 *是否打印(1是0否)
 	 */
	public static final String KEY_ISPRINT = "IsPrint";
	/**
 	 *是否按订单暂缓(1是0否)
 	 */
	public static final String KEY_ISDEFER = "IsDefer";
	/**
 	 *是否有报价(1是0否)
 	 */
	public static final String KEY_ISOFFERPRICE = "IsOfferPrice";
	/**
 	 *客户id
 	 */
	public static final String KEY_CONSUMERID = "ConsumerId";
	/**
 	 *客户名称
 	 */
	public static final String KEY_CONSUMERNAME = "ConsumerName";
	/**
 	 *客户代码
 	 */
	public static final String KEY_CONSUMERCODE = "ConsumerCode";
	/**
 	 *币种Id
 	 */
	public static final String KEY_CURRENCYTYPEID = "CurrencyTypeId";
	/**
 	 *币种
 	 */
	public static final String KEY_CURRENCYTYPE = "CurrencyType";
	/**
 	 *汇率Id
 	 */
	public static final String KEY_EXCHANGERATEID = "ExchangeRateId";
	/**
 	 *汇率
 	 */
	public static final String KEY_EXCHANGERATE = "ExchangeRate";
	/**
 	 *税率(百分比),客户资料预设
 	 */
	public static final String KEY_TAXRATE = "TaxRate";
	/**
 	 *月结方式是否变更(1变更,0未变更)
 	 */
	public static final String KEY_ISSAPCHANGE = "IsSapChange";
	/**
 	 *结算类型(0所有,1系统结算,2订单结算)
 	 */
	public static final String KEY_SAP = "Sap";
	/**
 	 *付款方式id
 	 */
	public static final String KEY_PAYTYPEID = "PayTypeId";
	/**
 	 *付款方式名称
 	 */
	public static final String KEY_PAYTYPE = "PayType";
	/**
 	 *总税额(原币)
 	 */
	public static final String KEY_SOURCETAXTOTAL = "SourceTaxTotal";
	/**
 	 *总税额(本位币)
 	 */
	public static final String KEY_TAXTOTAL = "TaxTotal";
	/**
 	 *是否客户确认(1是0否)
 	 */
	public static final String KEY_ISCONFIRMED = "IsConfirmed";
	/**
 	 *客户对订单数据确认日期
 	 */
	public static final String KEY_CONFIRMDATE = "ConfirmDate";
	/**
 	 *更改客户确认标志人
 	 */
	public static final String KEY_CONFIRMBY = "ConfirmBy";
	/**
 	 *是否作废(1是0否)
 	 */
	public static final String KEY_ISCANCEL = "IsCancel";
	/**
 	 *作废人
 	 */
	public static final String KEY_CANCELBY = "CancelBy";
	/**
 	 *作废时间
 	 */
	public static final String KEY_CANCELDATE = "CancelDate";
	/**
 	 *作废原因
 	 */
	public static final String KEY_CANCELREASON = "CancelReason";
	/**
 	 *是否关闭(1是0否)
 	 */
	public static final String KEY_ISCLOSE = "IsClose";
	/**
 	 *关闭人
 	 */
	public static final String KEY_CLOSEBY = "CloseBy";
	/**
 	 *关闭时间
 	 */
	public static final String KEY_CLOSEDATE = "CloseDate";
	/**
 	 *关闭原因
 	 */
	public static final String KEY_CLOSEREASON = "CloseReason";
	/**
 	 *是否PO后补(1是0否)
 	 */
	public static final String KEY_ISPOWAITING = "IsPOWaiting";
	/**
 	 *PO后补标志更改人
 	 */
	public static final String KEY_POBACKBY = "POBackBy";
	/**
 	 *预计PO补回日期
 	 */
	public static final String KEY_POBACKDATE = "POBackDate";
	/**
 	 *是否复核(1是0否)
 	 */
	public static final String KEY_RECHECKSTATUS = "ReCheckStatus";
	/**
 	 *复核结果(1通过,2不通过)
 	 */
	public static final String KEY_RECHECKRESULT = "ReCheckResult";
	/**
 	 *复核通过日期
 	 */
	public static final String KEY_AUDITDATE = "AuditDate";
	/**
 	 *复审人
 	 */
	public static final String KEY_LASTAUDITBY = "LastAuditBy";
	/**
 	 *复核不通过原因
 	 */
	public static final String KEY_AUDITNOTPASSREASON = "AuditNotPassReason";
	/**
 	 *是否锁定(1是0否)
 	 */
	public static final String KEY_ISLOCK = "IsLock";
	/**
 	 *锁定原因
 	 */
	public static final String KEY_LOCKREASON = "LockReason";
	/**
 	 *解锁人
 	 */
	public static final String KEY_UNLOCKBY = "UnlockBy";
	/**
 	 *解锁时间
 	 */
	public static final String KEY_UNLOCKON = "UnlockOn";
	/**
 	 *解锁原因
 	 */
	public static final String KEY_UNLOCKREASON = "UnlockReason";
	/**
 	 *是否预支付(1是0否)
 	 */
	public static final String KEY_ISPREPAID = "IsPrePaid";
	/**
 	 *预支付金额(原币)
 	 */
	public static final String KEY_PREPAIDTOTAL = "PrePaidTotal";
	/**
 	 *客户订单备注
 	 */
	public static final String KEY_REMARK = "Remark";
	/**
 	 *创建时间
 	 */
	public static final String KEY_CREATEDON = "CreatedOn";
	/**
 	 *创建人
 	 */
	public static final String KEY_CREATEDBY = "CreatedBy";
	/**
 	 *修改时间
 	 */
	public static final String KEY_MODIFIEDON = "ModifiedOn";
	/**
 	 *修改人
 	 */
	public static final String KEY_MODIFIEDBY = "ModifiedBy";
	/**
 	 *版本号
 	 */
	public static final String KEY_VERSION = "Version";
	/**
 	 *PO下产品种类个数
 	 */
	public static final String KEY_POKINDSCOUNT = "POKindsCount";
	/**
 	 *是否存在拖欠款
 	 */
	public static final String KEY_ISHAVEUNPAIDORDER = "IsHaveUnpaidOrder";
	/**
 	 *拖欠款总额
 	 */
	public static final String KEY_UNPAIDORDERTOTAL = "UnpaidOrderTotal";
	/**
 	 *拖欠款天数
 	 */
	public static final String KEY_BACKMENOEYDAYS = "BackMenoeyDays";
	/**
 	 *客户在下单时的信用等级
 	 */
	public static final String KEY_CURRENTCREDITLEVEL = "CurrentCreditLevel";
	/**
 	 *客户在下单时的信用额度
 	 */
	public static final String KEY_CURRENTCREDITLINE = "CurrentCreditLine";
	/**
 	 *是否超过信用额度
 	 */
	public static final String KEY_ISOUTOFCREDITLINE = "IsOutOfCreditLine";
	/**
 	 *订单各个产品的费用之和(不包含额外费用)
 	 */
	public static final String KEY_ORDERPRODUCTSPRICE = "OrderProductsPrice";
	/**
 	 *订单各产品的额外费用之和
 	 */
	public static final String KEY_ORDEREXTENDPRICE = "OrderExtendPrice";
	/**
 	 *订单总额(本位币)
 	 */
	public static final String KEY_LOCALORDERPRICE = "LocalOrderPrice";
	/**
 	 *订单总额(原币)
 	 */
	public static final String KEY_ORDERPRICE = "OrderPrice";
	/**
 	 *交货规律(1可提前出货可跨月交货,2可提前出货但不可跨月交货,3,不能提前只能按期交货,4需等客户排期交货,5延期出货(拼货))
 	 */
	public static final String KEY_SUMMITORDERRULES = "SummitOrderRules";
    
	public static final CustomerOrder dao = new CustomerOrder();
	
	/**
	 * 客户订单关联的所有产品订?
	 */
	public List<ProductOrder> productorders;
	
	/**
	 * 获取客户订单下的所有产品子订单
	 * @return
	 */
	public List<ProductOrder> getProductorders() {
		if(productorders!=null){
			return productorders;
		}
		else{
			String customerOrderId = this.get(CustomerOrder.KEY_COID);
			List<ProductOrder> tmpOrders = ProductOrderService.me().findByCustomerOrderId(customerOrderId);
			return tmpOrders;
		}	
	}

	public void setProductorders(List<ProductOrder> productorders) {
		this.productorders = productorders;
	}

 }

以上是我的一个model定义,你可以看到,是有关系维护的代码在里面的。mode的代码是用模板生成的,每次生成会导致我的更改过的model
被覆盖,model中添加关系维护的代码没有问题,但是如何才能保证充血模型持续维护,有没有好点的维护方式,或者只能手动维护呢?



0
JFinal
JFinal

引用来自“JFinal”的评论

    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。

引用来自“菜花儿”的评论

/**
 * 客户订单表
 * @author canyou 
 */
@TableBind(tableName = "SL_mk_Schema.CustomerOrder",pkName="COId")
public class CustomerOrder extends BaseModel<CustomerOrder>{

	private static final long serialVersionUID = 1L;
	
	public static final String TABLE_NAME = "SL_mk_Schema.CustomerOrder";
	
	/**
 	 *客户订单id
 	 */
	public static final String KEY_COID = "COId";
	/**
 	 *系统订单号(系统内使用)
 	 */
	public static final String KEY_CONO = "CONo";
	/**
 	 *客户源订单号(深联客户发给深联的订单编号)
 	 */
	public static final String KEY_COSOURCENO = "COSourceNo";
	/**
 	 *订单来源(0所有,1系统订单,2非系统订单)
 	 */
	public static final String KEY_ORDERORIGIN = "OrderOrigin";
	/**
 	 *是否打印(1是0否)
 	 */
	public static final String KEY_ISPRINT = "IsPrint";
	/**
 	 *是否按订单暂缓(1是0否)
 	 */
	public static final String KEY_ISDEFER = "IsDefer";
	/**
 	 *是否有报价(1是0否)
 	 */
	public static final String KEY_ISOFFERPRICE = "IsOfferPrice";
	/**
 	 *客户id
 	 */
	public static final String KEY_CONSUMERID = "ConsumerId";
	/**
 	 *客户名称
 	 */
	public static final String KEY_CONSUMERNAME = "ConsumerName";
	/**
 	 *客户代码
 	 */
	public static final String KEY_CONSUMERCODE = "ConsumerCode";
	/**
 	 *币种Id
 	 */
	public static final String KEY_CURRENCYTYPEID = "CurrencyTypeId";
	/**
 	 *币种
 	 */
	public static final String KEY_CURRENCYTYPE = "CurrencyType";
	/**
 	 *汇率Id
 	 */
	public static final String KEY_EXCHANGERATEID = "ExchangeRateId";
	/**
 	 *汇率
 	 */
	public static final String KEY_EXCHANGERATE = "ExchangeRate";
	/**
 	 *税率(百分比),客户资料预设
 	 */
	public static final String KEY_TAXRATE = "TaxRate";
	/**
 	 *月结方式是否变更(1变更,0未变更)
 	 */
	public static final String KEY_ISSAPCHANGE = "IsSapChange";
	/**
 	 *结算类型(0所有,1系统结算,2订单结算)
 	 */
	public static final String KEY_SAP = "Sap";
	/**
 	 *付款方式id
 	 */
	public static final String KEY_PAYTYPEID = "PayTypeId";
	/**
 	 *付款方式名称
 	 */
	public static final String KEY_PAYTYPE = "PayType";
	/**
 	 *总税额(原币)
 	 */
	public static final String KEY_SOURCETAXTOTAL = "SourceTaxTotal";
	/**
 	 *总税额(本位币)
 	 */
	public static final String KEY_TAXTOTAL = "TaxTotal";
	/**
 	 *是否客户确认(1是0否)
 	 */
	public static final String KEY_ISCONFIRMED = "IsConfirmed";
	/**
 	 *客户对订单数据确认日期
 	 */
	public static final String KEY_CONFIRMDATE = "ConfirmDate";
	/**
 	 *更改客户确认标志人
 	 */
	public static final String KEY_CONFIRMBY = "ConfirmBy";
	/**
 	 *是否作废(1是0否)
 	 */
	public static final String KEY_ISCANCEL = "IsCancel";
	/**
 	 *作废人
 	 */
	public static final String KEY_CANCELBY = "CancelBy";
	/**
 	 *作废时间
 	 */
	public static final String KEY_CANCELDATE = "CancelDate";
	/**
 	 *作废原因
 	 */
	public static final String KEY_CANCELREASON = "CancelReason";
	/**
 	 *是否关闭(1是0否)
 	 */
	public static final String KEY_ISCLOSE = "IsClose";
	/**
 	 *关闭人
 	 */
	public static final String KEY_CLOSEBY = "CloseBy";
	/**
 	 *关闭时间
 	 */
	public static final String KEY_CLOSEDATE = "CloseDate";
	/**
 	 *关闭原因
 	 */
	public static final String KEY_CLOSEREASON = "CloseReason";
	/**
 	 *是否PO后补(1是0否)
 	 */
	public static final String KEY_ISPOWAITING = "IsPOWaiting";
	/**
 	 *PO后补标志更改人
 	 */
	public static final String KEY_POBACKBY = "POBackBy";
	/**
 	 *预计PO补回日期
 	 */
	public static final String KEY_POBACKDATE = "POBackDate";
	/**
 	 *是否复核(1是0否)
 	 */
	public static final String KEY_RECHECKSTATUS = "ReCheckStatus";
	/**
 	 *复核结果(1通过,2不通过)
 	 */
	public static final String KEY_RECHECKRESULT = "ReCheckResult";
	/**
 	 *复核通过日期
 	 */
	public static final String KEY_AUDITDATE = "AuditDate";
	/**
 	 *复审人
 	 */
	public static final String KEY_LASTAUDITBY = "LastAuditBy";
	/**
 	 *复核不通过原因
 	 */
	public static final String KEY_AUDITNOTPASSREASON = "AuditNotPassReason";
	/**
 	 *是否锁定(1是0否)
 	 */
	public static final String KEY_ISLOCK = "IsLock";
	/**
 	 *锁定原因
 	 */
	public static final String KEY_LOCKREASON = "LockReason";
	/**
 	 *解锁人
 	 */
	public static final String KEY_UNLOCKBY = "UnlockBy";
	/**
 	 *解锁时间
 	 */
	public static final String KEY_UNLOCKON = "UnlockOn";
	/**
 	 *解锁原因
 	 */
	public static final String KEY_UNLOCKREASON = "UnlockReason";
	/**
 	 *是否预支付(1是0否)
 	 */
	public static final String KEY_ISPREPAID = "IsPrePaid";
	/**
 	 *预支付金额(原币)
 	 */
	public static final String KEY_PREPAIDTOTAL = "PrePaidTotal";
	/**
 	 *客户订单备注
 	 */
	public static final String KEY_REMARK = "Remark";
	/**
 	 *创建时间
 	 */
	public static final String KEY_CREATEDON = "CreatedOn";
	/**
 	 *创建人
 	 */
	public static final String KEY_CREATEDBY = "CreatedBy";
	/**
 	 *修改时间
 	 */
	public static final String KEY_MODIFIEDON = "ModifiedOn";
	/**
 	 *修改人
 	 */
	public static final String KEY_MODIFIEDBY = "ModifiedBy";
	/**
 	 *版本号
 	 */
	public static final String KEY_VERSION = "Version";
	/**
 	 *PO下产品种类个数
 	 */
	public static final String KEY_POKINDSCOUNT = "POKindsCount";
	/**
 	 *是否存在拖欠款
 	 */
	public static final String KEY_ISHAVEUNPAIDORDER = "IsHaveUnpaidOrder";
	/**
 	 *拖欠款总额
 	 */
	public static final String KEY_UNPAIDORDERTOTAL = "UnpaidOrderTotal";
	/**
 	 *拖欠款天数
 	 */
	public static final String KEY_BACKMENOEYDAYS = "BackMenoeyDays";
	/**
 	 *客户在下单时的信用等级
 	 */
	public static final String KEY_CURRENTCREDITLEVEL = "CurrentCreditLevel";
	/**
 	 *客户在下单时的信用额度
 	 */
	public static final String KEY_CURRENTCREDITLINE = "CurrentCreditLine";
	/**
 	 *是否超过信用额度
 	 */
	public static final String KEY_ISOUTOFCREDITLINE = "IsOutOfCreditLine";
	/**
 	 *订单各个产品的费用之和(不包含额外费用)
 	 */
	public static final String KEY_ORDERPRODUCTSPRICE = "OrderProductsPrice";
	/**
 	 *订单各产品的额外费用之和
 	 */
	public static final String KEY_ORDEREXTENDPRICE = "OrderExtendPrice";
	/**
 	 *订单总额(本位币)
 	 */
	public static final String KEY_LOCALORDERPRICE = "LocalOrderPrice";
	/**
 	 *订单总额(原币)
 	 */
	public static final String KEY_ORDERPRICE = "OrderPrice";
	/**
 	 *交货规律(1可提前出货可跨月交货,2可提前出货但不可跨月交货,3,不能提前只能按期交货,4需等客户排期交货,5延期出货(拼货))
 	 */
	public static final String KEY_SUMMITORDERRULES = "SummitOrderRules";
    
	public static final CustomerOrder dao = new CustomerOrder();
	
	/**
	 * 客户订单关联的所有产品订?
	 */
	public List<ProductOrder> productorders;
	
	/**
	 * 获取客户订单下的所有产品子订单
	 * @return
	 */
	public List<ProductOrder> getProductorders() {
		if(productorders!=null){
			return productorders;
		}
		else{
			String customerOrderId = this.get(CustomerOrder.KEY_COID);
			List<ProductOrder> tmpOrders = ProductOrderService.me().findByCustomerOrderId(customerOrderId);
			return tmpOrders;
		}	
	}

	public void setProductorders(List<ProductOrder> productorders) {
		this.productorders = productorders;
	}

 }

以上是我的一个model定义,你可以看到,是有关系维护的代码在里面的。mode的代码是用模板生成的,每次生成会导致我的更改过的model
被覆盖,model中添加关系维护的代码没有问题,但是如何才能保证充血模型持续维护,有没有好点的维护方式,或者只能手动维护呢?



给一个简单的方案:

1:生成 Model 时候,先直接生成一个 BaseCustomerOrder类继承自Model,里面的内容正好是你这个回复的内容,这部分内容完全依靠代码生成器来生成

2:然后再手动创建真正的 CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。

3:当数据库有变动时,再重新生成在第一步中的 BaseCustomerOrder的代码,这样就不会干扰到你的业务类 CustomerOrder

4:既然是用到了生成,建议直接生成 getter、setter 方法即可,而不要生成这种东东:

  public static final String KEY_COID = "COId"; //有了getter、setter这个已然没有什么意义

     这个方案相当于引入了一个中间 BaseXxxModel 专门用于使用工具来生成机械化的代码,以便于享用到 java 静态类型检测的便利,而最后一层业务Model 继承于它以后不会受到BaseXxxModel 重新生成后的干扰和覆盖,当 BaseXxxModel 中的 getter、setter 发生变化以后,eclipse、IDEA 开发环境会有错误提示,就可以很轻松安全地对上层依赖于BaseXxxModel 的代码进行重构。

0
天生蛋疼菊紧
天生蛋疼菊紧

引用来自“JFinal”的评论

引用来自“JFinal”的评论

    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。

引用来自“菜花儿”的评论

/**
 * 客户订单表
 * @author canyou 
 */
@TableBind(tableName = "SL_mk_Schema.CustomerOrder",pkName="COId")
public class CustomerOrder extends BaseModel<CustomerOrder>{

	private static final long serialVersionUID = 1L;
	
	public static final String TABLE_NAME = "SL_mk_Schema.CustomerOrder";
	
	/**
 	 *客户订单id
 	 */
	public static final String KEY_COID = "COId";
	/**
 	 *系统订单号(系统内使用)
 	 */
	public static final String KEY_CONO = "CONo";
	/**
 	 *客户源订单号(深联客户发给深联的订单编号)
 	 */
	public static final String KEY_COSOURCENO = "COSourceNo";
	/**
 	 *订单来源(0所有,1系统订单,2非系统订单)
 	 */
	public static final String KEY_ORDERORIGIN = "OrderOrigin";
	/**
 	 *是否打印(1是0否)
 	 */
	public static final String KEY_ISPRINT = "IsPrint";
	/**
 	 *是否按订单暂缓(1是0否)
 	 */
	public static final String KEY_ISDEFER = "IsDefer";
	/**
 	 *是否有报价(1是0否)
 	 */
	public static final String KEY_ISOFFERPRICE = "IsOfferPrice";
	/**
 	 *客户id
 	 */
	public static final String KEY_CONSUMERID = "ConsumerId";
	/**
 	 *客户名称
 	 */
	public static final String KEY_CONSUMERNAME = "ConsumerName";
	/**
 	 *客户代码
 	 */
	public static final String KEY_CONSUMERCODE = "ConsumerCode";
	/**
 	 *币种Id
 	 */
	public static final String KEY_CURRENCYTYPEID = "CurrencyTypeId";
	/**
 	 *币种
 	 */
	public static final String KEY_CURRENCYTYPE = "CurrencyType";
	/**
 	 *汇率Id
 	 */
	public static final String KEY_EXCHANGERATEID = "ExchangeRateId";
	/**
 	 *汇率
 	 */
	public static final String KEY_EXCHANGERATE = "ExchangeRate";
	/**
 	 *税率(百分比),客户资料预设
 	 */
	public static final String KEY_TAXRATE = "TaxRate";
	/**
 	 *月结方式是否变更(1变更,0未变更)
 	 */
	public static final String KEY_ISSAPCHANGE = "IsSapChange";
	/**
 	 *结算类型(0所有,1系统结算,2订单结算)
 	 */
	public static final String KEY_SAP = "Sap";
	/**
 	 *付款方式id
 	 */
	public static final String KEY_PAYTYPEID = "PayTypeId";
	/**
 	 *付款方式名称
 	 */
	public static final String KEY_PAYTYPE = "PayType";
	/**
 	 *总税额(原币)
 	 */
	public static final String KEY_SOURCETAXTOTAL = "SourceTaxTotal";
	/**
 	 *总税额(本位币)
 	 */
	public static final String KEY_TAXTOTAL = "TaxTotal";
	/**
 	 *是否客户确认(1是0否)
 	 */
	public static final String KEY_ISCONFIRMED = "IsConfirmed";
	/**
 	 *客户对订单数据确认日期
 	 */
	public static final String KEY_CONFIRMDATE = "ConfirmDate";
	/**
 	 *更改客户确认标志人
 	 */
	public static final String KEY_CONFIRMBY = "ConfirmBy";
	/**
 	 *是否作废(1是0否)
 	 */
	public static final String KEY_ISCANCEL = "IsCancel";
	/**
 	 *作废人
 	 */
	public static final String KEY_CANCELBY = "CancelBy";
	/**
 	 *作废时间
 	 */
	public static final String KEY_CANCELDATE = "CancelDate";
	/**
 	 *作废原因
 	 */
	public static final String KEY_CANCELREASON = "CancelReason";
	/**
 	 *是否关闭(1是0否)
 	 */
	public static final String KEY_ISCLOSE = "IsClose";
	/**
 	 *关闭人
 	 */
	public static final String KEY_CLOSEBY = "CloseBy";
	/**
 	 *关闭时间
 	 */
	public static final String KEY_CLOSEDATE = "CloseDate";
	/**
 	 *关闭原因
 	 */
	public static final String KEY_CLOSEREASON = "CloseReason";
	/**
 	 *是否PO后补(1是0否)
 	 */
	public static final String KEY_ISPOWAITING = "IsPOWaiting";
	/**
 	 *PO后补标志更改人
 	 */
	public static final String KEY_POBACKBY = "POBackBy";
	/**
 	 *预计PO补回日期
 	 */
	public static final String KEY_POBACKDATE = "POBackDate";
	/**
 	 *是否复核(1是0否)
 	 */
	public static final String KEY_RECHECKSTATUS = "ReCheckStatus";
	/**
 	 *复核结果(1通过,2不通过)
 	 */
	public static final String KEY_RECHECKRESULT = "ReCheckResult";
	/**
 	 *复核通过日期
 	 */
	public static final String KEY_AUDITDATE = "AuditDate";
	/**
 	 *复审人
 	 */
	public static final String KEY_LASTAUDITBY = "LastAuditBy";
	/**
 	 *复核不通过原因
 	 */
	public static final String KEY_AUDITNOTPASSREASON = "AuditNotPassReason";
	/**
 	 *是否锁定(1是0否)
 	 */
	public static final String KEY_ISLOCK = "IsLock";
	/**
 	 *锁定原因
 	 */
	public static final String KEY_LOCKREASON = "LockReason";
	/**
 	 *解锁人
 	 */
	public static final String KEY_UNLOCKBY = "UnlockBy";
	/**
 	 *解锁时间
 	 */
	public static final String KEY_UNLOCKON = "UnlockOn";
	/**
 	 *解锁原因
 	 */
	public static final String KEY_UNLOCKREASON = "UnlockReason";
	/**
 	 *是否预支付(1是0否)
 	 */
	public static final String KEY_ISPREPAID = "IsPrePaid";
	/**
 	 *预支付金额(原币)
 	 */
	public static final String KEY_PREPAIDTOTAL = "PrePaidTotal";
	/**
 	 *客户订单备注
 	 */
	public static final String KEY_REMARK = "Remark";
	/**
 	 *创建时间
 	 */
	public static final String KEY_CREATEDON = "CreatedOn";
	/**
 	 *创建人
 	 */
	public static final String KEY_CREATEDBY = "CreatedBy";
	/**
 	 *修改时间
 	 */
	public static final String KEY_MODIFIEDON = "ModifiedOn";
	/**
 	 *修改人
 	 */
	public static final String KEY_MODIFIEDBY = "ModifiedBy";
	/**
 	 *版本号
 	 */
	public static final String KEY_VERSION = "Version";
	/**
 	 *PO下产品种类个数
 	 */
	public static final String KEY_POKINDSCOUNT = "POKindsCount";
	/**
 	 *是否存在拖欠款
 	 */
	public static final String KEY_ISHAVEUNPAIDORDER = "IsHaveUnpaidOrder";
	/**
 	 *拖欠款总额
 	 */
	public static final String KEY_UNPAIDORDERTOTAL = "UnpaidOrderTotal";
	/**
 	 *拖欠款天数
 	 */
	public static final String KEY_BACKMENOEYDAYS = "BackMenoeyDays";
	/**
 	 *客户在下单时的信用等级
 	 */
	public static final String KEY_CURRENTCREDITLEVEL = "CurrentCreditLevel";
	/**
 	 *客户在下单时的信用额度
 	 */
	public static final String KEY_CURRENTCREDITLINE = "CurrentCreditLine";
	/**
 	 *是否超过信用额度
 	 */
	public static final String KEY_ISOUTOFCREDITLINE = "IsOutOfCreditLine";
	/**
 	 *订单各个产品的费用之和(不包含额外费用)
 	 */
	public static final String KEY_ORDERPRODUCTSPRICE = "OrderProductsPrice";
	/**
 	 *订单各产品的额外费用之和
 	 */
	public static final String KEY_ORDEREXTENDPRICE = "OrderExtendPrice";
	/**
 	 *订单总额(本位币)
 	 */
	public static final String KEY_LOCALORDERPRICE = "LocalOrderPrice";
	/**
 	 *订单总额(原币)
 	 */
	public static final String KEY_ORDERPRICE = "OrderPrice";
	/**
 	 *交货规律(1可提前出货可跨月交货,2可提前出货但不可跨月交货,3,不能提前只能按期交货,4需等客户排期交货,5延期出货(拼货))
 	 */
	public static final String KEY_SUMMITORDERRULES = "SummitOrderRules";
    
	public static final CustomerOrder dao = new CustomerOrder();
	
	/**
	 * 客户订单关联的所有产品订?
	 */
	public List<ProductOrder> productorders;
	
	/**
	 * 获取客户订单下的所有产品子订单
	 * @return
	 */
	public List<ProductOrder> getProductorders() {
		if(productorders!=null){
			return productorders;
		}
		else{
			String customerOrderId = this.get(CustomerOrder.KEY_COID);
			List<ProductOrder> tmpOrders = ProductOrderService.me().findByCustomerOrderId(customerOrderId);
			return tmpOrders;
		}	
	}

	public void setProductorders(List<ProductOrder> productorders) {
		this.productorders = productorders;
	}

 }

以上是我的一个model定义,你可以看到,是有关系维护的代码在里面的。mode的代码是用模板生成的,每次生成会导致我的更改过的model
被覆盖,model中添加关系维护的代码没有问题,但是如何才能保证充血模型持续维护,有没有好点的维护方式,或者只能手动维护呢?



给一个简单的方案:

1:生成 Model 时候,先直接生成一个 BaseCustomerOrder类继承自Model,里面的内容正好是你这个回复的内容,这部分内容完全依靠代码生成器来生成

2:然后再手动创建真正的 CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。

3:当数据库有变动时,再重新生成在第一步中的 BaseCustomerOrder的代码,这样就不会干扰到你的业务类 CustomerOrder

4:既然是用到了生成,建议直接生成 getter、setter 方法即可,而不要生成这种东东:

  public static final String KEY_COID = "COId"; //有了getter、setter这个已然没有什么意义

     这个方案相当于引入了一个中间 BaseXxxModel 专门用于使用工具来生成机械化的代码,以便于享用到 java 静态类型检测的便利,而最后一层业务Model 继承于它以后不会受到BaseXxxModel 重新生成后的干扰和覆盖,当 BaseXxxModel 中的 getter、setter 发生变化以后,eclipse、IDEA 开发环境会有错误提示,就可以很轻松安全地对上层依赖于BaseXxxModel 的代码进行重构。

波总,多谢你的改进方案。有几点我不太明白。再次找你请教下

“CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。”我项目里是有专门的一层service的,你的业务方法手动在业务实体里写是什么意思?

我自己是这么理解的,比如我CustomerOrder下面有多个ProductOrder,那么业务实体CustomerOrder里,有getProductOrder()用于获取客户订单关联到的所有产品订单,实际业务实体里就调用用service里的相应方法。

这么做的目的是,对订单下单这个域,定义一个业务类型,用来承载业务。这个类型能够实现业务关系的自描述。拿刀业务实体后,开发者能很清晰的知道业务实体涉及到的关联,而不是在service靠手动的写很多代码来维护表实体之间的关系。我期望任何一个业务领域,都有一个业务模型来承载。不是直接穿透过去,在service靠零散的代码来对表Entity手动进行建立关系。那样我个人觉得不适用于复杂的业务场景。

从前期你的介绍和建议,Jfinal应该是可以做到的,上面那个理解,麻烦波总确认下我理解的是否有误?

另外一个“既然是用到了生成,建议直接生成 getter、setter 方法即可”,我目前了解到的model描述,都是“public static final String KEY_COID = "COId" 这种。并没有setter和getter的这种方式的model定义示例,不知道能否提供下示例,以便我参考改进。



0
JFinal
JFinal

引用来自“JFinal”的评论

引用来自“JFinal”的评论

    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。

引用来自“菜花儿”的评论

/**
 * 客户订单表
 * @author canyou 
 */
@TableBind(tableName = "SL_mk_Schema.CustomerOrder",pkName="COId")
public class CustomerOrder extends BaseModel<CustomerOrder>{

	private static final long serialVersionUID = 1L;
	
	public static final String TABLE_NAME = "SL_mk_Schema.CustomerOrder";
	
	/**
 	 *客户订单id
 	 */
	public static final String KEY_COID = "COId";
	/**
 	 *系统订单号(系统内使用)
 	 */
	public static final String KEY_CONO = "CONo";
	/**
 	 *客户源订单号(深联客户发给深联的订单编号)
 	 */
	public static final String KEY_COSOURCENO = "COSourceNo";
	/**
 	 *订单来源(0所有,1系统订单,2非系统订单)
 	 */
	public static final String KEY_ORDERORIGIN = "OrderOrigin";
	/**
 	 *是否打印(1是0否)
 	 */
	public static final String KEY_ISPRINT = "IsPrint";
	/**
 	 *是否按订单暂缓(1是0否)
 	 */
	public static final String KEY_ISDEFER = "IsDefer";
	/**
 	 *是否有报价(1是0否)
 	 */
	public static final String KEY_ISOFFERPRICE = "IsOfferPrice";
	/**
 	 *客户id
 	 */
	public static final String KEY_CONSUMERID = "ConsumerId";
	/**
 	 *客户名称
 	 */
	public static final String KEY_CONSUMERNAME = "ConsumerName";
	/**
 	 *客户代码
 	 */
	public static final String KEY_CONSUMERCODE = "ConsumerCode";
	/**
 	 *币种Id
 	 */
	public static final String KEY_CURRENCYTYPEID = "CurrencyTypeId";
	/**
 	 *币种
 	 */
	public static final String KEY_CURRENCYTYPE = "CurrencyType";
	/**
 	 *汇率Id
 	 */
	public static final String KEY_EXCHANGERATEID = "ExchangeRateId";
	/**
 	 *汇率
 	 */
	public static final String KEY_EXCHANGERATE = "ExchangeRate";
	/**
 	 *税率(百分比),客户资料预设
 	 */
	public static final String KEY_TAXRATE = "TaxRate";
	/**
 	 *月结方式是否变更(1变更,0未变更)
 	 */
	public static final String KEY_ISSAPCHANGE = "IsSapChange";
	/**
 	 *结算类型(0所有,1系统结算,2订单结算)
 	 */
	public static final String KEY_SAP = "Sap";
	/**
 	 *付款方式id
 	 */
	public static final String KEY_PAYTYPEID = "PayTypeId";
	/**
 	 *付款方式名称
 	 */
	public static final String KEY_PAYTYPE = "PayType";
	/**
 	 *总税额(原币)
 	 */
	public static final String KEY_SOURCETAXTOTAL = "SourceTaxTotal";
	/**
 	 *总税额(本位币)
 	 */
	public static final String KEY_TAXTOTAL = "TaxTotal";
	/**
 	 *是否客户确认(1是0否)
 	 */
	public static final String KEY_ISCONFIRMED = "IsConfirmed";
	/**
 	 *客户对订单数据确认日期
 	 */
	public static final String KEY_CONFIRMDATE = "ConfirmDate";
	/**
 	 *更改客户确认标志人
 	 */
	public static final String KEY_CONFIRMBY = "ConfirmBy";
	/**
 	 *是否作废(1是0否)
 	 */
	public static final String KEY_ISCANCEL = "IsCancel";
	/**
 	 *作废人
 	 */
	public static final String KEY_CANCELBY = "CancelBy";
	/**
 	 *作废时间
 	 */
	public static final String KEY_CANCELDATE = "CancelDate";
	/**
 	 *作废原因
 	 */
	public static final String KEY_CANCELREASON = "CancelReason";
	/**
 	 *是否关闭(1是0否)
 	 */
	public static final String KEY_ISCLOSE = "IsClose";
	/**
 	 *关闭人
 	 */
	public static final String KEY_CLOSEBY = "CloseBy";
	/**
 	 *关闭时间
 	 */
	public static final String KEY_CLOSEDATE = "CloseDate";
	/**
 	 *关闭原因
 	 */
	public static final String KEY_CLOSEREASON = "CloseReason";
	/**
 	 *是否PO后补(1是0否)
 	 */
	public static final String KEY_ISPOWAITING = "IsPOWaiting";
	/**
 	 *PO后补标志更改人
 	 */
	public static final String KEY_POBACKBY = "POBackBy";
	/**
 	 *预计PO补回日期
 	 */
	public static final String KEY_POBACKDATE = "POBackDate";
	/**
 	 *是否复核(1是0否)
 	 */
	public static final String KEY_RECHECKSTATUS = "ReCheckStatus";
	/**
 	 *复核结果(1通过,2不通过)
 	 */
	public static final String KEY_RECHECKRESULT = "ReCheckResult";
	/**
 	 *复核通过日期
 	 */
	public static final String KEY_AUDITDATE = "AuditDate";
	/**
 	 *复审人
 	 */
	public static final String KEY_LASTAUDITBY = "LastAuditBy";
	/**
 	 *复核不通过原因
 	 */
	public static final String KEY_AUDITNOTPASSREASON = "AuditNotPassReason";
	/**
 	 *是否锁定(1是0否)
 	 */
	public static final String KEY_ISLOCK = "IsLock";
	/**
 	 *锁定原因
 	 */
	public static final String KEY_LOCKREASON = "LockReason";
	/**
 	 *解锁人
 	 */
	public static final String KEY_UNLOCKBY = "UnlockBy";
	/**
 	 *解锁时间
 	 */
	public static final String KEY_UNLOCKON = "UnlockOn";
	/**
 	 *解锁原因
 	 */
	public static final String KEY_UNLOCKREASON = "UnlockReason";
	/**
 	 *是否预支付(1是0否)
 	 */
	public static final String KEY_ISPREPAID = "IsPrePaid";
	/**
 	 *预支付金额(原币)
 	 */
	public static final String KEY_PREPAIDTOTAL = "PrePaidTotal";
	/**
 	 *客户订单备注
 	 */
	public static final String KEY_REMARK = "Remark";
	/**
 	 *创建时间
 	 */
	public static final String KEY_CREATEDON = "CreatedOn";
	/**
 	 *创建人
 	 */
	public static final String KEY_CREATEDBY = "CreatedBy";
	/**
 	 *修改时间
 	 */
	public static final String KEY_MODIFIEDON = "ModifiedOn";
	/**
 	 *修改人
 	 */
	public static final String KEY_MODIFIEDBY = "ModifiedBy";
	/**
 	 *版本号
 	 */
	public static final String KEY_VERSION = "Version";
	/**
 	 *PO下产品种类个数
 	 */
	public static final String KEY_POKINDSCOUNT = "POKindsCount";
	/**
 	 *是否存在拖欠款
 	 */
	public static final String KEY_ISHAVEUNPAIDORDER = "IsHaveUnpaidOrder";
	/**
 	 *拖欠款总额
 	 */
	public static final String KEY_UNPAIDORDERTOTAL = "UnpaidOrderTotal";
	/**
 	 *拖欠款天数
 	 */
	public static final String KEY_BACKMENOEYDAYS = "BackMenoeyDays";
	/**
 	 *客户在下单时的信用等级
 	 */
	public static final String KEY_CURRENTCREDITLEVEL = "CurrentCreditLevel";
	/**
 	 *客户在下单时的信用额度
 	 */
	public static final String KEY_CURRENTCREDITLINE = "CurrentCreditLine";
	/**
 	 *是否超过信用额度
 	 */
	public static final String KEY_ISOUTOFCREDITLINE = "IsOutOfCreditLine";
	/**
 	 *订单各个产品的费用之和(不包含额外费用)
 	 */
	public static final String KEY_ORDERPRODUCTSPRICE = "OrderProductsPrice";
	/**
 	 *订单各产品的额外费用之和
 	 */
	public static final String KEY_ORDEREXTENDPRICE = "OrderExtendPrice";
	/**
 	 *订单总额(本位币)
 	 */
	public static final String KEY_LOCALORDERPRICE = "LocalOrderPrice";
	/**
 	 *订单总额(原币)
 	 */
	public static final String KEY_ORDERPRICE = "OrderPrice";
	/**
 	 *交货规律(1可提前出货可跨月交货,2可提前出货但不可跨月交货,3,不能提前只能按期交货,4需等客户排期交货,5延期出货(拼货))
 	 */
	public static final String KEY_SUMMITORDERRULES = "SummitOrderRules";
    
	public static final CustomerOrder dao = new CustomerOrder();
	
	/**
	 * 客户订单关联的所有产品订?
	 */
	public List<ProductOrder> productorders;
	
	/**
	 * 获取客户订单下的所有产品子订单
	 * @return
	 */
	public List<ProductOrder> getProductorders() {
		if(productorders!=null){
			return productorders;
		}
		else{
			String customerOrderId = this.get(CustomerOrder.KEY_COID);
			List<ProductOrder> tmpOrders = ProductOrderService.me().findByCustomerOrderId(customerOrderId);
			return tmpOrders;
		}	
	}

	public void setProductorders(List<ProductOrder> productorders) {
		this.productorders = productorders;
	}

 }

以上是我的一个model定义,你可以看到,是有关系维护的代码在里面的。mode的代码是用模板生成的,每次生成会导致我的更改过的model
被覆盖,model中添加关系维护的代码没有问题,但是如何才能保证充血模型持续维护,有没有好点的维护方式,或者只能手动维护呢?



给一个简单的方案:

1:生成 Model 时候,先直接生成一个 BaseCustomerOrder类继承自Model,里面的内容正好是你这个回复的内容,这部分内容完全依靠代码生成器来生成

2:然后再手动创建真正的 CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。

3:当数据库有变动时,再重新生成在第一步中的 BaseCustomerOrder的代码,这样就不会干扰到你的业务类 CustomerOrder

4:既然是用到了生成,建议直接生成 getter、setter 方法即可,而不要生成这种东东:

  public static final String KEY_COID = "COId"; //有了getter、setter这个已然没有什么意义

     这个方案相当于引入了一个中间 BaseXxxModel 专门用于使用工具来生成机械化的代码,以便于享用到 java 静态类型检测的便利,而最后一层业务Model 继承于它以后不会受到BaseXxxModel 重新生成后的干扰和覆盖,当 BaseXxxModel 中的 getter、setter 发生变化以后,eclipse、IDEA 开发环境会有错误提示,就可以很轻松安全地对上层依赖于BaseXxxModel 的代码进行重构。

引用来自“菜花儿”的评论

波总,多谢你的改进方案。有几点我不太明白。再次找你请教下

“CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。”我项目里是有专门的一层service的,你的业务方法手动在业务实体里写是什么意思?

我自己是这么理解的,比如我CustomerOrder下面有多个ProductOrder,那么业务实体CustomerOrder里,有getProductOrder()用于获取客户订单关联到的所有产品订单,实际业务实体里就调用用service里的相应方法。

这么做的目的是,对订单下单这个域,定义一个业务类型,用来承载业务。这个类型能够实现业务关系的自描述。拿刀业务实体后,开发者能很清晰的知道业务实体涉及到的关联,而不是在service靠手动的写很多代码来维护表实体之间的关系。我期望任何一个业务领域,都有一个业务模型来承载。不是直接穿透过去,在service靠零散的代码来对表Entity手动进行建立关系。那样我个人觉得不适用于复杂的业务场景。

从前期你的介绍和建议,Jfinal应该是可以做到的,上面那个理解,麻烦波总确认下我理解的是否有误?

另外一个“既然是用到了生成,建议直接生成 getter、setter 方法即可”,我目前了解到的model描述,都是“public static final String KEY_COID = "COId" 这种。并没有setter和getter的这种方式的model定义示例,不知道能否提供下示例,以便我参考改进。



   我说到的“手动”写在业务实体里面是区别前面提到的代码生成,一个是生成,一个是强调手写以强调与生成的区别,这样在利用工具生成的时候,就不会覆盖你手写过的代码了。没其它意思了。

   另外业务写在哪里,是在业务层还是在 CustomerOrder 根据你的习惯,并不做规定。我之所以上次谈到业务写在 CusotmerOrder 中是因为我以为你以前就是将业务手写在这里的,并且你提到了生成代码时覆盖掉了你手写的代码。往简单里想。

0
天生蛋疼菊紧
天生蛋疼菊紧

引用来自“JFinal”的评论

引用来自“JFinal”的评论

引用来自“JFinal”的评论

    jfinal 的 model 就是领域模型,并且建议是充血领域模型。 我不太了解你的具体需求,贴出一点示便性代码,表示一下具体的需求。

引用来自“菜花儿”的评论

/**
 * 客户订单表
 * @author canyou 
 */
@TableBind(tableName = "SL_mk_Schema.CustomerOrder",pkName="COId")
public class CustomerOrder extends BaseModel<CustomerOrder>{

	private static final long serialVersionUID = 1L;
	
	public static final String TABLE_NAME = "SL_mk_Schema.CustomerOrder";
	
	/**
 	 *客户订单id
 	 */
	public static final String KEY_COID = "COId";
	/**
 	 *系统订单号(系统内使用)
 	 */
	public static final String KEY_CONO = "CONo";
	/**
 	 *客户源订单号(深联客户发给深联的订单编号)
 	 */
	public static final String KEY_COSOURCENO = "COSourceNo";
	/**
 	 *订单来源(0所有,1系统订单,2非系统订单)
 	 */
	public static final String KEY_ORDERORIGIN = "OrderOrigin";
	/**
 	 *是否打印(1是0否)
 	 */
	public static final String KEY_ISPRINT = "IsPrint";
	/**
 	 *是否按订单暂缓(1是0否)
 	 */
	public static final String KEY_ISDEFER = "IsDefer";
	/**
 	 *是否有报价(1是0否)
 	 */
	public static final String KEY_ISOFFERPRICE = "IsOfferPrice";
	/**
 	 *客户id
 	 */
	public static final String KEY_CONSUMERID = "ConsumerId";
	/**
 	 *客户名称
 	 */
	public static final String KEY_CONSUMERNAME = "ConsumerName";
	/**
 	 *客户代码
 	 */
	public static final String KEY_CONSUMERCODE = "ConsumerCode";
	/**
 	 *币种Id
 	 */
	public static final String KEY_CURRENCYTYPEID = "CurrencyTypeId";
	/**
 	 *币种
 	 */
	public static final String KEY_CURRENCYTYPE = "CurrencyType";
	/**
 	 *汇率Id
 	 */
	public static final String KEY_EXCHANGERATEID = "ExchangeRateId";
	/**
 	 *汇率
 	 */
	public static final String KEY_EXCHANGERATE = "ExchangeRate";
	/**
 	 *税率(百分比),客户资料预设
 	 */
	public static final String KEY_TAXRATE = "TaxRate";
	/**
 	 *月结方式是否变更(1变更,0未变更)
 	 */
	public static final String KEY_ISSAPCHANGE = "IsSapChange";
	/**
 	 *结算类型(0所有,1系统结算,2订单结算)
 	 */
	public static final String KEY_SAP = "Sap";
	/**
 	 *付款方式id
 	 */
	public static final String KEY_PAYTYPEID = "PayTypeId";
	/**
 	 *付款方式名称
 	 */
	public static final String KEY_PAYTYPE = "PayType";
	/**
 	 *总税额(原币)
 	 */
	public static final String KEY_SOURCETAXTOTAL = "SourceTaxTotal";
	/**
 	 *总税额(本位币)
 	 */
	public static final String KEY_TAXTOTAL = "TaxTotal";
	/**
 	 *是否客户确认(1是0否)
 	 */
	public static final String KEY_ISCONFIRMED = "IsConfirmed";
	/**
 	 *客户对订单数据确认日期
 	 */
	public static final String KEY_CONFIRMDATE = "ConfirmDate";
	/**
 	 *更改客户确认标志人
 	 */
	public static final String KEY_CONFIRMBY = "ConfirmBy";
	/**
 	 *是否作废(1是0否)
 	 */
	public static final String KEY_ISCANCEL = "IsCancel";
	/**
 	 *作废人
 	 */
	public static final String KEY_CANCELBY = "CancelBy";
	/**
 	 *作废时间
 	 */
	public static final String KEY_CANCELDATE = "CancelDate";
	/**
 	 *作废原因
 	 */
	public static final String KEY_CANCELREASON = "CancelReason";
	/**
 	 *是否关闭(1是0否)
 	 */
	public static final String KEY_ISCLOSE = "IsClose";
	/**
 	 *关闭人
 	 */
	public static final String KEY_CLOSEBY = "CloseBy";
	/**
 	 *关闭时间
 	 */
	public static final String KEY_CLOSEDATE = "CloseDate";
	/**
 	 *关闭原因
 	 */
	public static final String KEY_CLOSEREASON = "CloseReason";
	/**
 	 *是否PO后补(1是0否)
 	 */
	public static final String KEY_ISPOWAITING = "IsPOWaiting";
	/**
 	 *PO后补标志更改人
 	 */
	public static final String KEY_POBACKBY = "POBackBy";
	/**
 	 *预计PO补回日期
 	 */
	public static final String KEY_POBACKDATE = "POBackDate";
	/**
 	 *是否复核(1是0否)
 	 */
	public static final String KEY_RECHECKSTATUS = "ReCheckStatus";
	/**
 	 *复核结果(1通过,2不通过)
 	 */
	public static final String KEY_RECHECKRESULT = "ReCheckResult";
	/**
 	 *复核通过日期
 	 */
	public static final String KEY_AUDITDATE = "AuditDate";
	/**
 	 *复审人
 	 */
	public static final String KEY_LASTAUDITBY = "LastAuditBy";
	/**
 	 *复核不通过原因
 	 */
	public static final String KEY_AUDITNOTPASSREASON = "AuditNotPassReason";
	/**
 	 *是否锁定(1是0否)
 	 */
	public static final String KEY_ISLOCK = "IsLock";
	/**
 	 *锁定原因
 	 */
	public static final String KEY_LOCKREASON = "LockReason";
	/**
 	 *解锁人
 	 */
	public static final String KEY_UNLOCKBY = "UnlockBy";
	/**
 	 *解锁时间
 	 */
	public static final String KEY_UNLOCKON = "UnlockOn";
	/**
 	 *解锁原因
 	 */
	public static final String KEY_UNLOCKREASON = "UnlockReason";
	/**
 	 *是否预支付(1是0否)
 	 */
	public static final String KEY_ISPREPAID = "IsPrePaid";
	/**
 	 *预支付金额(原币)
 	 */
	public static final String KEY_PREPAIDTOTAL = "PrePaidTotal";
	/**
 	 *客户订单备注
 	 */
	public static final String KEY_REMARK = "Remark";
	/**
 	 *创建时间
 	 */
	public static final String KEY_CREATEDON = "CreatedOn";
	/**
 	 *创建人
 	 */
	public static final String KEY_CREATEDBY = "CreatedBy";
	/**
 	 *修改时间
 	 */
	public static final String KEY_MODIFIEDON = "ModifiedOn";
	/**
 	 *修改人
 	 */
	public static final String KEY_MODIFIEDBY = "ModifiedBy";
	/**
 	 *版本号
 	 */
	public static final String KEY_VERSION = "Version";
	/**
 	 *PO下产品种类个数
 	 */
	public static final String KEY_POKINDSCOUNT = "POKindsCount";
	/**
 	 *是否存在拖欠款
 	 */
	public static final String KEY_ISHAVEUNPAIDORDER = "IsHaveUnpaidOrder";
	/**
 	 *拖欠款总额
 	 */
	public static final String KEY_UNPAIDORDERTOTAL = "UnpaidOrderTotal";
	/**
 	 *拖欠款天数
 	 */
	public static final String KEY_BACKMENOEYDAYS = "BackMenoeyDays";
	/**
 	 *客户在下单时的信用等级
 	 */
	public static final String KEY_CURRENTCREDITLEVEL = "CurrentCreditLevel";
	/**
 	 *客户在下单时的信用额度
 	 */
	public static final String KEY_CURRENTCREDITLINE = "CurrentCreditLine";
	/**
 	 *是否超过信用额度
 	 */
	public static final String KEY_ISOUTOFCREDITLINE = "IsOutOfCreditLine";
	/**
 	 *订单各个产品的费用之和(不包含额外费用)
 	 */
	public static final String KEY_ORDERPRODUCTSPRICE = "OrderProductsPrice";
	/**
 	 *订单各产品的额外费用之和
 	 */
	public static final String KEY_ORDEREXTENDPRICE = "OrderExtendPrice";
	/**
 	 *订单总额(本位币)
 	 */
	public static final String KEY_LOCALORDERPRICE = "LocalOrderPrice";
	/**
 	 *订单总额(原币)
 	 */
	public static final String KEY_ORDERPRICE = "OrderPrice";
	/**
 	 *交货规律(1可提前出货可跨月交货,2可提前出货但不可跨月交货,3,不能提前只能按期交货,4需等客户排期交货,5延期出货(拼货))
 	 */
	public static final String KEY_SUMMITORDERRULES = "SummitOrderRules";
    
	public static final CustomerOrder dao = new CustomerOrder();
	
	/**
	 * 客户订单关联的所有产品订?
	 */
	public List<ProductOrder> productorders;
	
	/**
	 * 获取客户订单下的所有产品子订单
	 * @return
	 */
	public List<ProductOrder> getProductorders() {
		if(productorders!=null){
			return productorders;
		}
		else{
			String customerOrderId = this.get(CustomerOrder.KEY_COID);
			List<ProductOrder> tmpOrders = ProductOrderService.me().findByCustomerOrderId(customerOrderId);
			return tmpOrders;
		}	
	}

	public void setProductorders(List<ProductOrder> productorders) {
		this.productorders = productorders;
	}

 }

以上是我的一个model定义,你可以看到,是有关系维护的代码在里面的。mode的代码是用模板生成的,每次生成会导致我的更改过的model
被覆盖,model中添加关系维护的代码没有问题,但是如何才能保证充血模型持续维护,有没有好点的维护方式,或者只能手动维护呢?



给一个简单的方案:

1:生成 Model 时候,先直接生成一个 BaseCustomerOrder类继承自Model,里面的内容正好是你这个回复的内容,这部分内容完全依靠代码生成器来生成

2:然后再手动创建真正的 CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。

3:当数据库有变动时,再重新生成在第一步中的 BaseCustomerOrder的代码,这样就不会干扰到你的业务类 CustomerOrder

4:既然是用到了生成,建议直接生成 getter、setter 方法即可,而不要生成这种东东:

  public static final String KEY_COID = "COId"; //有了getter、setter这个已然没有什么意义

     这个方案相当于引入了一个中间 BaseXxxModel 专门用于使用工具来生成机械化的代码,以便于享用到 java 静态类型检测的便利,而最后一层业务Model 继承于它以后不会受到BaseXxxModel 重新生成后的干扰和覆盖,当 BaseXxxModel 中的 getter、setter 发生变化以后,eclipse、IDEA 开发环境会有错误提示,就可以很轻松安全地对上层依赖于BaseXxxModel 的代码进行重构。

引用来自“菜花儿”的评论

波总,多谢你的改进方案。有几点我不太明白。再次找你请教下

“CustomerOrder 类继承自 BaseCustomerOrder,所有的业务方法手动在这里面书写。”我项目里是有专门的一层service的,你的业务方法手动在业务实体里写是什么意思?

我自己是这么理解的,比如我CustomerOrder下面有多个ProductOrder,那么业务实体CustomerOrder里,有getProductOrder()用于获取客户订单关联到的所有产品订单,实际业务实体里就调用用service里的相应方法。

这么做的目的是,对订单下单这个域,定义一个业务类型,用来承载业务。这个类型能够实现业务关系的自描述。拿刀业务实体后,开发者能很清晰的知道业务实体涉及到的关联,而不是在service靠手动的写很多代码来维护表实体之间的关系。我期望任何一个业务领域,都有一个业务模型来承载。不是直接穿透过去,在service靠零散的代码来对表Entity手动进行建立关系。那样我个人觉得不适用于复杂的业务场景。

从前期你的介绍和建议,Jfinal应该是可以做到的,上面那个理解,麻烦波总确认下我理解的是否有误?

另外一个“既然是用到了生成,建议直接生成 getter、setter 方法即可”,我目前了解到的model描述,都是“public static final String KEY_COID = "COId" 这种。并没有setter和getter的这种方式的model定义示例,不知道能否提供下示例,以便我参考改进。



   我说到的“手动”写在业务实体里面是区别前面提到的代码生成,一个是生成,一个是强调手写以强调与生成的区别,这样在利用工具生成的时候,就不会覆盖你手写过的代码了。没其它意思了。

   另外业务写在哪里,是在业务层还是在 CustomerOrder 根据你的习惯,并不做规定。我之所以上次谈到业务写在 CusotmerOrder 中是因为我以为你以前就是将业务手写在这里的,并且你提到了生成代码时覆盖掉了你手写的代码。往简单里想。

@Jfinal 波总你好。

按照你的思路,服务端已经完成领域模型的引进,但是出现了 新的问题。

我定义了一个新类,继承于生成的model、在新类里定义了一些扩展属性,有getter和set方法、

从controler里将这个扩展过的model进行序列化,只能序列化父类中Record里那个map中的属性,而我自己定义的强类型的扩展属性却不能被序列化,请教如何解决这个问题呢?

扩展model定义代码如下

public class CustomerModel extends Customer {


	private static final long serialVersionUID = 1L;

	
	private CustomerProduct customerproduct;


	public CustomerProduct getCustomerproduct() {
		return customerproduct;
	}


	public void setCustomerproduct(CustomerProduct customerproduct) {
		this.customerproduct = customerproduct;
	}
	
	
}
以上有一个customerproduct属性,序列化的使用的方法是Jfinal自带的工具类

JsonKit.toJson(Object value)

请教波总@Jfinal ,扩展属性在序列化的时候被忽略的问题如何解决?谢谢。



返回顶部
顶部