1)使用一张表
1> 原理:使用一张表来保存父类和子类中的所有字段,并通过一个字段来区别不同的类
2> pojo设计
父类:
public class Article {
private int id;
private String title;
private Date date;
private String content;
}
子类:
public class Topic extends Article {
private int type;//表示是精华、置顶...
}
public class Replay extends Article {
private int floor;
}
3> 映射文件
注:映射文件要和父类同名
</pre><pre name="code" class="html"> <class name="cn.com.cpf.pojo.Article" table="t_article">
<id name="id" column="id">
<generator class="native"/>
</id>
<discriminator column="class_" type="string"/>
<property name="content" length="500" type="text"/>
<property name="date" type="timestamp"/>
<property name="title"/>
<subclass name="cn.com.cpf.pojo.Topic" discriminator-value="Topic">
<property name="type" type="int"/>
</subclass>
<subclass name="cn.com.cpf.pojo.Replay" discriminator-value="Replay">
<property name="floor"/>
</subclass>
</class>
</pre> 说明:</p><p> 1.discriminator标签用来在一个表中区别不同的类,column指定保存区别的字段</p><p> 2.subcla标签用来指定子类的特有属性,name为子类的全名,discriminator-value用来指定在区别字段中的值,默认的是类的全名 4> 生成的数据库表结构</p><p> <img src="https://img-blog.youkuaiyun.com/20140811180552659" alt="" /> 5> 保存操作</p><p><pre name="code" class="java"> factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();
Article article = new Article();
article.setTitle("this is a article");
Topic topic = new Topic();
topic.setTitle("this is a topic");
Replay replay = new Replay();
replay.setTitle("this is a replay");
session.save(article);
session.save(topic);
session.save(replay);
tx.commit();
结果为:
6> 获取操作
Article article1 = (Article) session.get(Article.class, 1);
Topic article2 = (Topic) session.get(Topic.class, 2);
Replay article3 = (Replay) session.get(Replay.class, 3);
System.out.println(article1.getTitle());
System.out.println(article2.getTitle());
System.out.println(article3.getTitle());
结果为:
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select topic0_.id as id1_2_0_, topic0_.content as content3_2_0_, topic0_.date as date4_2_0_, topic0_.title as title5_2_0_, topic0_.type as type6_2_0_ from t_article topic0_ where topic0_.id=? and topic0_.class_='Topic'
Hibernate: select replay0_.id as id1_2_0_, replay0_.content as content3_2_0_, replay0_.date as date4_2_0_, replay0_.title as title5_2_0_, replay0_.floor as floor7_2_0_ from t_article replay0_ where replay0_.id=? and replay0_.class_='Replay'
this is a article
this is a topic
this is a replay
或者:
Article article1 = (Article) session.get(Article.class, 1);
Article article2 = (Article) session.get(Article.class, 2);
Article article3 = (Article) session.get(Article.class, 3);
System.out.println(article1.getTitle());
System.out.println(article2.getTitle());
System.out.println(article3.getTitle());
结果为:
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
this is a article
this is a topic
this is a replay
2)每个类均使用一张表(包括抽象类)
1> 原理:
1.父类对应表中存放公共字段,子类中仅存放自己特有的
2.子类对应表通过主键关联和父类进行一对一映射
2> 映射文件
<class name="cn.com.cpf.pojo.Article" table="t_article2">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="content" length="500" type="text"/>
<property name="date" type="timestamp"/>
<property name="title"/>
<joined-subclass name="cn.com.cpf.pojo.Topic" table="t_topic2">
<key column="aid"/>
<property name="type"/>
</joined-subclass>
<joined-subclass name="cn.com.cpf.pojo.Replay" table="t_replay2">
<key column="aid"/>
<property name="floor"/>
</joined-subclass>
</class>
3> 生成的表结构
父类表结构:
子类Topic表结构
子类Replay表结构
4> 保存
Article article = new Article();
article.setTitle("this is a article");
Topic topic = new Topic();
topic.setTitle("this is a topic");
Replay replay = new Replay();
replay.setTitle("this is a replay");
session.save(article);
session.save(topic);
session.save(replay);
结果为:
3)每一个具体类均对应一张表(抽象类不对应)
1> 原理:
子类对应表包含所有字段,包括父类中的
2> 映射文件
<class name="cn.com.cpf.pojo.Article" abstract="true" table="t_article2">
<id name="id" column="id">
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">10</param>
</generator>
</id>
<property name="content" length="500" type="text"/>
<property name="date" type="timestamp"/>
<property name="title"/>
<union-subclass name="cn.com.cpf.pojo.Topic" table="t_topic3">
<property name="type"/>
</union-subclass>
<union-subclass name="cn.com.cpf.pojo.Replay" table="t_replay3">
<property name="floor"/>
</union-subclass>
</class>
说明:
1.如果注明abstract=true,那么就不会生成表
2.使用这种继承方式,id生成方式不能为identity(因为要求整个继承体系中id均为唯一的,这样才能使用多态的特性,而identity是数据库自动生成,极有可能对topic和replay表生成相同的id,这样通过Article.class来查找的时候就无法确定找出来的是哪一个)
3> 生成的数据库表结构
topic表:
replay表:
4> 保存
Article article = new Article();
article.setTitle("this is a article");
Topic topic = new Topic();
topic.setTitle("this is a topic");
Replay replay = new Replay();
replay.setTitle("this is a replay");
session.save(article);
session.save(topic);
session.save(replay);
结果为:
4) 总结
继承结构一般很少使用,因为需要查找多张表,效率会低