Hibernate基础
**
一、什么是Hibernate?
**
Hibernate是一個輕量級的ORMapping框架
ORMapping原理(Object Relational Mapping)
ORMapping基本對應規則:
- 1:類跟表相對應
- 2:類的屬性跟表的字段相對應
- 3:類的實例與表中具體的一條記錄相對應
- 4:一個類可以對應多個表,一個表也可以對應對個類
- 5:DB中的表可以沒有主鍵,但是Object中必須設置主鍵字段
- 6:DB中表與表之間的關系(如:外鍵)映射成為Object之間的關系
- 7:Object中屬性的個數和名稱可以和表中定義的字段個數和名稱不一樣
ORMapping的基本實現方式:
使用JDBC,用SQL來操作數據庫,只是看動態生成還是人工寫代碼來實現。
大家想想,我們實現過ORMapping嗎?
**
二、Hibernate能干什么:
**
Hibernate主要用來實現Java對象和表之間的映射,除此之外還提供還提供數據查詢和獲取數據的方法,可以大幅度減少開發時人工使用SQL和JDBC處理數據的時間。
Hibernate的目標是對于開發者通常的數據持久化相關的編程任務,解放其中的95%。對于以數據為中心的程序來說,它們往往只在數據庫中使用存儲過程來實現商業邏輯,Hibernate可能不是最好的解決方案;對于那些在基于Java的中間層應用中,它們實現面向對象的業務模型和商業邏輯的應用,Hibernate是最有用的。
Hibernate可以幫助你消除或者包裝那些針對特定廠商的SQL代碼,并且幫你把結果集從表格式的表示形式轉換到一系列的對象去。
一個非常簡要的Hibernate體系結構的高層概要圖
Hibernate運行時體系結構
“最小”的體系結構方案,要求應用程序提供自己的 JDBC 連接并管理自己的事務。這種方案使用了Hibernate API 的最小子集.
“全面解決”的體系結構方案,將應用層從底層的JDBC/JTA API中抽象出來,而讓Hibernate來處理這些細節。
**
三、Hibernate中的對象
**
SessionFactory (org.hibernate.SessionFactory)
針對單個數據庫映射關系經過編譯后的內存鏡像,是線程安全的(不可變)。 它是生成的工廠,本身要用到。
Session (org.hibernate.Session)
表示應用程序與持久儲存層之間交互操作的一個單線程對象,此對象生存期很短,隱藏了連接,也是的工廠。
Transaction (org.hibernate.Transaction)
應用程序用來指定原子操作單元范圍的對象,它是單線程的,生命周期很短。它通過抽象將應用從底層具體的、以及事務隔離開。
ConnectionProvider (org.hibernate.connection.ConnectionProvider)
生成連接的工廠(有連接池的作用)。它通過抽象將應用從底層的或隔離開。僅供開發者擴展/實現用,并不暴露給應用程序使用。
TransactionFactory (org.hibernate.TransactionFactory)
生成對象實例的工廠。僅供開發者擴展/實現用,并不暴露給應用程序使用。
示例如下:
數據庫表:Student.sql
配置文件: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"> <hibernate-configuration><session-factory><!-- 數據庫URL --><property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property><!-- 數據庫用戶名 --><property name="connection.username">zhengcheng</property><!-- 數據庫密碼 --><property name="connection.password">123123</property><!-- JDBC驅動 --><property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property><!-- 每個數據庫都有對應的Dialect以匹配其平臺特性 --><property name="dialect">org.hibernate.dialect.Oracle10gDialect</property><!-- 指定當前session范圍和上下文 --><property name="current_session_context_class">thread</property><!-- 指定運行期生成的SQL輸出到日志以供調試 --><property name="show_sql">true</property><!-- 是否格式化sql --><property name="format_sql">true</property><!-- 映射文件 --><mapping resource="Student.hbm.xml" /> </session-factory> </hibernate-configuration>1:與被描述的類同名 ,如:Student.hbm.xml
2:存放位置與所描述類存放在同一文件夾下
3:主要有如下四部分配置 :
(1)類和表的映射
(2)主鍵的映射
(3)類的屬性和DB中字段的映射
(4)關系的映射
4:配置的時候可以到hibernate發行包里面找個例子,比如可以用“\project\hibernate-core\src\test\java\org\hibernate\test\cid”下面的Customer.hbm.xml作例子
映射文件:Student.hbm.xml
客戶端文件:
java代碼:StudentService.java
package hibDemo1.dao;import hibDemo1.entity.Student;import java.util.List;import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration;public class StudentService {private static Configuration conf;private static SessionFactory sf;private static Transaction tx;static {try {conf = new Configuration().configure();sf = conf.buildSessionFactory();} catch (HibernateException e) {e.printStackTrace();}}public static Session getSession() {return sf.openSession(); //過去老的方法,不需要使用事務//return sf.getCurrentSession(); // 新的方法,需要和事務一起使用,可以保證每個用戶創建的session獨立,需要在配置文件中配置//<property name="current_session_context_class">thread</property>}/*** 獲取所有學生列表* * @return*/public List<Student> GetAllStudent() {List<Student> list = null;Session session = getSession();if (session != null) {try {String hql = "from Student";Query query = session.createQuery(hql);list = query.list();} catch (HibernateException e) {e.printStackTrace();} finally {session.close();}}return list;}/*** 獲取單個學生信息* * @param stuNo* @return*/public Student GetStudentBystuNo(String stuNo) {Student stu = null;Session session = getSession();if (session != null) {try {// get如果沒有查詢到數據,則返回null// stu = (Student) session.get(Student.class, stuNo);// load如果沒有查詢到數據,則拋出異常stu = (Student) session.load(Student.class, stuNo);} catch (HibernateException e) {e.printStackTrace();} finally {session.close();}}return stu;}/*** 添加一個學生* * @param stu* @author Administrator*/public boolean AddStudent(Student stu) {boolean b = false;Session session = getSession();if (session != null) {try {// 開啟一個事務tx = session.beginTransaction();// 保存session.save(stu);// 提交事務tx.commit();return true;} catch (HibernateException e) {e.printStackTrace();tx.rollback();} finally {session.close();}}return b;}/*** 更新一個學生* * @param stu* @author Administrator*/public boolean UpdateStudent(String stuNo, String newName) {boolean b = false;Session session = getSession();if (session != null) {try {// 開啟一個事務tx = session.beginTransaction();// 獲取一個學生對象Student stu = (Student) session.load(Student.class, stuNo);// 更新某個屬性stu.setStuName(newName);// 提交事務tx.commit();return true;} catch (HibernateException e) {e.printStackTrace();tx.rollback();} finally {session.close();}}return b;}/*** 更新一個學生* * @param stu* @author Administrator*/public boolean DeleteStudent(String stuNo) {boolean b = false;Session session = getSession();if (session != null) {try {// 開啟一個事務tx = session.beginTransaction();// 獲取一個學生對象Student stu = (Student) session.load(Student.class, stuNo);// 刪除操作session.delete(stu);// 提交事務tx.commit();return true;} catch (HibernateException e) {e.printStackTrace();tx.rollback();} finally {session.close();}}return b;} }test.java
package hibDemo.test;import hibDemo1.dao.StudentService; import hibDemo1.entity.Student;import java.util.List; import java.util.Scanner;public class test {public static void main(String[] args) {// 添加學生信息// AddStudent();// 顯示所有學生信息ShowAll();// 顯示單個學生信息// ShowOne();//更新學生信息//Update();//刪除學生信息//Delete();ShowAll();}public static void ShowAll() {StudentService service = new StudentService();List<Student> list = service.GetAllStudent();for (Student student : list) {System.out.println(student.getStuNo() + " " + student.getStuName());}}public static void ShowOne() {String no = "A004";StudentService service = new StudentService();Student student = service.GetStudentBystuNo(no);if (student != null) {System.out.println(student.getStuNo() + " " + student.getStuName());} else {System.out.println("no data");}}public static void AddStudent() {Scanner input = new Scanner(System.in);Student stu = new Student();System.out.print("請輸入學生編號:(A001)");stu.setStuNo(input.next());System.out.print("請輸入學生姓名:(A001)");stu.setStuName(input.next());stu.setStuPass("888888");System.out.print("請輸入學生年齡:(0-100)");stu.setStuAge(input.nextInt());System.out.print("請輸入學生手機號:(A001)");stu.setMobile(input.next());System.out.print("請輸入學生郵箱:(A001)");stu.setEmail(input.next());System.out.print("請輸入學生地址:(A001)");stu.setAddress(input.next());StudentService service = new StudentService();service.AddStudent(stu);}public static void Update() {Scanner input = new Scanner(System.in);System.out.print("輸入要修改的學號:");String stuNo = input.next();System.out.print("輸入要修改的姓名:");String newName = input.next();StudentService service = new StudentService();service.UpdateStudent(stuNo, newName);}public static void Delete() {Scanner input = new Scanner(System.in);System.out.print("輸入要修改的學號:");String stuNo = input.next();StudentService service = new StudentService();service.DeleteStudent(stuNo);} }說明:
1:SessionFactory sf = new Configuration().configure().buildSessionFactory();這句話的意思是讀取hibernate.cfg.xml,創建Session工廠,是線程安全的。
默認是”hibernate.cfg.xml”,不用寫出來,如果文件名不是”hibernate.cfg.xml”,那么需要顯示指定,如下:
SessionFactory sf = new Configuration(). configure( “javass.cfg.xml” ).buildSessionFactory();
2:Session是應用程序主要使用的Hibernate接口,約相當于JDBC的Connection+Statement/PreparedStatement的功能,是線程不安全的
3:在Hibernate4里面,已經不推薦使用Configuration類了,而改為使用 ServiceRegistryBuilder和MetadataSources來代替,新的寫法大致如下:
ServiceRegistryBuilder builder = new ServiceRegistryBuilder().configure();
builder.applySetting(“connection.driver_class”, “oracle.jdbc.driver.OracleDriver”);
builder.applySetting(“connection.url”, “jdbc:oracle:thin:@localhost:1521:orcl”);
builder.applySetting(“connection.username”, “ztb”);
builder.applySetting(“connection.password”, “ztb”);
builder.applySetting(“connection.pool_size”, “2”);
builder.applySetting(“hibernate.dialect”, “org.hibernate.dialect.OracleDialect”);
builder.applySetting(“show_sql”, “true”);
MetadataSources sources = new MetadataSources( builder.buildServiceRegistry() );
sources.addResource(“cn/javass/h4/hello/UserModel.hbm.xml”);
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
SessionFactory sf = metadata.getSessionFactoryBuilder().buildSessionFactory();
這種寫法,現在還沒有實現完全,不太好用,所以官方給出的示例里面還是采用以前的方式,大家先了解一下。
4:這里使用的事務Transaction是Hibernate的Transaction,需要有,不能去掉。
為什么必須有這個Hibernate的事務呢?以HelloWorld為例來看看:
總結
以上是生活随笔為你收集整理的Hibernate基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 倍思 MagPro 磁吸无线充 15W
- 下一篇: Hibernate懒加载问题的5种解决方