十一 集合映射
set的集合配置方式在一对多 多对一 多对多中已经讲过 将不再阐述
现在来看List这种集合的映射方式
List形式的映射
部门实体
package vo.util.bean;
import java.util.List;
/**
* 部门类
* @author Administrator
*
*/
public class Department {
private int id;
private String name;
private List<Employee> ems;
public int getId() {
return id;
}
public List<Employee> getEms() {
return ems;
}
public void setEms(List<Employee> ems) {
this.ems = ems;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
映射文件
<?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
package="vo.util.bean">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 配置一对多的映射关系 -->
<!--
<set name="ems">
-->
<!-- 关联关系的外键 -->
<!--
<key column="depaer_id"/>
-->
<!-- 关联关系的实体类配置 -->
<!--
<one-to-many class="Employee" />
</set>
-->
<list name="ems">
<key column="depaer_id"/>
<!-- 这一列指定其记录顺序 这一列由hibernate来使用 -->
<list-index column="ol"/>
<one-to-many class="Employee"/>
</list>
</class>
</hibernate-mapping>
映射文件分析:list标签就是配置List形式属性的标签 key是一个外键 比如说 现在我们查出了部门信息
我还想查员工信息 怎么查 key这时候就起作用了 这个键是在员工表这存在的 并且这列是作为外键而存在,它的
值就是部门表主键id 所以这就好办了 就可以查出来了 那么list-index是作什么用的呢?这个啊,是交给hibernate
使用的,是用来干什么的,是用来存放顺序的值,为什么set标签怎么就没有这个呢?这就牵扯到set与list的区别了
Set与List集合的区别 最大区别就是list可以存放重复值,并是按顺序存放的
现在知道了吧 这个list-index其实就是给hibernate存放顺序的,这个列自己可以随便定义 以上这两个列都会在部门表的从表中存在
值由hibernate自动去存的,当然这些都是在部门表的映射文件中配置的,那么当然在增加数据的时候,必须由部门对象去跟从表实体
给关联对象 否则会出现顺序这一列的值在从实体的员工表中是空值,如果利用其部门对象去获取从表的对象,将会出现空列值异常
org.hibernate.HibernateException: null index column for collection 那下面的one-to-many的class表示什么呢,表示的是list
这个属性是属于哪一个实体类 当前指定的是 Employee实体类,通过这hibernate就可以知道其从实体的表了
员工实体类
package vo.util.bean;
/**
* 员工类
* @author Administrator
*
*/
public class Employee {
private int id;
private String name;
private Department derpartment;
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 getDerpartment() {
return derpartment;
}
public void setDerpartment(Department derpartment) {
this.derpartment = derpartment;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "id="+this.id+"name="+this.name;
}
}
映射文件
<?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
package="vo.util.bean">
<class name="Employee">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="derpartment" column="depaer_id"/>
</class>
</hibernate-mapping>
测试类
package vo.util.test;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import vo.util.HibernateUtil;
import vo.util.bean.Department;
import vo.util.bean.Employee;
public class ManytoOne {
/**
* @param args
*/
public static void main(String[] args) {
add();
Department dpart= queryDepart(1);
// System.out.println(dpart.getEms());
}
static Department add(){
Session session = null;
Transaction tx = null;
try{
session =HibernateUtil.getSession();
tx = session.beginTransaction();
//…你的代码save,delete,update,get…
Department dpart=new Department();
dpart.setName("BSM部门");
Employee em1=new Employee();
em1.setName("员工许春荣");
Employee em2=new Employee();
em2.setName("员工丁辉");
em1.setDerpartment(dpart);
em2.setDerpartment(dpart);
List<Employee> em=new ArrayList<Employee>();
em.add(em1);
em.add(em2);
dpart.setEms(em);
session.save(dpart);
session.save(em1);
session.save(em2);
tx.commit();
return dpart;
}finally{
if(session != null)session.close();
}
}
static Employee query(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
Employee em=(Employee)session.get(Employee.class, id);
//System.out.println(em.getDerpartment().getEms());
return em;
}finally{
if(session != null)session.close();
}
}
static Department queryDepart(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
session.beginTransaction();
Department dep=(Department)session.get(Department.class, id);
session.beginTransaction().commit();
System.out.println(dep.getEms());
return dep;
}finally{
if(session != null)session.close();
}
}
}
如果把上面的增加员工数据的方法 dpart.setEms(em);给注释掉 将会出现空列值异常 因为没有让部门去设置其关系
那么在部门的映射的顺序列(给hibernate使用的)ol列在员工表中出现空值的现象,导致hibernate去查询的时候,因为
在list集合里,它会按顺序把值给输出来,而现在是空值,就不知道其顺序了,所以就会报此错误 dep.getEms()这一句是
获取ems的集合数据 这个集合是list的集合
很多时候顺序并不是我所考虑的,对我来讲无所谓,还可以用另外一种映射方式,当然这种方式只是跟List集合结合使用
,其它那是不可以的
请看
修改前的部门实体映射文件
<?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
package="vo.util.bean">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 配置一对多的映射关系 -->
<!--
<set name="ems">
-->
<!-- 关联关系的外键 -->
<!--
<key column="depaer_id"/>
-->
<!-- 关联关系的实体类配置 -->
<!--
<one-to-many class="Employee" />
</set>
-->
<list name="ems">
<key column="depaer_id"/>
<!-- 这一列指定其记录顺序 这一列由hibernate来使用 -->
<list-index column="ol"/>
<one-to-many class="Employee"/>
</list>
</class>
</hibernate-mapping>
修改后的
<?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
package="vo.util.bean">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 配置一对多的映射关系 -->
<!--
<set name="ems">
-->
<!-- 关联关系的外键 -->
<!--
<key column="depaer_id"/>
-->
<!-- 关联关系的实体类配置 -->
<!--
<one-to-many class="Employee" />
</set>
-->
<!--
<list name="ems">
<key column="depaer_id"/>
-->
<!-- 这一列指定其记录顺序 这一列由hibernate来使用 -->
<!--
<list-index column="ol"/>
<one-to-many class="Employee"/>
</list>
-->
<bag name="ems">
<key column="depaer_id"/>
<one-to-many class="Employee"/>
</bag>
</class>
</hibernate-mapping>
这时在测试的时候,谁指定关系已经无所谓了,只要有一个实体对象关联另外一个实体对象就行
这时关联的对象仅仅是把外键的值给加上 在外键这个值上,为了合理必须给加上not null约束
否则如果没有对象关联其关系,也会把数据给增加上,比如说部门与员工,如果员工的外键没有给加上
这个约束,将可以给员工录入数据,这条数据就跟部门没有任何关系了,这条数据不属于任何部门
当然这个外键hibernate是放在哪个表中的,当然就由哪个表的实体去维护了,如果在主实体的映射文件的外键
配置其属性,会报其Repeated column in mapping for entity: vo.util.bean.Employee column异常
所以只需要在员工表的实体配置其属性即可
当然其关联关系当然由其从表实体员工去关联,否则如果由主表部门实体去关联,将会报非空约束异常
如果主表和从表都去关联,那么在主表保存数据的时候,它会去更新从表实体的数据,将会多出update语句
最好从表关联了,主表就不要去关联了,除非需要;
package vo.util.test;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import vo.util.HibernateUtil;
import vo.util.bean.Department;
import vo.util.bean.Employee;
public class ManytoOne {
/**
* @param args
*/
public static void main(String[] args) {
add();
Department dpart= queryDepart(1);
// System.out.println(dpart.getEms());
}
static Department add(){
Session session = null;
Transaction tx = null;
try{
session =HibernateUtil.getSession();
tx = session.beginTransaction();
//…你的代码save,delete,update,get…
Department dpart=new Department();
dpart.setName("BSM部门");
Employee em1=new Employee();
em1.setName("员工许春荣");
Employee em2=new Employee();
em2.setName("员工丁辉");
//关联主表外键数据
em1.setDerpartment(dpart);
em2.setDerpartment(dpart);
List<Employee> em=new ArrayList<Employee>();
em.add(em1);
em.add(em2);
//这里已经不做关联从表的数据
//dpart.setEms(em);
session.save(dpart);
session.save(em1);
session.save(em2);
tx.commit();
return dpart;
}finally{
if(session != null)session.close();
}
}
static Employee query(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
Employee em=(Employee)session.get(Employee.class, id);
//System.out.println(em.getDerpartment().getEms());
return em;
}finally{
if(session != null)session.close();
}
}
static Department queryDepart(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
session.beginTransaction();
Department dep=(Department)session.get(Department.class, id);
session.beginTransaction().commit();
System.out.println(dep.getEms());
return dep;
}finally{
if(session != null)session.close();
}
}
}
好了到这就结束list集合映射了
end 完毕!