SSH框架之Hibernate第一篇
- 2019 年 10 月 5 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/zhao1299002788/article/details/100622886
1.2Hibernate的概述: 1.2.1 什麼Hibernate? Hibernate(開發源程式碼的對象關係映射框架)是一個開放源程式碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與資料庫表建立映射關係, 是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執行,使得Java程式設計師可以隨心所欲的使用對象編程思維來操作資料庫.Hibernate可以應用在任何使用JDBC的場合, 既可以在Java的客戶端程式使用,也可以在Servlet/JSP的Web應用中使用,最具有革命意義的是,Hibernate可以在應用EJB的J2EE框架中取代CMP,完成數據持久化的重任. Hibernate就是一個持久層的ORM的框架.對JDBC做了封裝. 對JDBC做了封裝: 類似咋們之前的dbutis,都對最底層的jdbc操作做了封裝. ORM框架 : ORM框架有很多,hibernate框架只是其中的一個 1.2.2 什麼是ORM ORM : Object Relational Mapping對象關係映射. 將對象與資料庫中表建立映射關係,操作對象就可以操作資料庫中表.就是將java類和資料庫的表創建一種關係. 好處: 創建這種關係的好處? 以後操作這個java類,就相當於操作資料庫的對應的這張表了. 在dao層操作資料庫數據 : JDBC+C3P0 dbutils hibernate框架的作用? 1 : 簡化了Dao層的編碼工作. 大大簡化了數據訪問層繁瑣的重複性程式碼,加快了運行效率. 2 : 程式更加面向對象 可以不需要編寫SQL語句,只需要操作相應的對象就可以完成資料庫數據的crud操作. ps : sql語句不需要自己寫了,都是Hibernate底層寫好了. Hibernate對JDBC訪問資料庫的程式碼做了輕量級封裝,大大簡化了數據訪問層繁瑣的重複性程式碼,並且減少了記憶體消耗,加快了運行效率. Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現,它很大程度的簡化了DAO(Data Access Object, 數據訪問對象)層編碼工作. Hibernate的性能非常好,映射的靈活性很出色.它支援很多關係型資料庫,從一對一到多對多的各種複雜關係. 可以擴展性強,由於源程式碼的開源以及API的開放,當本身功能不夠用的時,可以自行編碼進行擴展. 1.3Hibernate入門 下載Hibernate的開發包. 解壓Hibernate 在減壓的文件夾目錄有: documentation : Hibernate的開發規範和文檔. lib : Hibernate的開發使用的jar包. project : Hibernate的提供測試的工程. 1.3.3 創建項目,引入jar包 引入lib/required/*.jar 資料庫驅動包 日誌包 1.3.4創建資料庫和表 CREATE TABLE `cst_customer` ( `cust_id` int AUTO_INCREMENT COMMENT '客戶編號(主鍵)', `cust_name` varchar(32) NOT NULL COMMENT '客戶名稱(公司名稱)', `cust_source` varchar(32) DEFAULT NULL COMMENT '客戶資訊來源', `cust_industry` varchar(32) DEFAULT NULL COMMENT '客戶所屬行業', `cust_level` varchar(32) DEFAULT NULL COMMENT '客戶級別', `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定電話', `cust_mobile` varchar(16) DEFAULT NULL COMMENT '行動電話', PRIMARY KEY (`cust_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 1.3.5 創建實體類 1.3.5 創建Hibernate 的映射文件 Hibernate的映射文件只要是一個XML文件就可以了.一般映射命名 : 類名.hbm.xml 1.3.6 "創建實體類 <?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> <!-- 建立映射關係:將類與表建立映射關係 --> <!-- class標籤:用於建立類與表的映射 * name :類的全路徑 * table :資料庫表名稱 --> <class name="com.baidu.hibernate.domain.Customer" table="cst_customer"> <!-- 建立類中的屬性與表中的欄位的映射 --> <!-- id標籤:用來建立表中的主鍵欄位與類中的屬性的映射 --> <id name="cust_id" column="cust_id"> <!-- 主鍵生成策略: --> <generator class="native"/> </id> <!-- 其他的屬性都是用property建立映射 --> <property name="cust_name" column="cust_name"/> <property name="cust_source" column="cust_source"/> <property name="cust_industry" column="cust_industry"/> <property name="cust_level" column="cust_level"/> <property name="cust_phone" column="cust_phone"/> <property name="cust_mobile" column="cust_mobile"/> </class> </hibernate-mapping> 1.3.7 創建Hibernate核心配置文件 : 默認SRC下有個hibernate.cfg.xml文件 <?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernates</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">abcd</property> <!-- 配置Hibernate的相關屬性 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可選屬性 --> <!-- 顯示SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- hbm2ddl --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 載入映射文件: --> <mapping resource="com/baidu/hibernate/domain/Customer.hbm.xml"/> </session-factory> </hibernate-configuration> 1.3.8編寫程式碼 public void t1() { // 載入資料庫核心配置文件 Configuration con = new Configuration(); con.configure(); //自動去載入默認地址的默認配置文件名 // 獲取session-factory 連接池 SessionFactory factory = con.buildSessionFactory(); // 獲取session 連接對象 Session session = factory.openSession(); // 開啟事務 Transaction tx = session.beginTransaction(); // 操作(面對對象) Customer ct = new Customer(); ct.setCust_name("jack"); // 保存 session.save(ct); // sql語句雖然生成了,但是需要自己手動提交 // 手動提交 tx.commit(); // 釋放資源 session.close(); factory.close(); } @Test public void t2() { Configuration con = new Configuration(); con.configure(); // 手動載入映射文件 con.addResource("cn/baidu/domain/Customer.hbm.xml"); // 了解 SessionFactory factory = con.buildSessionFactory(); Session session = factory.openSession(); Transaction tx = session.beginTransaction(); // 操作(單條數據查詢) /*Customer ct = session.get(Customer.class, 4L); // 立即載入: 只要調用方法的時候就把數據全部載入出來 System.out.println(ct);*/ Customer ct = session.load(Customer.class, 4L); // 延遲載入: 在調用方法的時候,先不去查詢載入數據,當使用到這個數據的時候才去載入 System.out.println(ct); // 重點面試題(100%): get查詢和load查詢的區別: // 1(重點): get查詢是立即載入,load查詢是延遲載入 // 2 : get查詢返回的是本身類型的對象,load查詢返回的是代理對象 // 3 : get查詢差不多數據會返回null,load查詢查不到數據會報錯 // 手動提交 tx.commit(); //關閉資源 session.close(); factory.close(); } @Test public void t3() { Session session = HibernateUtils.openSession(); // 開啟事務 Transaction tx = session.beginTransaction(); // 操作(更新方式一) /*Customer ct = new Customer(); ct.setCust_id(1L); ct.setCust_name("jackbbb"); session.update(ct);*/ // 更新方式二 先查再改 Customer ct = session.get(Customer.class, 1L); ct.setCust_name("jackccccc"); session.update(ct); // 手動提交 tx.commit(); // 釋放資源 session.close(); } @Test public void t4() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //操作(刪除-先查再刪) Customer ct = session.get(Customer.class, 3L); session.delete(ct); tx.commit(); session.close(); } @Test // 如果證明咱們使用的連接是從配置好的c3p0裡面獲取的 public void t5() { Session session = HibernateUtils.openSession(); session.doWork(new Work() { @Override //com.mchange.v2.c3p0.impl.NewProxyConnection public void execute(Connection con) throws SQLException { System.out.println(con.getClass().getName()); } }); } } 1.4Hibernate的常見配置 1.4.2核心配置文件的配置 Hibernate的核心配置文件的方式有兩種 hibernate.properties :不能載入映射文件。必須手動編寫程式碼載入映射文件。 hibernate.cfg.xml :結構清晰。(工作中使用) Hibernate的核心配置文件中的內容: 資料庫連接基本的參數 <?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> <!-- session-factory:連接池 session:連接對象 --> <!-- 5個必選項 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">1234</property> <!-- 配置方言 分頁: limit sqlserver:top oracle:sql嵌套 --> <!-- 作用:就是讓hibernte自動的匹配符合當前資料庫的sql語法 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可選的 --> <!-- 集成c3p0連接池 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 讓控制台輸出hibernate生成的sql語句 默認是一行--> <property name="hibernate.show_sql">true</property> <!-- 可以格式化sql語句 --> <property name="hibernate.format_sql">true</property> <!-- 可以讓hibernate根據配置好的映射文件自己生成表 --> <!-- create: 沒有 :hibernate根據映射文件創建對應的表,如果有表:刪除再創建 create-drop:沒有 :hibernate根據映射文件創建對應的表,如果有表:刪除再創建 ,用完就刪掉 // 測試數據的時候使用 update: 沒有表創建表,有表使用表 validate: 默認的值 hibernate不會創建任何錶 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 引入映射文件地址 --> <mapping resource="cn/baidu/domain/Customer.hbm.xml"/> </session-factory> </hibernate-configuration> Hibernate的屬性 1.4.3 映射文件配置 映射文件就是將類與表建立映射關係文件,這個文件只要是XML即可.通常名稱 : 類名.hbm.xml class標籤 : 建立類和表的映射 name : 類的全路徑. table : 資料庫中表的名稱. catalog : 資料庫名稱(可以省略) id標籤 : 建立主鍵和類中屬性映射 name : 類中的屬性的名稱 column : 表中的欄位名稱.(如果類中的屬性名和表中欄位名一致,column可以省略) property標籤 : 建立普通欄位與類中屬性映射 name : 類中的屬性的名稱. column : 表中的欄位名稱.(如果類中的屬性名和表中的欄位名一致,column可以忽略) length : 欄位的長度(自動創建表) not-null : 非空(自動創建表) unique : 唯一(自動創建表) 1.5Hibernate的常用API 1.5.1 Configuration : 配置對象 用來載入核心配置文件 : hibernate.cfg.xml Configuration cfg = new Configuration(); cfg.configure(); 用來載入映射文件: 手動載入 : cfg.addResource("com/heima/domain/Customer.hbm.xml"); 1.5.2 SessionFactory : session工廠對象 session工廠,是一個執行緒安全的對象,內容維護Hibernate的連接池.一般一個應用只需要創建一次的對象. public class HibernateUtils { // 載入配置文件 private static Configuration con =null; // 連接池 private static SessionFactory factory = null; static { con=new Configuration(); con.configure(); factory=con.buildSessionFactory(); } // 獲取sessionfactory public static SessionFactory getSessionFactory() { return factory; } // 獲取session public static Session openSession() { return factory.openSession(); } } 1.5.3 Session(...) : 連接對象 session 相對於Connection ,是執行緒不安全的,Session是Hibernate持久化操作的核心API.(不要把它放在一個dao層的成員變數) Seralizable save(Object obj); 保存數據. T get(Class clazz,Serializable id);根據ID查詢數據 T load(Class clazz,Serializable id);根據ID 查詢數據 get和load區別: get採用的立即載入(馬上發送一條SQL語句) : 程式執行到這行的時候,就會馬上發送SQL語句進行查詢. get方法查詢對象的時候返回的是真實對象本身. get方法查詢一個找不到的對象的時候輸出null. load採用的延遲載入(沒有馬上發送sql語句) : 程式執行到這行的時候,不會發送SQL語句,真正使用這個對象的時候(使用非主鍵屬性),才會發送sql語句. load方法查詢對象的時候返回的是代理對象. load查詢一個找不到的對象的時候返回ObjectNotFoundException. //get方法 Customer customer = session.get(Customer.class,100L);//馬上發送一條SQL語句 System.out.println(customer); //load方法 Customer customer = session.load(Customer.class,100L);沒有馬上發送SQL語句 System.out.println(customer.getCust_name()); transaction.commit(); session.close(); 修改id為6的客戶的資訊 public void demo3() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); //1.直接創建對象,進行修改 Customer customer = new Customer(); customer.setCust_id(5L); customer.setCust_name("郝芙蓉"); session.update(customer); //2.先查詢再修改 Customer customer = session.get(Customer.class,3L); customer.setCust_name("郝強吉吉"); session.update(customer); transaction.commit(); session.cloase(); } 刪除操作: public void demo4() { Session session = HibernateUtil.openSession(); Transaction transaction = session.beginTransaction(); //1.直接創建對象,傳入id刪除 Customer customer = new Customer(); customer.setCust_id(2L); session.delete(customer); //2.先查詢再刪除(推薦:級聯刪除) Customer customer = session.get(Customer.class,6L); session.delete(customer); transaction.commit(); session.cloae(); }