如果持久化類具有List物件,我們可以通過對映檔案中的類的<list>
元素或注釋來對映List
。
在這裡,我們正在使用論壇的場景,其中一個問題有多個答案。
在這裡,我們使用論壇的場景,其中一個問題有多個答案。
我們來看看如何在對映檔案中實現列表(List):
<class name="com.yiibai.Question" table="q100">
...
<list name="answers" table="ans100">
<key column="qid"></key>
<index column="type"></index>
<element column="answer" type="string"></element>
</list>
...
</class>
註:
List
和Map
是基於索引的集合,因此將在表中建立一個額外的列進行索引。
在這個例子中,我們將看到列表(List)在集合對映的完整範例。 這是List中儲存字串值而不是實體參照的範例,這就是為什麼要在列表元素中使用element
標籤而不是one-to-many
標籤的元素。
這個範例專案的完整結構如下圖所示 -
這個持久化類定義了類的屬性,包括List
。
package com.yiibai;
import java.util.List;
public class Question {
private int id;
private String qname;
private List<String> 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 List<String> getAnswers() {
return answers;
}
public void setAnswers(List<String> answers) {
this.answers = answers;
}
}
在這裡,我們建立了用於定義列表的question.hbm.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="question_100">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="qname"></property>
<list name="answers" table="answer_100">
<key column="qid"></key>
<index column="type"></index>
<element column="answer" type="string"></element>
</list>
</class>
</hibernate-mapping>
此檔案包含有關資料庫和對映檔案的資訊。
檔案:hibernate.hnm.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"/>
</session-factory>
</hibernate-configuration>
在這個類(MainTest.java
)中,用來儲存Question
類的資料。使用HQL來獲取Answer
類的所有記錄,包括答案。 在這個範例中,它從功能相關的兩個表中獲取資料。
package com.yiibai;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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();
ArrayList<String> list1 = new ArrayList<String>();
list1.add("java is a programming language");
list1.add("java is a platform");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("Servlet is an Interface");
list2.add("Servlet is an API");
Question question1 = new Question();
question1.setQname("Java 是什麼?");
question1.setAnswers(list1);
Question question2 = new Question();
question2.setQname("Hibernate 是什麼?");
question2.setAnswers(list2);
session.persist(question1);
session.persist(question2);
t.commit();
// 查詢資料
Query<Question> 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
List<String> list21 = q.getAnswers();
Iterator<String> itr2 = list21.iterator();
while (itr2.hasNext()) {
System.out.println(itr2.next());
}
}
session.close();
System.out.println("success");
}
}
執行上面程式碼,得到以下輸出結果 -
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 05:18:56 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 max(id) from question_100
Hibernate: insert into question_100 (qname, id) values (?, ?)
Hibernate: insert into question_100 (qname, id) values (?, ?)
Hibernate: insert into answer_100 (qid, type, answer) values (?, ?, ?)
Hibernate: insert into answer_100 (qid, type, answer) values (?, ?, ?)
Hibernate: insert into answer_100 (qid, type, answer) values (?, ?, ?)
Hibernate: insert into answer_100 (qid, type, answer) values (?, ?, ?)
Hibernate: select question0_.id as id1_1_, question0_.qname as qname2_1_ from question_100 question0_
Question Name: What is Java?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
java is a programming language
java is a platform
Question Name: What is Servlet?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
Servlet is an Interface
Servlet is an API
Question Name: What is Java?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
java is a programming language
java is a platform
Question Name: What is Servlet?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
Servlet is an Interface
Servlet is an API
Question Name: What is Java?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
java is a programming language
java is a platform
Question Name: What is Servlet?
Hibernate: select answers0_.qid as qid1_0_0_, answers0_.answer as answer3_0_0_, answers0_.type as type2_0_ from answer_100 answers0_ where answers0_.qid=?
Servlet is an Interface
Servlet is an API
Question Name: Java 是什麼?
java is a programming language
java is a platform
Question Name: Hibernate 是什麼?
Servlet is an Interface
Servlet is an API
success