精通Hibernate:对象关系映射基础

 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。基本类型与包装类型之间可以如下简单转换:

 
 
 
 
  1. double prD=1;  
  2. //把double基本类型转换成Double包装类型  
  3. Double wrD=new Double(prD);  
  4. //把Double包装类型转换成double基本类型  
  5. prD=wrD.doubleValue(); 

Hibernate两种类型都是支持的。

(3)在持久化类的访问方法中加入程序逻辑

(a)在Customer类的getName()和setName()方法中加入程序逻辑

假如在Customer类中有firstname属性和lastname属性,但是没有name属性,而数据库CUSTOMERS表中只有NAME字段。当Hibernate从数据库中取得了CUSTOMERS表的NAME字段值后,会调用setName()方法,此时应该让Hibernate通过setName()方法来自动设置firstname属性和lastname。故要在setName()方法中加入额外的程序逻辑。

 
 
 
 
  1.  public String getName(){  
  2.    return firstname+ " "+lastname;  
  3. }  
  4.  
  5. public void setName(String name){  
  6.   StringTokenizer t=new StringTokenizer(name);  
  7.   firstname=t.nextToken();  
  8.   lastname=t.nextToken();  

在映射文件中此时直接映射name即可,无需映射firstname等。

 
 
 
 
  1.  

尽管在Customer类中没有定义name属性,由于Hibernate并不会直接访问name属性,而是通过getName()和setName()方法。只要在Customer.hbm.xml文件中映射了name属性,HQL语句就能访问:

 
 
 
 
  1. Query query=seesion.createQuery("from Customer as c where c.name='Tom'"); 

但是如果把Customer.hbm.xml文件中name属性配置为:

 
 
 
 
  1.  

程序会直接去访问Customer实例中的name属性,就会出现异常。

(b)在Customer类的setOrders()方法中加入程序逻辑

假定Customer类中有一个avgPrice属性,表示订单的平均价格,取值为它所关联Order对象的price的平均值。在CUSTOMERS表中没有AVG_PRICE字段。可以如下操作:

 
 
 
 
  1. public Double getAvgPrice(){  
  2.      return this.avgPrice;  
  3.  }  
  4.  private void setAvgPrice( Double avgPrice ){  
  5.      this.avgPrice = avgPrice;  
  6.  }  
  7.  public Double getTotalPrice(){  
  8.      return this.totalPrice;  
  9.  }  
  10.  private void setTotalPrice( Double totalPrice ){  
  11.      this.totalPrice = totalPrice;  
  12.  }  
  13.  
  14.  public void setOrders( Set orders ){  
  15.    this.orders = orders;  
  16.    calculatePrice();  
  17.  }  
  18.  public Set getOrders(){  
  19.    return orders;  
  20.  }//定义为一个Set  
  21.  private void calculatePrice(){  
  22.      double avgPrice = 0.0;  
  23.      double totalPrice = 0.0;  
  24.      int count=0;  
  25. /迭代计算orders里面所有price  
  26.      if ( getOrders() != null ){  
  27.        Iterator iter = getOrders().iterator();  
  28.        while( iter.hasNext() ){  
  29.          double orderPrice = ((Order)iter.next()).getPrice();  
  30.          totalPrice += orderPrice;  
  31.          count++;  
  32.        }  
  33.        // Set the price for the order from the calcualted value  
  34.        avgPrice=totalPrice/count;  
  35.        setAvgPrice( new Double(avgPrice) );  
  36.      }  
  37.  } 

在Customer.hbm.xml文件不用映射avgPrice,因为Hibernate不会直接访问avgPrice属性,也不会调用getavgPrice()和setavgPrice().

(c)在Customer类的setSex()方法中加入数据验证逻辑

在持久化类的访问方法中,还可以加入数据验证逻辑。

 
 
 
 
  1. public char getSex(){  
  2.    return this.sex;  
  3.  }  
  4.  public void setSex(char sex){  
  5.      if(sex!='F' && sex!='M'){  
  6.        throw new IllegalArgumentException("Invalid Sex");  
  7.      }  
  8.      this.sex =sex ;  
  9.  } 

(4)设置派生属性
持久化类并非所有属性都直接和表的字段匹配,持久化类的有些属性是可以在运行的时候得出的,这些称作派生属性。正如之前的avgPrice属性,该方案包括两个步骤:

  • 在映射文件中不映射avgPrice属性
  • 在Customer类的setOrders()方法中加入程序逻辑,自动为avgPrice属性赋值。

除了这种方法来设置派生属性,还可以如下解决:

利用元素的formula属性。formula属性用来设置一个SQL表达式,Hibernate将根据它来计算派生属性的值。以Customer类的totalPrice属性为例:

 
 
 
 
  1.  

在Hibernate从数据库中查询Customer对象时,若查询totalPrice,即:

 
 
 
 
  1. select totalPrice from CUSTOMERS; 

使用formula属性后,上面的查询语句就会自动地被替代成:

 
 
 
 
  1. select (select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=1) from CUSTOMERS; 

如果子句的查询结果为空,那么上述的语句就会出现异常。解决方法是:将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

 
 
 
 
  1. package mypack;  
  2. import org.hibernate.cfg.ImprovedNamingStrategy;  
  3. import org.hibernate.util.StringHelper;  
  4. public class MyNamingStrategy extends ImprovedNamingStrategy {  
  5.    public String classToTableName(String className) {  
  6.         return  StringHelper.unqualify(className).toUpperCase()+'S';//classname转化成大写字母+S就是对应的表名  
  7.    }  
  8.    public String propertyToColumnName(String propertyName) {  
  9.        return propertyName.toUpperCase();  
  10.    }  
  11.    public String tableName(String tableName) {  
  12.        return tableName;  
  13.    }  
  14.    public String columnName(String columnName) {  
  15.        return columnName;  
  16.    }  
  17.    public String propertyToTableName(String className, String propertyName) {  
  18.        return classToTableName(className) + '_' +  
  19.             propertyToColumnName(propertyName);  
  20.    }  

使用命名策略后可以更好的将数据库中表名、列名对象化成类中的对象。

#p#

3、实例

本节的代码下载地址:http://down./data/326754

主要的BusinessService.java

 
 
 
 
  1. package mypack;  
  2.  
  3. import org.hibernate.*;  
  4. import org.hibernate.cfg.Configuration;  
  5. import java.util.*;  
  6.  
  7. public class BusinessService{  
  8.   public static SessionFactory sessionFactory;  
  9.   static{  
  10.      try{  
  11.        Configuration config = new Configuration()  
  12.              .setNamingStrategy( new MyNamingStrategy() )  
  13.              .configure();       //加载hibernate.cfg.xml文件中配置的信息  
  14.       sessionFactory = config.buildSessionFactory();  
  15.     }catch(RuntimeException e){e.printStackTrace();throw e;}  
  16.   }  
  17.  
  18.   public Customer loadCustomer(long customer_id){  
  19.     Session session = sessionFactory.openSession();  
  20.     Transaction tx = null;  
  21.     try {  
  22.       tx = session.beginTransaction();  
  23.       Customer customer=(Customer)session.get(Customer.class,new Long(customer_id));  
  24.       tx.commit();  
  25.       return customer;  
  26.     }catch (RuntimeException e) {  
  27.       if (tx != null) {  
  28.          tx.rollback();  
  29.       }  
  30.       throw e;  
  31.     } finally {  
  32.        session.close();  
  33.     }  
  34.   }  
  35.  
  36.   public void saveCustomer(Customer customer){  
  37.     Session session = sessionFactory.openSession();  
  38.     Transaction tx = null;  
  39.     try {  
  40.       tx = session.beginTransaction();  
  41.       session.save(customer);  
  42.       tx.commit();  
  43.  
  44.     }catch (RuntimeException e) {  
  45.       if (tx != null) {  
  46.          tx.rollback();  
  47.       }  
  48.       throw e;  
  49.     } finally {  
  50.        session.close();  
  51.     }  
  52.   }  
  53.  
  54.     public void loadAndUpdateCustomer(long customerId) {  
  55.       Session session = sessionFactory.openSession();  
  56.       Transaction tx = null;  
  57.       try {  
  58.         tx = session.beginTransaction();  
  59.         Customer customer=(Customer)session.get(Customer.class,new Long(customerId));  
  60.         customer.setDescription("A lovely customer!");  
  61.         tx.commit();  
  62.  
  63.     }catch (RuntimeException e) {  
  64.       if (tx != null) {  
  65.         tx.rollback();  
  66.       }  
  67.       throw e;  
  68.     } finally {  
  69.       session.close();  
  70.     }  
  71.   }  
  72.  
  73.   public void updateCustomer(Customer customer){  
  74.     Session session = sessionFactory.openSession();  
  75.     Transaction tx = null;  
  76.     try {  
  77.       tx = session.beginTransaction();  
  78.       session.update(customer);  
  79.       tx.commit();  
  80.  
  81.     }catch (RuntimeException e) {  
  82.       if (tx != null) {  
  83.          tx.rollback();  
  84.       }  
  85.       throw e;  
  86.     } finally {  
  87.        session.close();  
  88.     }  
  89.   }  
  90.  
  91.   public void saveDictionary(Dictionary dictionary) {  
  92.     Session session = sessionFactory.openSession();  
  93.     Transaction tx = null;  
  94.     try {  
  95.       tx = session.beginTransaction();  
  96.       session.save(dictionary);  
  97.       tx.commit();  
  98.  
  99.     }catch (RuntimeException e) {  
  100.       if (tx != null) {  
  101.         tx.rollback();  
  102.       }  
  103.       throw e;  
  104.     } finally {  
  105.       session.close();  
  106.     }  
  107.   }  
  108.  
  109.  public void updateDictionary(Dictionary dictionary){  
  110.     Session session = sessionFactory.openSession();  
  111.     Transaction tx = null;  
  112.     try {  
  113.       tx = session.beginTransaction();  
  114.       session.update(dictionary);  
  115.       tx.commit();  
  116.  
  117.     }catch (RuntimeException e) {  
  118.       if (tx != null) {  
  119.         tx.rollback();  
  120.       }  
  121.       throw e;  
  122.     } finally {  
  123.       session.close();  
  124.     }  
  125.   }  
  126.   public Dictionary loadDictionary(long dictionary_id) {  
  127.     Session session = sessionFactory.openSession();  
  128.     Transaction tx = null;  
  129.     try {  
  130.       tx = session.beginTransaction();  
  131.       Dictionary dictionary=(Dictionary)session.get(Dictionary.class,new Long(dictionary_id));  
  132.       tx.commit();  
  133.       return dictionary;  
  134.     }catch (RuntimeException e) {  
  135.       if (tx != null) {  
  136.         tx.rollback();  
  137.       }  
  138.       throw e;  
  139.     } finally {  
  140.       session.close();  
  141.     }  
  142.   }  
  143.  
  144.   public void printCustomer(Customer customer){  
  145.       System.out.println("name:"+customer.getName());  
  146.       System.out.println("sex:"+customer.getSex());  
  147.       System.out.println("description:"+customer.getDescription());  
  148.       System.out.println("avgPrice:"+customer.getAvgPrice());  
  149.       System.out.println("totalPrice:"+customer.getTotalPrice());  
  150.   }  
  151.  
  152.   public void printDictionary(Dictionary dictionary){  
  153.       System.out.println("type:"+dictionary.getType());  
  154.       System.out.println("key:"+dictionary.getKey());  
  155.       System.out.println("value:"+dictionary.getValue());  
  156.   }  
  157.    public void test(){  
  158.       Customer customer=new Customer("Laosan","Zhang",'M',new HashSet(),"A good citizen!");  
  159.       Order order1=new Order("Order001",new Double(100),customer);  
  160.       Order order2=new Order("Order002",new Double(200),customer);  
  161.       customer.getOrders().add(order1);  
  162.       customer.getOrders().add(order2);  
  163.  
  164.       saveCustomer(customer);  
  165.  
  166.       customer=new Customer("Laowu","Wang",'M',new HashSet(),null);  
  167.       saveCustomer(customer);  
  168.  
  169.       customer=loadCustomer(1);  
  170.       printCustomer(customer);  
  171.  
  172.       customer.setDescription("An honest customer!");  
  173.       updateCustomer(customer);  
  174.  
  175.       loadAndUpdateCustomer(1);  
  176.  
  177.       Dictionary dictionary=new Dictionary("SEX","M","MALE");  
  178.       saveDictionary(dictionary);  
  179.  
  180.       dictionary=loadDictionary(1);  
  181.       dictionary.setValue("MAN");  
  182.       updateDictionary(dictionary);  
  183.  
  184.       dictionary=loadDictionary(1);  
  185.       printDictionary(dictionary);  
  186.  
  187.    }  
  188.  
  189.   public static void main(String args[]) {  
  190.     new BusinessService().test();  
  191.     sessionFactory.close();  
  192.   }  

原文链接:http://blog.csdn.net/yu422560654/article/details/7047661

文章标题:精通Hibernate:对象关系映射基础
文章路径:http://www.hantingmc.com/qtweb/news16/416.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联