十一 聚合映射 List集合
十一 集合映射 List集合
十一 集合映射 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 完毕!