1 一对多关系在使用的时候一定要慎重,尽量保证在多的段下面不超过100。
2 多对多关系尽量不要使用。
3 组件关联,就是说,不是两张表,是一张表。
4 set这个类,没有顺序,也不允许重复。
5 list可以允许重复。
Employee.java
package cn.itcast.domain;
public class Employee {
private int id;
private String name;
private Department depart;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepart() {
return depart;
}
public void setDepart(Department depart) {
this.depart = depart;
}
}
Employee.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 package="cn.itcast.domain">
<class name="Employee">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<many-to-one name="depart" column="depart_id"></many-to-one>
</class>
</hibernate-mapping>
Department.java
package cn.itcast.domain;
import java.util.List;
public class Department {
private int id;
private String name;
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Department.hbm.xml
package cn.itcast.domain;
import java.util.List;
public class Department {
private int id;
private String name;
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package cn.itcast.dao.test;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.itcast.dao.HibernateUtil;
import cn.itcast.domain.Department;
import cn.itcast.domain.Employee;
public class Many2One {
/**
* @param args
*/
public static void main(String[] args) {
add();
}
static Employee query(int empId)
{
Session s=null;
Transaction tx=null;
try {
s=HibernateUtil.getSession();
tx=s.beginTransaction();
Employee employee=(Employee) s.get(Employee.class,empId);
tx.commit();
return employee;
} finally {
if (s!=null)
s.close();
}
}
static Department add()
{
Session s=null;
Transaction tx=null;
try {
Department depart =new Department();
depart.setName("depart");
Employee emp1=new Employee();
emp1.setDepart(depart);//建立两个对象之间的关联
emp1.setName("emp1");
Employee emp2=new Employee();
emp2.setDepart(depart);//建立两个对象之间的关联
emp2.setName("emp2");
List<Employee> list=new ArrayList<Employee>();
list.add(emp1);
list.add(emp2);
depart.setEmployees(list);
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.save(emp1);
s.save(emp2);
s.save(depart);
tx.commit();
return depart;
} finally {
if (s!=null)
s.close();
}
}
}
但是如果用list的话其实在数据库的表中多出来一项,用来描述list的顺序,但是他也是会消耗资源的。
所以我们现在我们使用bag来做配置,就不用多出来一项,其他的配置与list完全相同,测试代码页完全相同。
Department.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 package="cn.itcast.domain">
<class name="Department">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<!--
<set name="employees">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>
-->
<!--
<list name="employees">
<key column="depart_id"></key>
<list-index column="index_col"></list-index>
<one-to-many class="Employee"/>
</list>
-->
<bag name="employees">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</bag>
</class>
</hibernate-mapping>
在这个程序运行的时候,有一个小插曲。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.ExceptionInInitializerError
at cn.itcast.dao.test.Many2One.add(Many2One.java:61)
at cn.itcast.dao.test.Many2One.main(Many2One.java:19)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource cn/itcast/domain/Department.hbm.xml
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXml(Configuration.java:4009)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXmlQueue(Configuration.java:3998)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3986)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1398)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1856)
at cn.itcast.dao.HibernateUtil.<clinit>(HibernateUtil.java:29)
... 2 more
Caused by: org.hibernate.DuplicateMappingException: Duplicate collection role mapping cn.itcast.domain.Department.employees
at org.hibernate.cfg.Configuration$MappingsImpl.addCollection(Configuration.java:3211)
at org.hibernate.cfg.HbmBinder.createClassProperties(HbmBinder.java:2189)
at org.hibernate.cfg.HbmBinder.createClassProperties(HbmBinder.java:2164)
at org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(HbmBinder.java:412)
at org.hibernate.cfg.HbmBinder.bindRootClass(HbmBinder.java:326)
at org.hibernate.cfg.HbmBinder.bindRoot(HbmBinder.java:177)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processHbmXml(Configuration.java:4006)
... 7 more
注意Duplicate collection role mapping cn.itcast.domain.Department.employees。也就是说重复赋值。
当时我去检查java代码没有问题,后来在检查xml配置文件的时候,发现对employees这个属性配置了两次,一次使用set
另一次使用list,也就是说上一次的代码忘记加上注释了。