每个具体类对应一个表

  • 写一个虚拟父类,用具体类来继承这个虚拟父类,有多少个具体类就建多少张表,父表的外键关联全部的这些具体表
  • 由于根类是虚拟的,在父表这里也不必配置集合映射了,直接在具体类的映射文件中配置多对一的映射即可。
  • 通过外键来获取这些具体类时比较麻烦,要一个一个地去获取,然后再集成一个大集合
  • 下面举了一个例子,是学生拥有多张生活照和工作照的例子

     //学生父表
     public class Student {
    
         private long id;
         private String name;
         private Set images;
    }
    
    //照片虚拟类
    public abstract class Image {
    
         private int id;
         private String imageName;
         private Student student;
     }
    
     //生活照和工作照分别为其子类
     public class LifeImage extends Image{}
     public class WorkImage extends Image{}
    
     //配置学生映射文件
     
    
     
         
     
    
     
    
     
    
     
    
     //配置照片具体类映射文件(重点是都要加上下面这条)
     
    
    • 数据库

      //配置简单,但是获取复杂,假如有很多子类那么获取难度很大
      @Test
      public void testGetAllImages() {

      List imageList=new ArrayList();
      int stuId=1;
      //多态
      List lifeImageList=(List)session.createQuery("from LifeImage l where l.student.id="+stuId).list();
      imageList.addAll(lifeImageList);
      List workImageList=(List)session.createQuery("from WorkImage w where w.student.id="+stuId).list();
      imageList.addAll(workImageList);
      Iterator iterator=imageList.iterator();
      while(iterator.hasNext()) {
          Image image=(Image) iterator.next();
          System.out.println(image.getImageName());
      }
      

      }

      根类对应一个表

  • 创建一个图片的根类(非虚拟类),加上类型属性来区别具体类;
  • 让两个具体类来继承它,但是真正起作用的还是根类
  • 在学生配置文件中加入根类的集合映射
  • 在根类的映射文件中则要加入解释器和子类来区别图片具体类型
  • 获取的话直接一次获取根类即可

     //学生父表
     public class Student2 {
    
         private int id;
         private String name;
         private Set images;
     }
    
     //照片类
     public class Image2 {
    
         private int id;
         private String imageName;
         private String imageType; //用来区别照片类型
         private Student2 student;
    }
    
     //生活照和工作照分别为其子类
     public class LifeImage2 extends Image2{}
     public class WorkImage2 extends Image2{}
    
    //学生映射文件
    
         
         
     
    
     //照片映射文件
     
    
     
      
     
      
     
    
    • 数据库

      //配置略复杂(要配置subclass),但获取简单,直接获取根类即可
      @Test
      public void testGetAllImages2() {

      Student2 student2=(Student2)session.get(Student2.class, 1); //int的话可以直接放数字
      Set images=student2.getImages();
      Iterator iterator=images.iterator();
      while(iterator.hasNext()) {
          Image2 image2=(Image2)iterator.next();
          System.out.println(image2.getImageName());
      }
      

      }

      每个类对应一个表

  • 前两种要么只有根表,要么只有具体表,这种既有根表又有具体表。
  • 跟第二种一样,先创建具体的根类,再创建两个具体类继承根类
  • 学生映射文件中配置根类的集合映射,根类的映射文件中配置一个外键同时关联两张具体类的子表
  • 获取的时候统一获取

    //学生父表
    public class Student3 {
    
        private int id;
        private String name;
        private Set images;
    }
    
    //根类
    public class Image3 {
    
        private int id;
        private String imageName;
        private Student3 student;
    }
    
    //具体类
    public class LifeImage3 extends Image3{}
    public class WorkImage3 extends Image3{}
    
    //学生映射文件
    
        
        
    
    
    //根类映射文件
    
    
    
    
         
    
    
        
    
    
    • 数据库

    • 因为两张具体表的主键都跟根表的主键关联,因此两张具体表的主键不能相同,生活表有1的主键,工作表就不能出现1的主键

//直接获取即可
@Test
public void testGetAllImages3() {
    Student3 student3=(Student3)session.get(Student3.class, 1); //int的话可以直接放数字
    Set images=student3.getImages();
    Iterator iterator=images.iterator();
    while(iterator.hasNext()) {
        Image3 image3=(Image3)iterator.next();
        System.out.println(image3.getImageName());
    }
}

代码实例

  • HibernateExtends