传统方式继承
需求:动物、猫、猴子。猫继承着动物
传统方式继承的特点就是:有多少个子类就写多少个配置文件.
表结构
我们的表应该是这样的:id和name从Animal中继承,catchMouse是子类的具体行为。
这里写图片描述
实体
Animal.java
package zhongfucheng.aa; // 动物类 public abstract class Animal { private int id; private String name; 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; } }
Cat.java继承着Animail
package zhongfucheng.aa; public class Cat extends Animal{ // 抓老鼠 private String catchMouse; public String getCatchMouse() { return catchMouse; } public void setCatchMouse(String catchMouse) { this.catchMouse = catchMouse; } }
映射文件
简单继承的映射文件很好写,在属性上,直接写父类的属性就可以了。
但是也有致命的缺点:如果子类有很多,就需要写很多的配置文件
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="zhongfucheng.aa" > <class name="Cat" table="cat" > <!--映射主键--> <id name="id" column="id"> <generator class="native"></generator> </id> <!-- 映射普通字段 父类的属性直接引用就行了,比如name属性,直接写就行了! --> <property name="name" column="name" ></property> <property name="catchMouse" column="catchMouse" ></property> </class> </hibernate-mapping>
测试
package zhongfucheng.aa; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; public class App5 { public static void main(String[] args) { //创建对象 Cat cat = new Cat(); //设置属性 cat.setName("大花猫"); cat.setCatchMouse("捉大老鼠"); //获取加载配置管理类 Configuration configuration = new Configuration(); configuration.configure().addClass(Cat.class); //创建Session工厂对象 SessionFactory factory = configuration.buildSessionFactory(); //得到Session对象 Session session = factory.openSession(); //使用Hibernate操作数据库,都要开启事务,得到事务对象 Transaction transaction = session.getTransaction(); //开启事务 transaction.begin(); session.save(cat); //如果取数据时候Animal父类接收的话,需要给出Anmail的全名 //提交事务 transaction.commit(); //关闭Session session.close(); } }
这里写图片描述
把所有子类映射成一张表
前面我们采用的是:每个子类都需要写成一个配置文件,映射成一张表…
如果子类的结构很简单,只比父类多几个属性。就像上面的例子…我们可以将所有的子类都映射成一张表中
但是呢,这样是不符合数据库设计规范的…..因为表中的数据可能是猫,可能是猴子…这明显是不合适的…
由于表中可能存在猫,存在猴子,为了区分是什么类型的。我们需要使用鉴别器
我们了解一下…
数据表
这里写图片描述
实体
实体和上面雷同,只多了一个猴子的实体表
Monkey.java
public class Monkey extends Animal { // 吃香蕉 private String eatBanana; public String getEatBanana() { return eatBanana; } public void setEatBanana(String eatBanana) { this.eatBanana = eatBanana; } }
映射文件
使用了subClass这个节点和鉴别器
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- 继承映射, 所有的子类都映射到一张表 --> <hibernate-mapping package="cn.itcast.e_extends2"> <class name="Animal" table="t_animal"> <id name="id"> <generator class="native"></generator> </id> <!-- 指定鉴别器字段(区分不同的子类) --> <discriminator column="type_"></discriminator> <property name="name"></property> <!-- 子类:猫 每个子类都用subclass节点映射 注意:一定要指定鉴别器字段,否则报错! 鉴别器字段:作用是在数据库中区别每一个子类的信息, 就是一个列 discriminator-value="cat_" 指定鉴别器字段,即type_字段的值 如果不指定,默认为当前子类的全名 --> <subclass name="Cat" discriminator-value="cat_"> <property name="catchMouse"></property> </subclass> <!-- 子类:猴子 --> <subclass name="Monkey" discriminator-value="monkey_"> <property name="eatBanana"></property> </subclass> </class> </hibernate-mapping>
测试
加载的是Animal父类的映射文件。保存的是cat和monkey。
package zhongfucheng.aa; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; public class App5 { public static void main(String[] args) { //创建对象 Cat cat = new Cat(); Monkey monkey = new Monkey(); //设置属性 cat.setName("大花猫"); cat.setCatchMouse("小老鼠"); monkey.setEatBanana("吃香蕉"); monkey.setName("大猴子"); //获取加载配置管理类 Configuration configuration = new Configuration(); //加载Animal的映射文件! configuration.configure().addClass(Animal.class); //创建Session工厂对象 SessionFactory factory = configuration.buildSessionFactory(); //得到Session对象 Session session = factory.openSession(); //使用Hibernate操作数据库,都要开启事务,得到事务对象 Transaction transaction = session.getTransaction(); //开启事务 transaction.begin(); session.save(cat); session.save(monkey); //提交事务 transaction.commit(); //关闭Session session.close(); } }
这里写图片描述