一、前言 發下牢騷,這段時間要做項目,又要學框架,搞得都沒時間寫筆記,但是覺得這知識學過還是要記錄下。進入主題了 1.1、Hibernate簡介 什麼是Hibernate?Hibernate有什麼用? Hibernate是開放源代碼的對象關係映射框架,用來把java的對象映射到資料庫中的關係數據中, ...
一、前言
發下牢騷,這段時間要做項目,又要學框架,搞得都沒時間寫筆記,但是覺得這知識學過還是要記錄下。進入主題了
1.1、Hibernate簡介
什麼是Hibernate?Hibernate有什麼用?
Hibernate是開放源代碼的對象關係映射框架,用來把java的對象映射到資料庫中的關係數據中,以便永久保存數據。
(簡單說來,我們都知道Java語言是面向對象的語言,資料庫是面向關係的,我們每次要往資料庫中添加數據的時候,是不是每次都需要寫SQL語句,進行CRUD,而優秀的開發人員
他們想出了一個非常好的映射框架,對象關係映射,也就是Hibernate,再透徹點說,就是你往對象添加數據的時候,資料庫中的表就自動添加了數據了。是不是很神奇!)
Hibernate的作用:
1、管理Java類的對象到資料庫的映射
2、提供數據查詢
3、提高效率,減少開發人員使用SQL和jdbc處理數據的時間
4、Hibernate能實現數據持久化和對象關係的映射
1.2、理解Hibernate
筆者在前面有說過,學一個東西,首先要理解它是什麼?有什麼用?為何存在?
我們要瞭解Hibernate,首先要先去瞭解三層結構,三層結構我們都聽過,但是,它和Hibernate有什麼關係呢?
這裡簡要說明下三層結構
三層結構分為: 表示層,業務邏輯層,資料庫層
表示層: 提供與用戶進行交互的界面
業務邏輯層: 負責各種業務邏輯,提供對業務數據的保存,更新,刪除和查詢操作等
資料庫層: 存放管理應用的持久化業務數據
而Hibernate,其實就是在業務邏輯層和資料庫層中間,添加一個持久化層,這個持久化層是業務邏輯中分離出來的;這樣,業務邏輯層通過持久化層,持久化層通過資料庫層。
這裡說了持久化,那麼什麼是持久化呢?
將數據(如記憶體中的對象)永久的保存到存儲設備中,就是持久化,持久化的作用是將記憶體中的數據存儲到關係型的資料庫中。
說到底其實數據存放分為兩種,一種是短期存放,就是存放在記憶體中,當你重新運行項目的時候,記憶體中的數據就消失,而另外一種就是永久存放。
理論就到這裡。
1.2、簡單例子——增刪改查
1.2.1、搭建環境
新建java property,這裡筆者的環境是Eclipse+Tomcat8.0,下載所需要的jar包,打包在這裡,註意還得添加mysql的jar包,將包導入到項目中,具體操作
右鍵項目名——Properties——Java Build Path——Libraries——Add Library——User Library——User Libraryies——New,接下來就添加jar,然後起個名字,之後將導入到你的項目就可以了。
效果圖:
1.2.2、新建配置文件
這裡需要註意一點就是:在Hibernate中,預設配置文件的命名為hibernate.cfg.xml,所以我們配置文件命名一般就是這個,如果說你想要重新命名的話,那麼在讀取配置文件的時候就要指定相對路徑。
在src下新建hibernate.cfg.xml
內容有連接資料庫,指定讀取實體類的配置信息,還有在控制台輸出SQL語句等數據;配置文件中的dtd文件,在hibernate-core-4.2.4.Final.jar中的org.hibernate中的最後就能看到hibernate-configuration-3.0.dtd,打開該文件,然後將下麵的dtd文件限制加到xml配置文件中即可。註意:筆者這裡使用的是hibernate 4.2的版本。但是一般都在核心包裡面的。
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
新建實體類:Student.java
package com.hibernate.hellos; public class Student { private int sid; private String sname; private int sage; public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public int getSage() { return sage; } public void setSage(int sage) { this.sage = sage; } }Student
重點來了:當我們新建實體類時,需要在該實體類的基礎上新建映射文件,dtd限制同樣在核心包中裡面查找
新建配置文件:Student.hbn.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> <!-- name:表示的是該類的相對路徑 table:表示的是資料庫的表名 --> <class name="com.hibernate.hellos.Student" table="Student"> <!-- type:表示該屬性是int類型 column:映射的是資料庫中的列名 native:根據底層資料庫的能力選擇identity, sequence 或者hilo中的一個,就是根據資料庫生成 --> <id name="sid" type="int"> <column name="ID" /> <generator class="native" /> </id> <property name="sname" type="java.lang.String"> <column name="SNAME" /> </property> <property name="sage" type="int"> <column name="SAGE" /> </property> </class> </hibernate-mapping>
註意:
其中generator的class有:
increment(遞增)
用於為long, short或者int類型生成唯一標識。只有在沒有其他進程往同一張表中插入數據時才能使用。
identity (標識)
對DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的內置標識欄位提供支持。返回的標識符是long, short 或者int類型的。
sequence (序列)
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的標識符是long, short或者 int類型的
uuid
用一個128位的UUID演算法生成字元串類型的標識符。在一個網路中唯一(使用了IP地址)。UUID被編碼為一個32位16進位數字的字元串。
native(本地)
根據底層資料庫的能力選擇identity, sequence 或者hilo中的一個。
新建配置文件:hiberate.cfg.xml,該文件放在src下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="show_sql">true</property> <!-- 顯示sql語句 --> <property name="format_sql">true</property> <!-- 格式化sql語句 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url"> <![CDATA[jdbc:mysql://localhost:3306/myhibernate?useUnicode=true&characterEncoding=utf8]]> </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 創建表 使用create,查詢或者更新的時候使用update--> <property name="hibernate.hbm2ddl.auto">create</property> <!-- hibernate的第一個測試例子 --> <mapping resource="com/hibernate/hellos/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
註意:使用hibernate.hbm2ddl.auto的時候,當為create的時候,表示如果你資料庫中沒創建表也沒關係,hibernate會自動幫你創建,當使用update的時候,表示在表的基礎上使用
接下來新建一個測試類:Test.java
package com.hibernate.hellos; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class Test { private static SessionFactory sessionfactory; private static Session session; public static void main(String[] args){ //讀取預設配置文件名 hibernate.cfg.xml //如果要指定文件名,只需要在new Configuration().configure("指定文件的路徑"); Configuration config = new Configuration().configure(); //註冊服務 ServiceRegistry service = new ServiceRegistryBuilder().applySettings(config.getProperties()) .buildServiceRegistry(); //實例化一個session工廠 SessionFactory sessionfactory = config.buildSessionFactory(service); //打開hibernate的session,執行操作 session = sessionfactory.openSession(); //添加 add(); //查詢 sel(); //修改 update(); //刪除 delete(); } //添加 public static void add(){ Transaction transaction = session.beginTransaction(); Student s = new Student(); s.setSname("張三"); s.setSage(20); session.save(s); transaction.commit(); //註意:如果session關閉的話,需要指定打開 } //查詢 public static void sel(){ Student s = (Student) session.get(Student.class, 1); System.out.println(s.getSname()); } //修改數據 public static void update(){ Student s = new Student(); s.setSname("李四"); s.setSage(30); Transaction transaction = session.beginTransaction(); //獲取資料庫中的表 Student s1 = (Student) session.get(Student.class,1); transaction.commit(); s1.setSname("李思思"); transaction = session.beginTransaction(); session.update(s1); transaction.commit(); } public static void delete(){ Transaction transaction = session.beginTransaction(); Student s = (Student) session.get(Student.class, 1); session.delete(s); transaction.commit(); } }
如果你直接複製我代碼的話,你就會看到資料庫中除了一張表數據什麼都沒有,把delete()方法註釋掉。恩,別犯傻。
當我們使用格式化的時候,就可以看到
添加和修改的效果圖:
資料庫中的表的數據:
總結:
1、新建實體類的時候,記得要寫映射文件,當然可以使用註解的方式,後期筆者會慢慢記錄
2、table表名不可以是mysql中的關鍵字
3、hibernate.hbm2ddl.auto的使用需要註意