在mysql里建立2个表
CREATE TABLE `customers` (
`id` int(11) NOT NULL auto_increment,
`name` char(20) character set latin1 default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `orders` (
`id` int(11) NOT NULL auto_increment,
`customer_id` int(50) NOT NULL default '0',
`order_number` int(50) default NULL,
PRIMARY KEY (`id`),
KEY `fk_customer_id` (`customer_id`),
CONSTRAINT `fk_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后自动生成持久化类,在customers.hbm.xml一方设置与orders的外键customer_id的一对多关联,其中联级操作为save-update,inverse="true"为表示hibernate不由customers对象的状态变化来更新数据库,仅按照Orders对象状态变化来更新数据库。由此来优化hibernate的性能。
<set name="orderses" inverse="true" cascade="save-update">
<key>
<column name="customer_id" unique="true" />
</key>
<one-to-many class="com.yourcompany.model.Orders" />
</set>
在orders.hbm.xml设置多对一关联,其中业务逻辑决定了order是由customer来下决定的,所以必须not-null="true" ,联级操作根据实际情况而定,本例子的逻辑关系里面,应该不需要在many-to-one一方设置save-update联级操作,因为增加orders并不需要增加customer。在目前的情况里如果设置了save-update,增加orders记录的时候hibernate就会把原来已存在的customers记录设置为null。这是不对的。
<many-to-one name="customers" class="com.yourcompany.model.Customers" fetch="select" >
<column name="customer_id" not-null="true" unique="true" />
</many-to-one>
在AddCustomerAction里保存一个customers,之后可以看到当保存一个customers的同时,orders也同时保存了该customers的id。
String strname = addCustomerForm.getString("name");
Customers customers = new Customers();
customers.setName(strname);
Orders orders=new Orders();
orders.setCustomers(customers);
customers.getOrderses().add(orders);
customersDAO.save(customers);
其中
orders.setCustomers(customers);
customers.getOrderses().add(orders);
在建立两个对象的双向关联时,应该同时修改关联两端的对象的相应属性,这样可提高业务逻辑的独立性。
比如:解除双向关联时:
customers.getOrderses().remove(orders);
orders.setCustomers(null);
在AddOrdersAction里,由表单传入customers的ID值和新增加的order_number值。ordersDAO.attachDirty(orders);为Myeclipse里生成的DAO,其调用的是HibernateTemplate的getHibernateTemplate().saveOrUpdate(instance);方法。
Integer strcustomers= Integer.valueOf(addOrdersForm.getString("customers"));
Integer strorder_number= Integer.valueOf(addOrdersForm.getString("order_number"));
Orders orders = new Orders();
Customers customers = new Customers();
customers.setId(strcustomers);
orders.setCustomers(customers);
orders.setOrderNumber(strorder_number);
ordersDAO.attachDirty(orders);
在这里的持久化对象的生命周期里,当Customers customers = new Customers();时,Customers还属于临时状态,而到了sessionv.save(customers);的时候Customers由临时状态转变为持久化状态。临时状态时不处于Session缓存中,转化为持久化状态后Customers就加入到了Session缓存中,在此Customers customers 2=(Customers)session.load(Customer.class,id);、Customers customers 3=(Customers)session.load(Customer.class,id);、均是在持久化状态。而直到session.close();就表明Customers退出了Session缓存,由持久化状态转变为游离状态。System.out.println(customers 3.getname());也是处于游离状态。到最后c2=null;c3=null;Customers生命周期结束。
Session有三种检索方法:load()、get()、find(),检索策略有类级别的:立即检索、延迟检索,关联级别的立即检索、延迟检索、迫切左外连接检索。在类级别中应该有线考虑使用立即检索。不管hbm文件里lazy属性是true还是false,Session的get()、find()方法总是使用立即检索策略。
在一对多关联级别中,对于<set>元素不能随意使用立即检索策略,尽量使用延迟检索策略。应用程序如果新闻访问游离状态的代理类实例,必须保证它在持久化状态时已经被初始化,不然会抛出异常
对于多对一或一对一关联,应该优先考虑使用外连接检索策略,因为它比立即检索策略使用的select语句数目少。在默认情况下<many-to-one>元素的outer-join属性为auto,<class>元素的lazy属性为false,因此默认使用迫切外连接检索策略。迫切外连接检索策略受数据库表的大小和连接影响,如果select语句中的外连接表的数目太多,会影响检索性能,可以通过Hibernate配置文件中的hibernate.max_fetch_depth来达到优化。hibernate.max_fetch_depth取决数据库连接性能及表大小。
posted on 2007-08-27 10:15
lzj520 阅读(729)
评论(0) 编辑 收藏 所属分类:
个人学习日记 、
Hibernate