Hibernate繼承映射之每個(gè)繼承層次一張表

1.概述
關(guān)系數(shù)據(jù)庫的表之間不存在繼承關(guān)系资锰,為了將面向?qū)ο笾械睦^承關(guān)系映射到關(guān)系數(shù)據(jù)庫中,可使用三種映射策略:

1追他、每個(gè)繼承層次一張表
2便瑟、每個(gè)具體類一張表
3仪壮、每個(gè)類一張表

2.每個(gè)繼承層次一張表
即用一張表表示一個(gè)繼承層次,因此需要增加一個(gè)字段用于區(qū)別

public class Person {
    private int id;
    private String name;
    private String sex;
    private int age;
}
public class Student extends Person {
    private String sno;
    private String school;
}
public class Worker extends Person{
    private String no;
    private double salary;
}

image.png

映射語法:

1胳徽、定義一個(gè)以父類命名的映射文件
2、<id>標(biāo)記對(duì)后面添加<discriminator>標(biāo)記爽彤,并指定column屬性來定義鑒別字段
3养盗、父類屬性放在<class>標(biāo)記對(duì)之間,子類屬性放在<subclass>標(biāo)記對(duì)之間
4适篙、在各類標(biāo)記中使用discriminator-value屬性指定各類對(duì)應(yīng)的鑒別字段的值

示例:

1往核、數(shù)據(jù)庫連接
2、為項(xiàng)目添加Hibernate支持
3嚷节、創(chuàng)建持久化類
4聂儒、創(chuàng)建映射文件
5虎锚、修改hibernate配置文件
6、創(chuàng)建工具類獲取Session實(shí)例
7衩婚、編寫Dao接口及其實(shí)現(xiàn)類
8窜护、測(cè)試

項(xiàng)目結(jié)構(gòu):


image.png

Person類:

public class Person {
    private int id;
    private String name;
    private String sex;
    private int age;

    public Person() {}

    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Worker類:

public class Worker extends Person{
    private String no;
    private double salary;

    public Worker() {}
    public Worker(String name, String sex, int age, String no, double salary) {
        super(name, sex, age);
        this.no = no;
        this.salary = salary;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

Student類:

public class Student extends Person {
    private String sno;
    private String school;

    public Student() {
    }

    public Student(String name, String sex, int age, String sno, String school) {
        super(name, sex, age);
        this.sno = sno;
        this.school = school;
    }

    public String getSno() {
        return sno;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }
}

工具類:

public class HibernateUtil {
    private static SessionFactory sf;

    // 工具類不允許實(shí)例化
    private HibernateUtil() {
    }
    // 靜態(tài)代碼塊,只執(zhí)行一次非春,提高性能
    static {
        Configuration cf = new Configuration().configure();
        sf = cf.buildSessionFactory();
    }
    public static Session getSession() {
        Session session = sf.getCurrentSession();
        return session;
    }
}

Dao及其實(shí)現(xiàn)類:

public interface HibernateDao {
    public void addPerson(Person person);
    @SuppressWarnings("unchecked")
    public List getAllPerson(String hql);
}

public class HibernateDaoImpl implements HibernateDao {
    @Override
    public void addPerson(Person person) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        try {
            session.save(person);
            tx.commit();
        } catch (Exception e) {
            if (null != tx) {
                tx.rollback();
            }
            e.printStackTrace();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public List getAllPerson(String hql) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery(hql);
        List persons = query.list();
        tx.commit();
        return persons;
    }
}

測(cè)試類:

public class HibernateTest {
    public static void main(String[] args) {
        Person person = new Person("張三", "男", 20);
        Worker worker = new Worker("李四", "女", 28, "P0001", 6000);
        Student student = new Student("王五", "女", 19, "SD001", "廣金");
        HibernateDao hibernateDao = new HibernateDaoImpl();
        hibernateDao.addPerson(person);
        hibernateDao.addPerson(student);
        hibernateDao.addPerson(worker);
        String hql = "from Person";
        List<Person> persons = hibernateDao.getAllPerson(hql);
        System.out.println("========所有人員信息=======");
        for (Person p : persons) {
            System.out.println("姓名:" + p.getName() + " 性別:" + p.getSex() + " 年齡:" + p.getAge());
        }
        hql = "from Worker";
        List<Worker> workers = hibernateDao.getAllPerson(hql);
        System.out.println("========工人信息=======");
        for (Worker w : workers) {
            System.out.println("姓名:" + w.getName() + " 性別:" + w.getSex() + " 年齡:" + w.getAge() +
                    " 工號(hào):" + w.getNo() + "薪水:" + w.getSalary());
        }
        hql = "from Student";
        List<Student> students = hibernateDao.getAllPerson(hql);
        System.out.println("========學(xué)生信息=======");
        for (Student s : students) {
            System.out.println("姓名:" + s.getName() + " 性別:" + s.getSex() + " 年齡:" + s.getAge() +
                    " 學(xué)號(hào):" + s.getSno() + "學(xué)校:" + s.getSchool());
        }
    }
}

Person.hbm.xml

<?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="這里寫你的Person類所在的包">
    <!--ORM對(duì)象柱徙、關(guān)系數(shù)據(jù)庫映射-->
    <class name="Person" table="person" discriminator-value="person">
        <id name="id" type="integer">
            <generator class="native"/>
        </id>
        <!--設(shè)置鑒別字段-->
        <discriminator column="type" type="string" length="15"/>
        <!--從父類繼承下來的共享屬性-->
        <property name="name" type="string" column="username" length="12" not-null="true"/>
        <property name="sex" type="string" length="1"/>
        <property name="age" type="integer"/>
        <subclass name="Student" discriminator-value="student">
            <!--子類新增屬性-->
            <property name="sno" type="string" length="10"/>
            <property name="school" type="string" length="50"/>
        </subclass>
        <subclass name="Worker" discriminator-value="worker">
            <!--子類新增屬性-->
            <property name="no" column="wno" type="string" length="10"/>
            <property name="salary" type="double"/>
        </subclass>
    </class>
</hibernate-mapping>

hibernate配置文件:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useSSL=true</property>
    <property name="connection.username">root</property>
    <property name="connection.password">這里填你的密碼</property>
    <!--連接池設(shè)置-->
    <property name="connection.pool_size">2</property>
    <!--數(shù)據(jù)庫方言設(shè)置-->
    <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
    <!--向控制臺(tái)顯示執(zhí)行的SQL語句-->
    <property name="show_sql">false</property>
    <!--格式化SQL語句后輸出-->
    <property name="hibernate.format_sql">true</property>
    <!--事務(wù)配置-->
    <property name="current_session_context_class">thread</property>
    <!--創(chuàng)建SessionFactory對(duì)象時(shí)自動(dòng)創(chuàng)建數(shù)據(jù)庫表,可取create、create-drop奇昙、update等值-->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!--配置映射文件-->
    <mapping resource="Person.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

運(yùn)行結(jié)果:


image.png

數(shù)據(jù)庫中:


image.png

補(bǔ)充說明:需要先建立數(shù)據(jù)庫hibernate护侮,此項(xiàng)目為maven項(xiàng)目。也可以建立普通java項(xiàng)目或web項(xiàng)目储耐。

一個(gè)繼承層次一張表的優(yōu)缺點(diǎn)如下:

1羊初、最簡(jiǎn)單,執(zhí)行效率最高(無需關(guān)聯(lián))
2什湘、存在冗余字段长赞,需要加入?yún)^(qū)分各類的字段;不允許子類屬性為not null約束(允許為空)禽炬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涧卵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腹尖,更是在濱河造成了極大的恐慌柳恐,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件热幔,死亡現(xiàn)場(chǎng)離奇詭異乐设,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)绎巨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門近尚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人场勤,你說我怎么就攤上這事戈锻。” “怎么了和媳?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵格遭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我留瞳,道長(zhǎng)拒迅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮璧微,結(jié)果婚禮上作箍,老公的妹妹穿的比我還像新娘。我一直安慰自己前硫,他們只是感情好胞得,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著开瞭,像睡著了一般懒震。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗤详,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天个扰,我揣著相機(jī)與錄音,去河邊找鬼葱色。 笑死递宅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苍狰。 我是一名探鬼主播办龄,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼淋昭!你這毒婦竟也來了俐填?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤翔忽,失蹤者是張志新(化名)和其女友劉穎英融,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歇式,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驶悟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了材失。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痕鳍。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖龙巨,靈堂內(nèi)的尸體忽然破棺而出笼呆,到底是詐尸還是另有隱情,我是刑警寧澤旨别,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布抄邀,位于F島的核電站,受9級(jí)特大地震影響昼榛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一胆屿、第九天 我趴在偏房一處隱蔽的房頂上張望奥喻。 院中可真熱鬧,春花似錦非迹、人聲如沸环鲤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冷离。三九已至,卻和暖如春纯命,著一層夾襖步出監(jiān)牢的瞬間西剥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工亿汞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞭空,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓疗我,卻偏偏與公主長(zhǎng)得像咆畏,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吴裤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容