每个具体类对应一个表
- 写一个虚拟父类,用具体类来继承这个虚拟父类,有多少个具体类就建多少张表,父表的外键关联全部的这些具体表
- 由于根类是虚拟的,在父表这里也不必配置集合映射了,直接在具体类的映射文件中配置多对一的映射即可。
- 通过外键来获取这些具体类时比较麻烦,要一个一个地去获取,然后再集成一个大集合
下面举了一个例子,是学生拥有多张生活照和工作照的例子
//学生父表 public class Student { private long id; private String name; private Set<String> images; } //照片虚拟类 public abstract class Image { private int id; private String imageName; private Student student; } //生活照和工作照分别为其子类 public class LifeImage extends Image{} public class WorkImage extends Image{} //配置学生映射文件 <class name="Student" table="t_student"> <id name="id" column="stuId"> <generator class="native"></generator> </id> <property name="name"></property> <!-- Image类是抽象类,主要是两个实现类在起作用,所以这里配置了Image的映射也没什么用 --> </class> //配置照片具体类映射文件(重点是都要加上下面这条) <many-to-one name="student" column="stuId" class="com.java1234.model.Student"></many-to-one>
数据库
//配置简单,但是获取复杂,假如有很多子类那么获取难度很大
@Test
public void testGetAllImages() {List<Image> imageList=new ArrayList<Image>(); int stuId=1; //多态 List<Image> lifeImageList=(List<Image>)session.createQuery("from LifeImage l where l.student.id="+stuId).list(); imageList.addAll(lifeImageList); List<Image> workImageList=(List<Image>)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<Image2> 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{} //学生映射文件 <set name="images"> <key column="stuId"></key> <one-to-many class="com.java1234.model.Image2"></one-to-many> </set> //照片映射文件 <many-to-one name="student" column="stuId" class="com.java1234.model.Student2"></many-to-one> <!--解释器,主要是作为标识的--> <discriminator column="imageType" type="string"></discriminator> <!--默认是string--> <!--子类--> <subclass name="com.java1234.model.LifeImage2" discriminator-value="li"></subclass> <!--假如imageType是li这个值那就是LifeImage2类--> <subclass name="com.java1234.model.WorkImage2" discriminator-value="wi"></subclass>
数据库
//配置略复杂(要配置subclass),但获取简单,直接获取根类即可
@Test
public void testGetAllImages2() {Student2 student2=(Student2)session.get(Student2.class, 1); //int的话可以直接放数字 Set<Image2> 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<Image3> images; } //根类 public class Image3 { private int id; private String imageName; private Student3 student; } //具体类 public class LifeImage3 extends Image3{} public class WorkImage3 extends Image3{} //学生映射文件 <set name="images"> <key column="stuId"></key> <one-to-many class="com.java1234.model.Image3"></one-to-many> </set> //根类映射文件 <many-to-one name="student" column="stuId" class="com.java1234.model.Student3"></many-to-one> <!-- 创建两张关联表 --> <joined-subclass name="com.java1234.model.LifeImage3" table="t_lifeImage3"> <key column="lifeImageId"></key> <!-- 主键,将会关联本表(总图片表)的主键,也即是三张图片表的主键同时都是外键 --> </joined-subclass> <joined-subclass name="com.java1234.model.WorkImage3" table="t_workImage3"> <key column="workImageId"></key> </joined-subclass>
数据库
因为两张具体表的主键都跟根表的主键关联,因此两张具体表的主键不能相同,生活表有1的主键,工作表就不能出现1的主键
//直接获取即可
@Test
public void testGetAllImages3() {
Student3 student3=(Student3)session.get(Student3.class, 1); //int的话可以直接放数字
Set<Image3> images=student3.getImages();
Iterator iterator=images.iterator();
while(iterator.hasNext()) {
Image3 image3=(Image3)iterator.next();
System.out.println(image3.getImageName());
}
}
代码实例
- HibernateExtends