本文著重講述了為什么要使用Hibernate,此外也簡單的介紹了如何使用Hibernate,以及Hibernate中的一些基本概念。借這篇文章來向還沒有接觸過Hibernate的開發者推薦款優秀的開源ORM產品。
一、WhyHibernate?
現在流行“測試驅動開發”,相似的我覺得“目的驅動學習”是一種比較好的接受新技術,新知識的途徑。在學習一樣新的技術之前,首先得明確到底有沒有必要學習,已有的技術是否已經工作的很好,學習這個新的技術是為了解決什么問題。如果您明確了以上問題,那么尋找并學習新的技術將會事半功倍,并且能快速應用到實際的開發當中來提高效益。
要說Hibernate,就得先介紹一下Object/RelationMapper(ORM),中文翻譯為對象關系映射。之所以會產生這樣的概念是源于目前軟件開發中的一些不協調的思想。目前流行的編程模型是OOP(ObjectOrientedProgramming),面向對象的編程,而目前流行的數據庫模型是RelationalDatabase,這兩者思考的方式不一樣,這必然產生了開發過程中的不協調。ORM框架(也稱為持久層框架,)的出現就是為了解決這樣的問題,屏蔽底層數據庫的操作,以面向對象的方式提供給開發者操作數據庫中數據的接口。目前流行的ORM框架有 ApachOJB,Hibernate,iBatis等等,當然最完善,最好用的是Hibernate,至少我這樣認為。或許您對“持久層”感到迷惑,其實說白了很簡單,把數據放到數據庫中叫做持久化(內存種的數據當然不是持久的),那么負責這一操作的結構層面就叫做持久層。您以前應該聽說過表現層,業務層,數據層,那么持久層是在業務層和數據層之間的一層,或者說持久層是數據層的一部分。
接下來,我想通過一個實際開發中的例子來說明ORM帶給我們的好處。先來講一下我們的需求,數據庫中有三張表,一張student,一張course,另外一張course_slection。其中student用來保存學生信息,course用來表示課程信息,course_selection用來表示學生的選課信息。(表的詳細結構這里我就省略了,因為這并不重要)現在要求編寫一個程序,用來選出指定學號學生所選的課程名字,那么可能會出現以下幾種程序編寫的方式:
1.菜鳥級
代碼片段1:
publicListselectCourses(StringstudentId)
{
Connectioncon=null;
Statementsta=null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection(
"jdbc:oracle:thin:@10.85.33.199:1521:glee",
"test","test");
Stringsql="select*fromcourse_selection";
Stringsql2="selectnamefromcoursewhereid=";
sta=con.createStatement();
ResultSetrs=sta.executeQuery(sql);
Listlist=newLinkedList();
while(rs.next())
{
ResultSetrs2=sta.executeQuery(sql2+
rs.getString("course_id")+"");
if(rs2.next())
{
list.add(rs2.getString("name"));
}
}
returnlist;
}
catch(Exceptione)
{
e.printStackTrace();
}
returnnull;
}
這段程序您一定看的很暈吧,什么亂七八糟的都搞在一起,那么接下來看一段改進過的程序。
2.改進后的代碼
代碼片段2:
classDBHelper
{
publicstaticConnectiongetConnection()
{
try
{
Class.forName(Constants.DB_DRIVER);
returnDriverManager.getConnection(Constants.DB_URL,
Constants.DB_USER,Constants.DB_PWD);
}
catch(Exceptione)
{
e.printStackTrace();
}
returnnull;
}
}
publicListselectCourses(StringstudentId)
{
Connectioncon=null;
Statementsta=null;
try
{
con=DBHelper.getConnection();
Stringsql="select*fromcourse_selection";
Stringsql2="selectnamefromcoursewhereid=";
sta=con.createStatement();
ResultSetrs=sta.executeQuery(sql);
Listlist=newLinkedList();
while(rs.next())
{
ResultSetrs2=sta.executeQuery(sql2+rs.getString("course_id")+"");
if(rs2.next())
{
list.add(rs2.getString("name"));
}
}
returnlist;
}
catch(Exceptione)
{
e.printStackTrace();
}
returnnull;
}
這段代碼的形式是一種被廣泛采用的形式,相對第一段代碼來說,應該已經有所進步,分離了數據庫連接操作,并把數據庫連接信息交給單獨的類完成(一般放在配置文件里面),往往在開發中還會引入數據庫連接池(ConnectionPool)來提高性能,我這里都盡量簡化了。但這些并不能從根本上改善程序的結構,在業務代碼中仍然混雜了很多數據庫操作,結構不清晰。下面來看一段徹底分離數據庫操作的代碼:
3.DAO模式
代碼片段3:
publicListselectCourses(StringstudentId)
{
StudentDAOsd=newStudentDAO();
Studentstudent=sd.findById(studentId);
Setset=student.getCourseSelections();
ListcourseNames=newLinkedList();
for(Iteratoriter=set.iterator();iter.hasNext();)
{
CourseSelectionelement=(CourseSelection)iter.next();
courseNames.add(element.getCourse()。getName());
}
returncourseNames;
}
是不是感覺代碼少了很多?或許您對這段代碼有點迷惑,沒關系,后文會詳細解釋。我想先解釋一下DAO。其實DAO和Hibernate沒有必然聯系,只不過一般用Hibernate的程序都用DAO模式。DAO的全稱是DataAccessObject,程序要訪問數據庫中的數據(包括獲取,更新,刪除)都通過DAO來訪問,實際上DAO才是真正屏蔽了所有數據庫操作的東西,這樣在業務代碼中就可以完全隔離數據層的代碼。如果我告訴您,在真正用 Hibernate開發的時候,要完成上文提到的功能,需要手寫的代碼就是“代碼片段3”這么多,甚至更少,您是不是有很大的動力去學習 Hibernate?那么好吧,讓我們開始Hibernate之旅。
新聞熱點
疑難解答