孙卫琴Hibernate第四章对象-关系映射基础

 
单个持久化类与单个数据库表之间进行映射的技巧:
主要解决以下问题:
       持久化类的属性没有相关的setXXX()和getXXX()方法;
持久化类的属性在数据库中没有对应的字段,或者数据库中的字段在持久化类中没有对应的属性;
控制Hibernate生成的insert和update语句;
设置从持久化类映射到数据库表,以及持久化类的属性映射到数据库表的字段的命名策略;
一.持久化类的属性及访问方法
 
1 、getXXX() setXXX() 的产生是为了控制属性的读权限和改权限;
2 、java中的基本类型和包装类型对应着相同的Hibernate映射类型;
3 、在持久化类中,java基本类型和包装类型比较:基本类型操作方便,可以直接进行运算,包装类不行;基本数据类型不能表达NULL值。(java包装类型与sql数据类型有更直接的对应关系)
二.Hibernate访问持久化类属性的策略
1.在对象--关系映射文件中,<property>元素的access属性用于指定访问持久化类的属性的方法。
      (1)property 默认值。表示Hibernate通过相应的setXXX() 和 getXXX()方法访问属性。
      (2)field 表明Hibernate运用java反射机制直接访问类的属性。(类中没有提供属性的setXXX() 和 getXXX()方法)
2. 在Customer类的setSex()方法中加入数据验证逻辑。
 
public void setSex( char sex){
       if (sex!= 'F' && sex!= 'M' ){
           throw new IllegalArgumentException( "Invalid Sex" );
       }
       this .sex=sex;
}
setSex( char sex) 有两个调用者: java 应用程序和 Hibernate Java 应用程序调用时,参数可能来自用户界面输入的数据,需要验证;而 hibernate 调用时,参数值来自数据库读出的数据,通常是合法的,不需要验证。 解决这一个矛盾的方法是:
  把映射文件中的 sex 属性的 <property> 元素的 access 属性设为 ”field”
这样 hinernate 就会直接访问 Customer 实例的 sex 属性,而不调用 set get 方法
 
一个例子:
1 数据库部分:
drop database if exists SAMPLEDB;
create database SAMPLEDB;
use SAMPLEDB;
 
create table DICTIONARIES (
   ID bigint not null ,
   TYPE varchar (15),
   TYPE_KEY varchar (15),
   VALUE varchar (128),
   primary key (ID)
);
create table ORDERS (
   ID bigint not null ,
   ORDER_NUMBER varchar (15),
   PRICE double precision ,
   CUSTOMER_ID bigint not null ,
   primary key (ID)
);
create table CUSTOMERS (
   ID bigint not null ,
   NAME varchar (15),
   SEX char (1),
   `CUSTOMER DESCRIPTION` text,
   primary key (id)
);
alter table ORDERS add index IDX_CUSTOMER (CUSTOMER_ID), add constraint FK_CUSTOMER foreign key (CUSTOMER_ID) references CUSTOMERS (id);
 
注意: `CUSTOMER DESCRIPTION` sql 引用标识符 数据库中的字段含有空格)
2 java类:
 
Customer.java
 
package mypack;
 
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
 
public class Customer implements Serializable {
 
    private Long id ;
 
    private String firstName ;
 
    private String lastName ;
 
    private char sex ;
 
    private Set orders = new HashSet();
 
    private double avgPrice ;
 
    private double totalPrice ;
 
    private String description ;
 
    public Customer() {
       // TODO Auto-generated constructor stub
    }
 
    public Customer(String lastName, String firstName, char sex,
           HashSet orders, String description) {
       // TODO Auto-generated constructor stub
 
       this . lastName = lastName;
       this . firstName = firstName;
       this . sex = sex;
       this . orders = orders;
       this . description = description;
 
    }
 
    public double getAvgPrice() {
       return avgPrice ;
    }
 
    public String getDescription() {
       return description ;
    }
 
    public void setDescription(String description) {
       this . description = description;
    }
 
    public String getFirstName() {
       return firstName ;
    }
 
    public Long getId() {
       return id ;
    }
 
    public void setId(Long id) {
       this . id = id;
    }
 
    public String getLastName() {
       return lastName ;
    }
 
    public Set getOrders() {
       return orders ;
    }
 
    public void setOrders(Set orders) {
       this . orders = orders;
    }
 
    public char getSex() {
       return sex ;
    }
 
    public void setSex( char sex) {
 
       if (sex != 'F' && sex != 'M' ) {
           throw new IllegalArgumentException( "Invalid Sex" );
       }
       this . sex = sex;
    }
 
    public double getTotalPrice() {
       return totalPrice ;
    }
 
    public void setTotalPrice( double totalPrice) {
       this . totalPrice = totalPrice;
    }
 
    public String getName() {
       return firstName + " " + lastName ;
    }
 
    public void setName(String name) {
       StringTokenizer t = new StringTokenizer(name);
       firstName = t.nextToken();
       lastName = t.nextToken();
    }
 
    public void caculatePrice() {
 
       double avgPrice = 0.0;
       double totalPrice = 0.0;
       int count = 0;
       Iterator it = getOrders().iterator();
       while (it.hasNext()) {
 
           Order order = (Order) it.next();
           totalPrice += order.getOrderPrice();
           count++;
       }
       avgPrice = totalPrice / count;
       setAvgPrice(avgPrice);
    }
 
    public void setAvgPrice( double avgPrice) {
       this . avgPrice = avgPrice;
    }
}
 
Order.java 类
 
package mypack;
 
import java.io.Serializable;
 
public class Order implements Serializable {
 
    private Long id ;
 
    private double orderPrice ;
 
    private String order_number ;
 
    private double price ;
 
    private Customer customer ;
 
    public Order(String order_number, double price, Customer customer) {
       // TODO Auto-generated constructor stub
       this . order_number = order_number;
       this . price = price;
       this . customer = customer;
    }
 
    public Customer getCustomer() {
       return customer ;
    }
 
    public void setCustomer(Customer customer) {
       this . customer = customer;
    }
 
    public String getOrder_number() {
       return order_number ;
    }
 
    public void setOrder_number(String order_number) {
       this . order_number = order_number;
    }
 
    public double getPrice() {
       return price ;
    }
 
    public void setPrice( double price) {
       this . price = price;
    }
 
    public double getOrderPrice() {
       return orderPrice ;
    }
 
    public void setOrderPrice( double orderPrice) {
       this . orderPrice = orderPrice;
    }
 
    public Long getId() {
       return id ;
    }
 
    private void setId(Long id) {
       this . id = id;
    }
}
 
Dictionary.java
 
package mypack;
 
import java.io.Serializable;
 
public class Dictionary implements Serializable {
 
    private Long id ;
 
    private String type ;
 
    private String type_key ;
 
    private String value ;
 
    public Dictionary() {
 
    }
 
    public Dictionary(String type, String type_key, String value) {
       this . type = type;
       this . type_key = type_key;
       this . value = value;
    }
 
    public Long getId() {
       return id ;
    }
 
    private void setId(Long id) {
       this . id = id;
    }
 
    public String getType() {
       return type ;
    }
 
    public void setType(String type) {
       this . type = type;
    }
 
    public String getType_key() {
       return type_key ;
    }
 
    public void setType_key(String type_key) {
       this . type_key = type_key;
    }
 
    public String getValue() {
       return value ;
    }
 
    public void setValue(String value) {
       this . value = value;
    }
}
 
3 映射文件部分
 
Customer.hbm.xml
 
<? xml version = "1.0" encoding = "utf-8" ?>
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
< hibernate-mapping >
    < class name = "mypack.Customer" table = "customers"
       catalog = "sampledb" dynamic-insert="true" dynamic-update="true" lazy = "false" >
       <!-- dynamic-insert="true" dynamic-update="true" 分别表示 insert 语句中仅包含所有取值不为空的字段 只有字段发生变化时才会包含到 update 语句中 -->
       < id name = "id" type = "long" >
           < column name = "ID" />
           < generator class = "increment" />
       </ id >
       < property name = "name" type = "string" >
           < column name = "NAME" />
       </ property >
       < property name = "sex" type = "character" access="field" > <!-- 直接取设属性值 -->
           < column name = "SEX" length = "1" />
       </ property >
       < property name = "description" type = "text" >
           < column name = " `CUSTOMER DESCRIPTION` " />
 
       </ property >
       < property name = "totalPrice"
           formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)" > <!— 数据库中不含有次字段,它对应一个 sql 语句的结果 -->
       </ property >
       < set name = "orders" inverse = "true" cascade = "save-update" >
           < key column = "CUSTOMER_ID" ></ key >
           < one-to-many class = "mypack.Order" />
       </ set >
 
    </ class >
</ hibernate-mapping >
 
Order.hbm.xml
<? xml version = "1.0" encoding = "utf-8" ?>
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
< hibernate-mapping >
    < class name = "mypack.Order" table = "ORDERS" catalog = "sampledb" dynamic-insert = "true" dynamic-update = "true" >
       < id name = "id" type = "long" >
           < column name = "ID" />
           < generator class = "increment" />
       </ id >
       < property name = "order_number" >
       </ property >
       < property name = "price" ></ property >
       < many-to-one name = "customer" column = "CUSTOMER_ID"
           class = "mypack.Customer" >
       </ many-to-one >
    </ class >
</ hibernate-mapping >
 
Dictionary.hbm.xml
 
<? xml version = "1.0" encoding = "utf-8" ?>
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
    < class name = "mypack.Dictionary" table = "DICTIONARIES"
       catalog = "sampledb" mutable = "false" lazy = "false" > <!--  整个实例不能被更新 -->
       < id name = "id" type = "long" >
           < column name = "ID" />
           < generator class = "increment" />
       </ id >
       < property name = "type" type = "string" access = "field" ></ property >
       < property name = "type_key" type = "string" access = "field" ></ property >
       < property name = "value" type = "string" access = "field" ></ property >
    </ class >
</ hibernate-mapping >
4 测试类
 
package mypack;
 
import java.util.HashSet;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import sessionFactory.HibernateSessionFactory;
 
public class BusinessService {
 
    public Customer loadCustomer(Long customer_id) throws Exception {
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
 
       try {
 
           tr = session.beginTransaction();
           Customer customer = (Customer) session.load(Customer. class ,
                  customer_id);
           tr.commit();
           return customer;
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
 
    }
 
    public void saveCustomer(Customer customer) throws Exception {
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
       try {
           tr = session.beginTransaction();
           session.save(customer);
           tr.commit();
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
    }
 
    public void loadAndUpdateCustomer(Long customerId) throws Exception {
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
       try {
           tr = session.beginTransaction();
           Customer customer = (Customer) session.load(Customer. class ,
                  customerId);
           customer.setDescription( "A lovely customer!" );
           tr.commit();
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
 
    }
 
    public void updateCustomer(Customer customer) throws Exception {
 
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
       try {
           tr = session.beginTransaction();
           session.update(customer);
           tr.commit();
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
    }
 
    public void saveDictionary(Dictionary dictionary) throws Exception {
 
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
       try {
           tr = session.beginTransaction();
           session.save(dictionary);
           tr.commit();
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
    }
 
    public void updateDictionary(Dictionary dictionary) throws Exception {
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
       try {
           tr = session.beginTransaction();
           session.update(dictionary);
           tr.commit();
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.rollback();
           }
           throw e;
       } finally {
           session.close();
       }
    }
 
    public Dictionary loadDictionary(Long dictionary_id) throws Exception {
       Session session = HibernateSessionFactory.getSession();
       Transaction tr = null ;
 
       try {
 
           tr = session.beginTransaction();
           Dictionary dictionary = (Dictionary) session.load(Dictionary. class ,
                  dictionary_id);
           tr.commit();
           return dictionary;
       } catch (Exception e) {
           // TODO : handle exception
           if (tr != null ) {
              tr.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.getType_key());
       System. out .println( "value:" + dictionary.getValue());
    }
 
    public void test() throws Exception {
       // Customer customer = new Customer("Laosan", "Zhang", 'M', new
       // HashSet(),
       // "A good citizen!");
       // Order order1 = new Order("Order001", 100, customer);
       // Order order2 = new Order("Order002", 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(new Long(1));
       //
       // customer.setDescription("An honest customer!");
       // updateCustomer(customer);
       //
       // printCustomer(customer);
       //    
       // loadAndUpdateCustomer(new Long(1));
 
       Dictionary dictionary = new Dictionary( "SEX" , "M" , "MALE" );
       saveDictionary(dictionary);
       printDictionary(dictionary);
 
       dictionary = loadDictionary( new Long(1));
       dictionary.setValue( "MAN" );
       updateDictionary(dictionary);
      
      
        dictionary = loadDictionary( new Long(1));
        printDictionary(dictionary);
 
    }
 
    public static void main(String[] args) throws Exception {
 
       BusinessService b = new BusinessService();
       b.test();
    }
}
 
5 问题:
在测试 Customer 和 Dictionary的load 方法时报错:
could not initialize proxy - the owning Session was closed
 
解决办法:把对应类的映射文件中加入 lazy= "false" 限制( class 元素中)
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值