初識Hibernate
ORM原理簡介:
ORM(Object Relationnal Mapping)是對象到關系的映射,它的作用是在關系數據庫和對象這件做一個自動的映射,將數據庫中的表映射成為對象,也就是持久化類,對關系型數據庫以對象的形式進行操作,減少開發中數據重復的編程任務。
Hibernate配置文件
Hibernate通過讀取默認的XML文件himbernate.cfg.xml加載數據庫的配置信息,該配置文件被默認放在classpath根目錄下。(文件名可以自定義,不過后面寫工具類時就要寫自定義的文件名,如果按照默認的就不需要寫文件名了,后面還會在詳細說明)
<?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安裝文件夾中的pfoject文件夾中招cfg.xml結尾的案例 --> <!-- 以/jndi/name綁定到JNDI的SessionFactory實例 --> <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.HSQLDialect</property><!-- 數據庫方言 -->(這里是mysql) <property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- jdbc數據庫驅動 --> <property name="connection.url">jdbc:mysql://localhost:3306/mydb?characterEncoding=GBK</property><!-- 鏈接數據庫 --> <property name="connection.username">root</property><!-- 用戶名 --> <property name="connection.password"></property><!-- 密碼 --> <property name="show_sql">true</property> <!-- 在控制台輸出生成的每一條sql語句,開發者一般為了調試寫為true,后期項目結束改為false --> <!-- 映射定義文件,(文件的路徑) --> <mapping resource="com/itnba/maya/hibernate/Fruit.hbm.xml"/> </session-factory> </hibernate-configuration>
Hibernate映射
1.首先了解一下持久化類(也就是基本的Bean類)
在持久化類中每一個屬性都有相應的set()和get()方法。它不依賴與任何接口和繼承任何類。
Hibernate中持久化類的4條編程原則:
a.實現一個默認的構造函數(所有的持久化類都必須含有一個默認的無參數構造方法),以便Hibernate通過Constructor.newInstance()實例化持久化類。
b.提供一個標識屬性(也就是對應數據庫中主鍵的字段名)
c.使用非final類
d.為屬性聲明訪問器:持久化類的屬性不能聲明為public,最好是private
2.對象關系映射:對象和關系型數據庫之間的映射通常使用XML文檔來實現的。映射文件的命名規則為*.hbm.xml 例如(User.hbm.xml)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- 上面復制粘貼 --> <hibernate-mapping default-lazy="false" package="com.itnba.maya.hibernate"> <!-- package選填,與下面對應好即可 --> <class name="Fruit" table="Fruit"> <!-- 如果上面寫了包名這里的name直接寫類名即可 --> <!-- name是類屬性名,表中的字段名 column="ID" 類型type="long"--> <!-- 庫表中的字段名和類型最好和類中的屬性名一一對應,那么這樣就只寫name就可以了 --> <id name="ids"> <generator class="assigned"/> <!-- 表示主鍵 --> </id> <property name="name"/> <!-- 以下是其他字段 --> <property name="source" /> <property name="price" /> <property name="numbers" /> <property name="image" /> </class> </hibernate-mapping>
Hibernate的3種實例狀態
1.瞬時狀態
實體對象new出來時,但是還沒有納入Hibernate Session的管理中,如果沒有變量對其引用,他將被JVM回收,瞬時狀態的對象在內存中是孤立存在的,它與數據庫中的數據無任何關聯,僅僅是一個信息的載體。
2.對象處於Session的緩存中和其關聯的狀態,處於該狀態的對象也稱為持久化對象。持久化對象特點:和Session關聯(受其管理)數據庫中有對應的記錄
3.(detached)(脫管狀態)數據庫中有對應的記錄但是沒有處於Session緩存中(和Session沒有關聯)的狀態。處於該狀態的對象也稱為游離對象。
脫管對象特點: 數據庫中有對應記錄、沒有和Session關聯(不受其管理)
Hibernate初始化類
Session對象是Hibernate中數據庫持久化操作的核心,他負責Hibernate所有的持久化操作。那么如何獲取Session對象呢?
Session對象是通過SessionFactory對象獲取的,而SessionFactory又是通過Configuration對象來創建的。(代碼如下)
創建HibernateUtil類,實現對Hibernate的初始化
package com.itnba.maya.hibernate; import org.hibernate.*; import org.hibernate.cfg.*; public class HibernateUtil { private static final ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();//為保證線程安全,將Seeeion放到ThreadLocal中管理。這樣就避免了Session的多線程共享數據的問題 private static final SessionFactory sessionFactory=BuilderFactory();//構建SessionFanctory對象 private static SessionFactory BuilderFactory() { Configuration cfg=new Configuration().configure();//加載Hibernate配置文件 return cfg.buildSessionFactory(); } //獲取session public Session getSession(){ Session session=threadLocal.get();//從線程中獲取session, if(session==null){//如果session為空 session=sessionFactory.openSession();//那么就用SessionFactory來創建一個session threadLocal.set(session);//並且為了線程安全,將它放進線程鎖中 } return session;//返回session } //關閉session public void closeSession(){ Session session=threadLocal.get();//首先也要從線程中獲取session,看是否存在這一次會話中的session if(session != null){//如果存在 session.close();//先將session關閉掉 threadLocal.set(null);//再將線程中的session移除設為空 } } }
基本添加修改刪除查詢操作
package com.itnba.maya.hibernatetest; import java.util.List; import org.hibernate.*; import org.hibernate.cfg.*; public class TestNigeht { public static void main(String[] args){ Session session=null; //添加 /*try{ session=HibernateUtil.getSession(); Fruit f=new Fruit(); f.setIds("z002"); f.setName("西紅柿"); session.beginTransaction(); session.save(f); session.getTransaction().commit(); }catch(Exception ex){ System.out.println("數據添加失敗"); ex.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtil.closeSession(); }*/ //查詢 /*try{ session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z001"); List<Fruit> list=session.createQuery("from Fruit").getResultList(); System.out.println(f.getIds()+f.getName()); for(Fruit fr:list){ System.out.println(fr.getName()); } }catch(Exception ex){ ex.printStackTrace(); System.out.println("數據查詢失敗"); }finally{ HibernateUtil.closeSession(); }*/ //修改 /*session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z001"); if(f != null){ try{ session.beginTransaction(); f.setName("冬瓜"); session.update(f); session.getTransaction().commit();; }catch(Exception ex){ session.getTransaction().rollback(); System.out.println("數據修改失敗"); ex.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }*/ //刪除 session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z002"); if(f != null){ try{ session.beginTransaction(); session.delete(f); session.getTransaction().commit(); }catch(Exception ex){ session.getTransaction().rollback(); System.out.println("數據刪除失敗"); ex.printStackTrace(); }finally{ HibernateUtil.closeSession(); } } } }