首先是设计两个实体类,在网上借贷系统中,通常一个用户可以有多笔贷款,这就是一个简单的一对多/多对一关系
简单的实体类设计
public class User implements Serializable {
private Integer id;
private String name;
private Set<Loan> loans = new HashSet<Loan>(0);
//getter() and setter()
}
public class Loan implements Serializable {
private Integer id;
private User user;
private String loanName;
//getter() and setter()
}
然后是xml配置文件
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yin.model.User" table="user">
<id name="id">
<generator class="identity"></generator>
</id>
<property name="name">
<column name="name"></column>
</property>
<set name="loans" inverse="true" lazy="false" fetch="select">
<key>
<column name="user_id"></column>
</key>
<one-to-many class="com.yin.model.Loan"/>
</set>
</class>
</hibernate-mapping>
Loan.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yin.model.Loan" table="loan">
<id name="id">
<column name="id"></column>
<generator class="identity"></generator>
</id>
<property name="loanName">
<column name="loan_name"></column>
</property>
<many-to-one name="user" class="com.yin.model.User" fetch="select">
<column name="user_id" ></column>
</many-to-one>
</class>
</hibernate-mapping>
这样就实现了两个实体类的一对多/多对一双向关联
在这里还要重点讲一下inverse属性,这里们写一个Test类,通过sql语句的打印来观察inverse=false/true时对数据库操作的不同
session.beginTransaction();
User user = new User();
user.setName("shandong");
Loan loan = new Loan();
loan.setLoanName("loan123");
loan.setUser(user);
user.getLoans().add(loan);
session.save(user);
session.save(loan);
session.getTransaction().commit();
session.close();
在不考虑级联的情况下,如果inverse=false 打印的sql语句是
Hibernate: insert into user (name) values (?)
Hibernate: insert into loan (loan_name, user_id) values (?, ?)
Hibernate: update loan set user_id=? where id=?
当inverse=true时
Hibernate: insert into user (name) values (?)
Hibernate: insert into loan (loan_name, user_id) values (?, ?)
这样我们就很明白的可以看到inverse的作用:
inverse的默认属性是false,表示关系的两端都维护关系,也就是说,当你保存一个用户时,会首先执行User的保存,然后更新外键,最后再保存Loan。当inverse=true时,就表明一方放弃主键的维护,交由多方来维护,这样就省略了无谓的更新语句。说到这里,我在总结一下Inverse属性
首先,inverse的默认值是false,表现在一对多的关系中就是一方和多方同时维护主键(关系)
然后,inverse一般配置在set属性中,inverse=true表示一方放弃主外键的维护,即将主外键的关系交由多方来维护,可以省却不必要的更新语句。