集合Set映射一對多(使用xml文件)

如果持久化類設置了包含實體引用的對象,則需要使用一對多關聯來映射集合(Set)元素。 我們可以通過任意一個Set集合來映射這個列表對象。

下面來看看看設置對象的持久化類。 在這種情況下,一個問題可以有很多答案,每個答案可能有自己的信息,這就是爲什麼使用set標籤元素來表示一個答案(Answer類)集合。

Set映射一對多關係示例

在這個示例中,使用Set實現一對多和多對一關係映射。以論壇中的問題和答案爲例,從一個問題可獲取這個問題的所有回答(一對多),從一個問題反關聯(多對一)得到問題信息。

創建一個名稱爲: setonetomany 的Java項目,其結構如下所示 -

集合Set映射一對多(使用xml文件)

Java代碼

首先,將運行程序創建表並將對應數據插入到表中,然後再從表中讀取數據。

Question.java 代碼如下所示 -

package com.yiibai;

import java.util.Set;

public class Question {
    private int id;
    private String qname;
    private Set<Answer> answers;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getQname() {
        return qname;
    }

    public void setQname(String qname) {
        this.qname = qname;
    }

    public Set<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(Set<Answer> answers) {
        this.answers = answers;
    }

}

Answer.java 代碼如下所示 -

package com.yiibai;

public class Answer {
    private int id;  
    private String answername;  
    private String postedBy;  
    private int qid;
    private Question question;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getAnswername() {
        return answername;
    }
    public void setAnswername(String answername) {
        this.answername = answername;
    }
    public String getPostedBy() {
        return postedBy;
    }
    public void setPostedBy(String postedBy) {
        this.postedBy = postedBy;
    }
    public int getQid() {
        return qid;
    }
    public void setQid(int qid) {
        this.qid = qid;
    }
    public Question getQuestion() {
        return question;
    }
    public void setQuestion(Question question) {
        this.question = question;
    }

    public String toString(){
        return this.answername+", postby : "+this.postedBy;
    }

}

配置文件

一共有三個配置文件,它們分別如下:

answer.hnm.xml 文件內容如下-

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.yiibai.Answer" table="a1002">
        <id name="id">
            <generator class="increment"></generator>
        </id>
        <property name="answername"></property>
        <property name="postedBy"></property>
        <many-to-one name="question" class="com.yiibai.Question" fetch="select">
            <column name="qid" not-null="true" />
        </many-to-one>
    </class>

</hibernate-mapping>

question.hnm.xml 文件內容如下-

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.yiibai.Question" table="q1002">
        <id name="id">
            <generator class="increment"></generator>
        </id>
        <property name="qname"></property>

        <set name="answers" table="a1002"
                inverse="true" lazy="true" fetch="select">
            <key>
                <column name="qid" not-null="true" />
            </key>
            <one-to-many class="com.yiibai.Answer" />
        </set>

    </class>

</hibernate-mapping>

hibernate.cfg.xml 文件內容如下-

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

    <session-factory>
        <property name="hbm2ddl.auto">update</property>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">true</property>

        <mapping resource="question.hbm.xml" />
        <mapping resource="answer.hbm.xml" />
    </session-factory>

</hibernate-configuration>

運行示例

MainTest.java文件的代碼如下 -

package com.yiibai;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.*;

public class MainTest {
    public static void main(String[] args) {
        // 但在5.1.0版本彙總,hibernate則採用如下新方式獲取:
        // 1. 配置類型安全的準服務註冊類,這是當前應用的單例對象,不作修改,所以聲明爲final
        // 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定資源路徑,默認在類路徑下尋找名爲hibernate.cfg.xml的文件
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();
        // 2. 根據服務註冊類創建一個元數據資源集,同時構建元數據並生成應用一般唯一的的session工廠
        SessionFactory sessionFactory = new MetadataSources(registry)
                .buildMetadata().buildSessionFactory();

        /**** 上面是配置準備,下面開始我們的數據庫操作 ******/
        Session session = sessionFactory.openSession();// 從會話工廠獲取一個session

        // creating transaction object
        Transaction t = session.beginTransaction();

        Question question1 = new Question();
        question1.setQname("What is Java?");
        session.save(question1);

        Answer ans1 = new Answer();
        ans1.setAnswername("java is a programming language");
        ans1.setPostedBy("Ravi Su");
        ans1.setQuestion(question1);
        //question1.getAnswers().add(ans1);

        session.save(ans1);

        Answer ans2 = new Answer();
        ans2.setAnswername("java is a platform");
        ans2.setPostedBy("Sudhir Lee");
        ans2.setQuestion(question1);
        session.save(ans2);

        t.commit();
        session.close();

        System.out.println("success");
    }
}

FetchData.java文件的代碼如下 -

package com.yiibai;

import java.util.*;

import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.*;

public class FetchData {
    public static void main(String[] args) {

        // 但在5.1.0版本彙總,hibernate則採用如下新方式獲取:
        // 1. 配置類型安全的準服務註冊類,這是當前應用的單例對象,不作修改,所以聲明爲final
        // 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定資源路徑,默認在類路徑下尋找名爲hibernate.cfg.xml的文件
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();
        // 2. 根據服務註冊類創建一個元數據資源集,同時構建元數據並生成應用一般唯一的的session工廠
        SessionFactory sessionFactory = new MetadataSources(registry)
                .buildMetadata().buildSessionFactory();

        /**** 上面是配置準備,下面開始我們的數據庫操作 ******/
        Session session = sessionFactory.openSession();// 從會話工廠獲取一個session

        // creating transaction object
        Transaction t = session.beginTransaction();

        Query query = session.createQuery("from Question");
        List<Question> list = query.list();

        Iterator<Question> itr = list.iterator();
        while (itr.hasNext()) {
            Question q = itr.next();
            System.out.println("Question Name: " + q.getQname());

            // printing answers
            Set<Answer> set = q.getAnswers();
            Iterator<Answer> itr2 = set.iterator();
            while (itr2.hasNext()) {
                Answer an = (Answer)itr2.next();
                System.out.println(an.getAnswername());
            }

        }
        session.close();
        System.out.println("success");

    }
}

執行 MainTest.java得到以下結果 -

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Sun Mar 26 23:33:27 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Hibernate: create table a1002 (id integer not null, answername varchar(255), postedBy varchar(255), qid integer not null, primary key (id)) engine=InnoDB
Hibernate: create table q1002 (id integer not null, qname varchar(255), primary key (id)) engine=InnoDB
Hibernate: alter table a1002 add constraint FK9la7qmitcg24x22e3dh3q9kjv foreign key (qid) references q1002 (id)
Hibernate: alter table q1002 add constraint FK1ap2g6pq36pyrpjaw5o31yxdf foreign key (id) references q1002 (id)
Hibernate: select max(id) from q1002
Hibernate: select max(id) from a1002
Hibernate: insert into q1002 (qname, id) values (?, ?)
Hibernate: insert into a1002 (answername, postedBy, qid, id) values (?, ?, ?, ?)
Hibernate: insert into a1002 (answername, postedBy, qid, id) values (?, ?, ?, ?)
success

執行 FetchData.java得到以下結果 -

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Sun Mar 26 23:42:52 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Hibernate: select question0_.id as id1_1_, question0_.qname as qname2_1_ from q1002 question0_
Question Name: What is Java?
Hibernate: select answers0_.qid as qid4_0_0_, answers0_.id as id1_0_0_, answers0_.id as id1_0_1_, answers0_.answername as answerna2_0_1_, answers0_.postedBy as postedBy3_0_1_, answers0_.qid as qid4_0_1_ from a1002 answers0_ where answers0_.qid=?
java is a platform
java is a programming language
success