hibernate设置派生属性, 在持久化类的访问方法中加入程序逻辑...
2008-10-17 11:37
330 查看
假定Customer类有一个avgPrice属生, 表示这个客户的所有订单的平均价格. 它的取值为与它关联的所有Order对象的price的平均值. 在CUSTOMERS表中没有 avg_price字段. 可以在Customer类的setOrders()方法中加入程序逻辑来实现:
private Set orders = new HashSet(0);
private double avgPrice;
public double getAvgPrice() {
return this.avgPrice;
}
private void setAvgPrice(double avgPrice) {
this.avgPrice = avgPrice;
}
public void setOrders(Set orders) {
this.orders = orders;
calculatePrice();
}
public Set getOrders() {
return orders;
}
private void calculatePrice() {
double avgPrice = 0.0;
double totalPrice = 0.0;
int count = 0;
if(getOrders() != null ) {
Iterator iter = getOrders().iterator();
while( iter.hasNext() ) {
double orderPrice = ((Order))iter.next()).getPrice();
totalPrice += orderPrice;
count++;
}
avgPrice = totalPrice/count;
setAvgPrice(avgPrice);
}
}
Customer类的getAvgPrice()方法为public类型, 而setAvgPrice()方法为private类型, 因此JAVA应用程序只能读取avgPrice属生, 但是不能直接修改avgPrice属性. 当JAVA应用程序或者Hibernate调用setOrders()方法时, 会自动调用calculatePrice()方法, calculatePrice()方法又调用setAvgPrice()方法, 从而给avgPrice属性赋值. 由此可见, 如果希望把为持久属性表示客户的所有订单的价格总和, 它的取值为与Customer对象关联的所有Order对象的price属性值的和. 在CUSTOMERS表中没有对应的TOTAL_PRICE字段.在Customer.xml文件中映射totalPrice属性的代码如下:
<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID = ID)" />
当Hibernate从数据库中查询Customer对象时, 在select语句中会包含以上用于计算totalPrice派生属性的子查询语句:
select ID, NAME, SEX, 'CUSTOMER DESCRIPTION', (select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=1) from customers;
如果子查询语句的查询结果为空, Hibernate会把totalPrice属性赋值为NULL, 如果totalPrice属性为double或int等基本类型, 会抛出异常:
[java] org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of 包名
为了避免以上异常, 应该把totalPrice属性定义为Double或Integer等包装类型.
<property>元素的formula属性指定一个SQL表达式, 该表达式可以引用表的字段, 调用SQL函数或者包含子查询语句. 例如LineItem类中有一个unitPrice属性, 而在LINEITEMS表中没有对应的UNIT_PRICE字段,可以通过以下方式映射unitPrice属性:
<property name="unitPrice" formula="BASE_PRICE*QUANTITY" />
private Set orders = new HashSet(0);
private double avgPrice;
public double getAvgPrice() {
return this.avgPrice;
}
private void setAvgPrice(double avgPrice) {
this.avgPrice = avgPrice;
}
public void setOrders(Set orders) {
this.orders = orders;
calculatePrice();
}
public Set getOrders() {
return orders;
}
private void calculatePrice() {
double avgPrice = 0.0;
double totalPrice = 0.0;
int count = 0;
if(getOrders() != null ) {
Iterator iter = getOrders().iterator();
while( iter.hasNext() ) {
double orderPrice = ((Order))iter.next()).getPrice();
totalPrice += orderPrice;
count++;
}
avgPrice = totalPrice/count;
setAvgPrice(avgPrice);
}
}
Customer类的getAvgPrice()方法为public类型, 而setAvgPrice()方法为private类型, 因此JAVA应用程序只能读取avgPrice属生, 但是不能直接修改avgPrice属性. 当JAVA应用程序或者Hibernate调用setOrders()方法时, 会自动调用calculatePrice()方法, calculatePrice()方法又调用setAvgPrice()方法, 从而给avgPrice属性赋值. 由此可见, 如果希望把为持久属性表示客户的所有订单的价格总和, 它的取值为与Customer对象关联的所有Order对象的price属性值的和. 在CUSTOMERS表中没有对应的TOTAL_PRICE字段.在Customer.xml文件中映射totalPrice属性的代码如下:
<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID = ID)" />
当Hibernate从数据库中查询Customer对象时, 在select语句中会包含以上用于计算totalPrice派生属性的子查询语句:
select ID, NAME, SEX, 'CUSTOMER DESCRIPTION', (select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=1) from customers;
如果子查询语句的查询结果为空, Hibernate会把totalPrice属性赋值为NULL, 如果totalPrice属性为double或int等基本类型, 会抛出异常:
[java] org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of 包名
为了避免以上异常, 应该把totalPrice属性定义为Double或Integer等包装类型.
<property>元素的formula属性指定一个SQL表达式, 该表达式可以引用表的字段, 调用SQL函数或者包含子查询语句. 例如LineItem类中有一个unitPrice属性, 而在LINEITEMS表中没有对应的UNIT_PRICE字段,可以通过以下方式映射unitPrice属性:
<property name="unitPrice" formula="BASE_PRICE*QUANTITY" />
相关文章推荐
- Hibernate访问持久化类(派生)属性的方法与策略
- Hibernate之访问属性策略和方法逻辑注入
- 持久化类的属性及访问方法
- 2012-04-24 14:31 VS2008工具,两种加入库的方法。 设置程序运行时目录
- 转载:浅谈python类属性的访问、设置和删除方法
- 解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
- Hibernate访问持久化类属性的策略
- 浅谈python类属性的访问、设置和删除方法
- 解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
- JavaScript DOM概述(获取节点的方法/节点的访问关系/节点创建添加删除复制/属性获取设置删除)
- 解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
- Acrobat 版本校验异常,请检查网络连接是否正常:NotAllowedError;安全性设置禁止访问本属性或方法。
- 解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
- VS2008工具,两种加入库的方法。 设置程序运行时目录
- 浅谈python类属性的访问、设置和删除方法
- Flex4 主程序调用模块方法报TypeError: Error #1009:无法访问空对象引用的属性或方法
- 在Hibernate应用中,持久化类的访问方法被谁调用?
- 攻城狮在路上(壹) Hibernate(三)--- 属性访问、命名策略、派生属性、指定包名等
- Hibernate设置派生属性(formula)