1、持久化类的属性和访问方法
(1)持久化类简介
在Hibernate中持久化类的访问方法有两个调用者,一个是Java应用程序,一个是Hibernate。值得注意的是,Java应用程序不能访问持久化类的private类型的getXXX()、setXXX(),而Hibernate没有这样的限制。
(2)基本类型属性和包装类型属性
Java有8种基本类型:byte,short,char,int,long,float,double,boolean;与之对应的Java提供了8种包装类型:Byte,Short,Character,Integer,Long,Float,Double,Boolean。基本类型与包装类型之间可以如下简单转换:
double prD=1;
//把double基本类型转换成Double包装类型
Double wrD=new Double(prD);
//把Double包装类型转换成double基本类型
prD=wrD.doubleValue();
- 1.
- 2.
- 3.
- 4.
- 5.
Hibernate两种类型都是支持的。
(3)在持久化类的访问方法中加入程序逻辑
(a)在Customer类的getName()和setName()方法中加入程序逻辑
假如在Customer类中有firstname属性和lastname属性,但是没有name属性,而数据库CUSTOMERS表中只有NAME字段。当Hibernate从数据库中取得了CUSTOMERS表的NAME字段值后,会调用setName()方法,此时应该让Hibernate通过setName()方法来自动设置firstname属性和lastname。故要在setName()方法中加入额外的程序逻辑。
public String getName(){
return firstname+ " "+lastname;
}
public void setName(String name){
StringTokenizer t=new StringTokenizer(name);
firstname=t.nextToken();
lastname=t.nextToken();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
在映射文件中此时直接映射name即可,无需映射firstname等。
<property name="name" column="NAME">
- 1.
尽管在Customer类中没有定义name属性,由于Hibernate并不会直接访问name属性,而是通过getName()和setName()方法。只要在Customer.hbm.xml文件中映射了name属性,HQL语句就能访问:
Query query=seesion.createQuery("from Customer as c where c.name='Tom'");
- 1.
但是如果把Customer.hbm.xml文件中name属性配置为:
<property name="name" column="NAME" access="field">
- 1.
程序会直接去访问Customer实例中的name属性,就会出现异常。
(b)在Customer类的setOrders()方法中加入程序逻辑
假定Customer类中有一个avgPrice属性,表示订单的平均价格,取值为它所关联Order对象的price的平均值。在CUSTOMERS表中没有AVG_PRICE字段。可以如下操作:
public Double getAvgPrice(){
return this.avgPrice;
}
private void setAvgPrice( Double avgPrice ){
this.avgPrice = avgPrice;
}
public Double getTotalPrice(){
return this.totalPrice;
}
private void setTotalPrice( Double totalPrice ){
this.totalPrice = totalPrice;
}
public void setOrders( Set orders ){
this.orders = orders;
calculatePrice();
}
public Set getOrders(){
return orders;
}//定义为一个Set
private void calculatePrice(){
double avgPrice = 0.0;
double totalPrice = 0.0;
int count=0;
/迭代计算orders里面所有price
if ( getOrders() != null ){
Iterator iter = getOrders().iterator();
while( iter.hasNext() ){
double orderPrice = ((Order)iter.next()).getPrice();
totalPrice += orderPrice;
count++;
}
// Set the price for the order from the calcualted value
avgPrice=totalPrice/count;
setAvgPrice( new Double(avgPrice) );
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
在Customer.hbm.xml文件不用映射avgPrice,因为Hibernate不会直接访问avgPrice属性,也不会调用getavgPrice()和setavgPrice().
(c)在Customer类的setSex()方法中加入数据验证逻辑
在持久化类的访问方法中,还可以加入数据验证逻辑。
public char getSex(){
return this.sex;
}
public void setSex(char sex){
if(sex!='F' && sex!='M'){
throw new IllegalArgumentException("Invalid Sex");
}
this.sex =sex ;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
(4)设置派生属性
持久化类并非所有属性都直接和表的字段匹配,持久化类的有些属性是可以在运行的时候得出的,这些称作派生属性。正如之前的avgPrice属性,该方案包括两个步骤:
- 在映射文件中不映射avgPrice属性
- 在Customer类的setOrders()方法中加入程序逻辑,自动为avgPrice属性赋值。
除了这种方法来设置派生属性,还可以如下解决:
利用<property>元素的formula属性。formula属性用来设置一个SQL表达式,Hibernate将根据它来计算派生属性的值。以Customer类的totalPrice属性为例:
<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)"/>
- 1.
在Hibernate从数据库中查询Customer对象时,若查询totalPrice,即:
select totalPrice from CUSTOMERS;
- 1.
使用formula属性后,上面的查询语句就会自动地被替代成:
select (select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=1) from CUSTOMERS;
- 1.
如果子句的查询结果为空,那么上述的语句就会出现异常。解决方法是:将totalPrice的属性定义为Double包装类型。
(5)控制insert和update语句
Hibernate在初始化阶段,就会根据映射文件的映射信息,为所有的持久化类定义以下的SQL语句。
以上SQL语句中的“?”代表JDBC PreparedStatement中的参数。这些SQL语句都存放在SessionFactory的内置缓存中,当执行Session的save()、update()、delete() 、load()和get()方法的时候,将从缓存中找到对应预定义的SQL语句,再把具体的参数值绑定到该SQL语句中。
#p#
2、创建命名策略
还有一直一种方法是实现Hibernate的org.hibernate.cfg.NamingStrategy接口,对于这个接口Hibernate提供了两种参考实现类:org.hibernate.cfg.defaultNamingStrategy和org.hibernate.cfg.ImprovedNamingStrategy类。
MyNamingStrategy.java
package mypack;
import org.hibernate.cfg.ImprovedNamingStrategy;
import org.hibernate.util.StringHelper;
public class MyNamingStrategy extends ImprovedNamingStrategy {
public String classToTableName(String className) {
return StringHelper.unqualify(className).toUpperCase()+'S';//classname转化成大写字母+S就是对应的表名
}
public String propertyToColumnName(String propertyName) {
return propertyName.toUpperCase();
}
public String tableName(String tableName) {
return tableName;
}
public String columnName(String columnName) {
return columnName;
}
public String propertyToTableName(String className, String propertyName) {
return classToTableName(className) + '_' +
propertyToColumnName(propertyName);
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
使用命名策略后可以更好的将数据库中表名、列名对象化成类中的对象。
#p#
3、实例
本节的代码下载地址:http://down.51cto.com/data/326754
主要的BusinessService.java
package mypack;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import java.util.*;
public class BusinessService{
public static SessionFactory sessionFactory;
static{
try{
Configuration config = new Configuration()
.setNamingStrategy( new MyNamingStrategy() )
.configure(); //加载hibernate.cfg.xml文件中配置的信息
sessionFactory = config.buildSessionFactory();
}catch(RuntimeException e){e.printStackTrace();throw e;}
}
public Customer loadCustomer(long customer_id){
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(customer_id));
tx.commit();
return customer;
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void saveCustomer(Customer customer){
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(customer);
tx.commit();
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void loadAndUpdateCustomer(long customerId) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(customerId));
customer.setDescription("A lovely customer!");
tx.commit();
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void updateCustomer(Customer customer){
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(customer);
tx.commit();
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void saveDictionary(Dictionary dictionary) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(dictionary);
tx.commit();
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void updateDictionary(Dictionary dictionary){
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(dictionary);
tx.commit();
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public Dictionary loadDictionary(long dictionary_id) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Dictionary dictionary=(Dictionary)session.get(Dictionary.class,new Long(dictionary_id));
tx.commit();
return dictionary;
}catch (RuntimeException e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void printCustomer(Customer customer){
System.out.println("name:"+customer.getName());
System.out.println("sex:"+customer.getSex());
System.out.println("description:"+customer.getDescription());
System.out.println("avgPrice:"+customer.getAvgPrice());
System.out.println("totalPrice:"+customer.getTotalPrice());
}
public void printDictionary(Dictionary dictionary){
System.out.println("type:"+dictionary.getType());
System.out.println("key:"+dictionary.getKey());
System.out.println("value:"+dictionary.getValue());
}
public void test(){
Customer customer=new Customer("Laosan","Zhang",'M',new HashSet(),"A good citizen!");
Order order1=new Order("Order001",new Double(100),customer);
Order order2=new Order("Order002",new Double(200),customer);
customer.getOrders().add(order1);
customer.getOrders().add(order2);
saveCustomer(customer);
customer=new Customer("Laowu","Wang",'M',new HashSet(),null);
saveCustomer(customer);
customer=loadCustomer(1);
printCustomer(customer);
customer.setDescription("An honest customer!");
updateCustomer(customer);
loadAndUpdateCustomer(1);
Dictionary dictionary=new Dictionary("SEX","M","MALE");
saveDictionary(dictionary);
dictionary=loadDictionary(1);
dictionary.setValue("MAN");
updateDictionary(dictionary);
dictionary=loadDictionary(1);
printDictionary(dictionary);
}
public static void main(String args[]) {
new BusinessService().test();
sessionFactory.close();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
原文链接:http://blog.csdn.net/yu422560654/article/details/7047661
【编辑推荐】