浏览 2681 次
锁定老帖子 主题:Hibernate关系映射
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-06-09
Xdoclet对组件的映射是这样写的 Customer.java /** * @hibernate.component * class="pojo.Address" */ private Address address; Address.java不需要映射class,因为address只是Customer的属性,是值类型,不是实体类型。 /** * @hibernate.property * column="home_Address" */ private String homeAddress; /** * @hibernate.property * column="com_Address" */ private String comAddress; 在Customer.hbm.xml会生成 <component name="address" class="pojo.Address"> <property name="homeAddress" column="home_Address"/> <property name="comAddress" column="com_Address"/> </component> 在数据库中,T_Customer会生成home_Address和com_Address字段 One-to-one外键关联 Customer.java /** * @hibernate.many-to-one * unique="true" * cascade="save-update" */ private Address address; 生成映射文件 <many-to-one unique="true" name="address" cascade="save-update"/> 即在T_Customer表中设置T_Address的外键 Address.java /** * @hibernate.one-to-one * class="pojo.Customer" * property-ref="address" */ private Customer customer; 生成映射文件 <one-to-one name="customer" property-ref="address" class="pojo.Customer"/> property-ref="address"指定外键 测试: CustomerManagerImpl m=new CustomerManagerImpl(); Customer c=new Customer(); c.setName("大大"); c.setData(new Date()); Address ads=new Address(); ads.setComAddress("五一路"); ads.setHomeAddress("五四路"); c.setAddress(ads); m.addCustomer(c); Many-to-One双向关联 Customer.java /** * @author Administrator *@hibernate.class * table=T_Customer */ public class Customer { /** * @hibernate.id * column="cid" * generator-class="native" */ private int id; /** * @hibernate.property * column="name" */ private String name; /** * @hibernate.property * column="data" */ private Date data; /** * @hibernate.set * inverse="true" * cascade="save-update" * @hibernate.key * column="customer" * @hibernate.one-to-many * class="pojo.Address" */ private Set address=new HashSet(); } Address.java /** *@hibernate.class * table=T_Address */ public class Address { /** * @hibernate.id * column="aid" * generator-class="native" */ private int id; /** * @hibernate.property * column="address" */ private String address; /** * * @hibernate.many-to-one * class="pojo.Customer" * */ private Customer customer; } 测试: CustomerManagerImpl m=new CustomerManagerImpl(); public void testAddCustomer() { Customer c=new Customer(); c.setData(new Date()); c.setName("李世民"); Address a1=new Address(); a1.setAddress("五台山"); Address a2=new Address(); a2.setAddress("长白山"); c.getAddress().add(a1); c.getAddress().add(a2); m.addCustomer(c); } 当set中没有设置Inverse=true时(主控在Customer方),执行如下sql Hibernate: insert into T_Customer (name, data) values (?, ?) Hibernate: insert into T_Address (address, customer) values (?, ?) Hibernate: insert into T_Address (address, customer) values (?, ?) Hibernate: update T_Address set customer=? where aid=? Hibernate: update T_Address set customer=? where aid=? 设置inverse=true时(主控在Address方),执行如下sql Hibernate: insert into T_Customer (name, data) values (?, ?) Hibernate: insert into T_Address (address, customer) values (?, ?) Hibernate: insert into T_Address (address, customer) values (?, ?)少了两条update语句 看表的结构 mysql> desc t_address; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | aid | int(11) | NO | PRI | NULL | auto_increment | | address | varchar(255) | YES | | NULL | | | customer | int(11) | YES | MUL | NULL | | +----------+--------------+------+-----+---------+----------------+ mysql> desc t_customer; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | cid | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | data | datetime | YES | | NULL | | +-------+--------------+------+-----+---------+----------------+ 在t_address中有个外键指向t_customer,因为这个外键在表t_address中,如果主控方是Customer,那么当commit时Hibernate清理缓存,探测到Customer,和Address均有变化,这时Customer无法知道Address的状态,所以为了保证同步更新数据库,额外执行了两条update语句。假如主控方在Address,那么Address可以知道自己的状态,并通过外键也可以知道Customer的状态,所以无须做额外的更新。这对提高数据库的性能有很大的帮助。以上是我对inverse的理解,如有错误还请指正。 Many-to-Many双向关联 Bank.java /** * @hibernate.set * table="T_Bank_Customer" * inverse="true" * @hibernate.key * column="bid" * @hibernate.many-to-many * column="cid" * class="pojo.Customer" */ private Set customers=new HashSet(); Customer.java /** *@hibernate.set * table="T_Bank_Customer" * cascade="all" *@hibernate.key * column="cid" *@hibernate.many-to-many * column="bid" * class="pojo.Bank" */ private Set band=new HashSet(); 测试: CustomerManagerImpl m=new CustomerManagerImpl(); public void testAddCustomer() { Bank b=new Bank(); b.setName("中国银行"); Customer c=new Customer(); c.setData(new Date()); c.setName("黄骅"); b.getCustomers().add(c); c.getBand().add(b); m.addCustomer(c); } Inverse在哪一方设置为tru都会执行如下sql: Hibernate: insert into T_Customer (name, data) values (?, ?) Hibernate: insert into T_Bank (name) values (?) Hibernate: insert into T_Bank_Customer (bid, cid) values (?, ?) 如果两边都没有设置inferse则默认为false那么两边都管理,导致混乱报异常。如果两都设置为true则会导致任何操作都不触发对关系表的操作,两表的数据添加了,但连接表为空,说明关系没有建立。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |