hibernate的强大就不多说,通过配置文件可以实现查询结果集的自动封装也不多说,我就直接从集合映射中来说吧。
常用的映射集合以Set和List最为常见,先以set为例。
假定有Order(订单)以及Item(订单项)两个JavaBean。订单中可以包含多个Item,于是在Order的POJO映射文件即Order.hbm.xml文件中应该:
<set name="items"> <!-- key表示用于维护关系的列为order_id --> <key column="order_id"></key> <!-- 这里表示Set中的元素为Item --> <one-to-many class="entity.Item"/> </set>
Order中有属性:
private Set<Item> items;//这里只能使用Set接口,而不能使用Set的实现类
至于为什么一定要用Set接口就不知道了,但是,实例化时是可以使用HashSet这样的实现类的。
这样,在编写的测试用例中写如下代码:
public static void main(String []args){ Session s=HibernateSessionFactory.getSession(); Transaction tx= s.beginTransaction(); tx.begin(); Order order=(Order)s.get(Order.class, 1); System.out.println(order.getAddress()); System.out.println(order.getItems()); tx.commit(); s.close(); }
是可以看出控制台输出我们想要的东西的。
但是如果需要保存一份新的Order呢?
@Test public void test_save(){ Order order=new Order(); order.setAddress("北京市朝阳区"); order.setUserId(2); Item it=new Item(); it.setOrderId(order.getId()); it.setProductId(3); Set<Item> items=new HashSet<Item>(); items.add(it); order.setItems(items); Session s=HibernateSessionFactory.getSession(); Transaction tx= s.beginTransaction(); tx.begin(); s.save(order); tx.commit(); s.close(); }
会有异常抛出:
Could not synchronize database state with session
org.hibernate.TransientObjectException
因为这时候,hibernate对于Set集合使用的是update语句,而非insert语句
Hibernate: insert into test.d_order (user_id, address) values (?, ?) Hibernate: update test.d_item set order_id=? where id=?
其实只需在Order.hbm.xml中配置Set的cascade属性为all即可,也可以选择其他的save-update也可以。
此时save操作是正常的,Hibernate执行的SQL语句为:
Hibernate: insert into test.d_order (user_id, address) values (?, ?) Hibernate: insert into test.d_item (order_id, product_id) values (?, ?) Hibernate: update test.d_item set order_id=? where id=?
为什么还会执行一次update?现在还不明白
——————————————————————————————————————————————————————————————————
关于cascade属性的可能值有
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作,但不具备级联保存和更新。
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点,也支持级联删除和级联保存更新。
比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点,即被删除。
——————————————————————————————————————————————————————————————————
以下为此用例的数据库建表语句:
create table d_order(id int(4) primary key auto_increment, user_id int(4), address varchar(30))default charset=UTF8; drop table d_item; create table d_item(id int(4) primary key auto_increment, order_id int(4), product_id int(4)); insert into d_order(user_id,address )values(1,'中华人民共和国'); insert into d_item(order_id ,product_id) values(1,2);
浙公网安备 33010602011771号