风也温柔

计算机科学知识库

精通hibernate:java对象持久化技术详解 《精通Hibernate》学习(3)——对象关系映射基础

  1、持久化类的属性和访问方法 (1)持久化类简介

  在中持久化类的访问方法有两个调用者,一个是Java应用程序,一个是。值得注意的是,Java应用程序不能访问持久化类的类型的()、(),而没有这样的限制。

  (2)基本类型属性和包装类型属性

  Java有8种基本类型:byte,short,char,int,long,float,,;与之对应的Java提供了8种包装类型:Byte,Short精通hibernate:java对象持久化技术详解 《精通Hibernate》学习(3)——对象关系映射基础,,,Long精通hibernate:java对象持久化技术详解,Float精通hibernate:java对象持久化技术详解,,。基本类型与包装类型之间可以如下简单转换:

   double prD=1;

    //把double基本类型转换成Double包装类型
    Double wrD=new Double(prD);
    //把Double包装类型转换成double基本类型

  两种类型都是支持的。

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

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

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

   public String getName(){

        return firstname+ " "+lastname;
     }
     public void setName(String name){
       StringTokenizer t=new StringTokenizer(name);
       firstname=t.nextToken();
       lastname=t.nextToken();

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

  

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

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

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

  

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

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

  假定类中有一个属性,表示订单的平均价格,取值为它所关联Order对象的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;
    <p>![精通hibernate:java对象持久化技术详解_hibernate的三种对象状态_精通hibernate 孙卫琴][1]

          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) );
          }

</p>
  在.hbm.xml文件不用映射,因为不会直接访问属性,也不会调用()和().

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

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

   public char getSex(){

        return this.sex;
      }
      public void setSex(char sex){
          if(sex!=&#39;F&#39; && sex!=&#39;M&#39;){
            throw new IllegalArgumentException("Invalid Sex");
          }
          this.sex =sex ;

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

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

  利用

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

  

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

   select totalPrice from CUSTOMERS;

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

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

  如果子句的查询结果为空,那么上述的语句就会出现异常。解决方法是:将的属性定义为包装类型。

  (5)控制和语句

  在初始化阶段,就会根据映射文件的映射信息,为所有的持久化类定义以下的SQL语句。

  以上SQL语句中的“?”代表JDBC 中的参数。这些SQL语句都存放在的内置缓存中,当执行的save()、()、()、load()和get()方法的时候,将从缓存中找到对应预定义的SQL语句,再把具体的参数值绑定到该SQL语句中。

  2、创建命名策略

  还有一直一种方法是实现的org..cfg.接口,对于这个接口提供了两种参考实现类:org..cfg.y和org..cfg.gy类。

  .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()+&#39;S&#39;;//classname转化成大写字母+S就是对应的表名
    <p>![精通hibernate:java对象持久化技术详解_精通hibernate 孙卫琴_hibernate的三种对象状态][2]

       }
       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) + &#39;_&#39; +
                propertyToColumnName(propertyName);
       }

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

  3、实例

  本节的代码下载地址:

  主要的.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;
    <p>![hibernate的三种对象状态_精通hibernate 孙卫琴_精通hibernate:java对象持久化技术详解][3]

        } 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 {
    &emsp;&emsp;![精通hibernate:java对象持久化技术详解_精通hibernate 孙卫琴_hibernate的三种对象状态][4]

          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",&#39;M&#39;,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",&#39;M&#39;,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();
      }
    }

</p>
  文章来源:https://blog.csdn.net/yu422560654/article/details/7047661