Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數據庫表建立映射關係,是一個全自動的orm框架(對象關係映射,英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping)),是一種程序技術,用於實現面向對象編程語言裏不同類型系統的數據之間的轉換),hibernate可以自動生成SQL語句,自動執行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,完成數據持久化的重任。(來自百度百科)
博主也接觸hibernate有一段時間了,藉此來寫一篇博客來梳理自己學到的知識。(學習資源大部分在網站教程等視頻學得)
話不多說,下面開始:
環境:eclipse、tomcat9.0.8、jdk1.8、mysql5.1.2以上
爲什麼要用hibernate呢?其實hibernate對於數據庫的操作做了很多封裝,當我們正常使用JDBC數據庫操作,創建連接、關閉連接,反反覆覆。而hibernate對於這些操作,都將其封裝了起來,用面向對象的方式來操作關係向數據庫,使得代碼維護更加容易,數據庫的操作更加簡便。
首先,官網下載hibernate,根據自己的系統下載不同的壓縮包。並解壓。
目錄結構
我們選取需要的jar包
1.創建web項目
使用eclipse創建個web項目(這裏不過多介紹)
將需要的jar包放入lib文件夾中
(可根據自己配置來導入jar包,目前我的jar包如上)
2.創建數據庫和表和配置
創建數據庫和表
create database hibernate;
use hibernate;
CREATE TABLE product_ (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(30) ,
price float ,
PRIMARY KEY (id)
) DEFAULT CHARSET=UTF8;
新建com.hibernate.pojo包,新建實體類,使之與數據庫的表對應
package com.hibernate.pojo;
public class Product {
int id;
String name;
float price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
在包com.hibernate.pojo下 新建一個配置文件Product.hbm.xml, 用於映射Product類對應數據庫中的product表(文件名 Product.hbm.xml中P一定要大寫,要和類名保持一致)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.pojo">
<class name="Product" table="product">
<id name="id" column="id">
<!--id的自增長方式採用數據庫的本地方式-->
<generator class="native">
</generator>
</id>
<property name="name" />
<property name="price" />
</class>
</hibernate-mapping>
在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="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- SQL dialect -->
<!-- 這表示使用MYSQL方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Hibernate事務管理方式,即每個線程一個事務 -->
<property name="current_session_context_class">thread</property>
<!-- 控制檯顯示執行的sql語句,true輸出,false不輸出 -->
<property name="show_sql">true</property>
<!-- 是否會自動更新數據庫的表結構,其實配置了這個是不需要創建表的,因爲Hibernate會自動去創建表結構 -->
<!-- 所以之前創建表那一步也可以省略 -->
<property name="hbm2ddl.auto">update</property>
<!-- 識別Product這個實體類 -->
<mapping resource="com/hibernate/pojo/Product.hbm.xml" />
</session-factory>
</hibernate-configuration>
好,現在配置完成,我們來測試下是否可以使用hibernate來操作數據庫
3.測試
新建測試類
package com.hibernate.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.hibernate.pojo.Product;
public class Test {
public static void main(String[] args) {
/*獲取SessionFactory*/
SessionFactory sf = new Configuration().configure().buildSessionFactory();
/*通過SessionFactory 獲取一個Session*/
Session session = sf.openSession();
/*在Session基礎上開啓一個事務*/
session.beginTransaction();
/*new一個Product對象用於測試*/
Product p = new Product();
p.setName("iphone2000");
p.setPrice(666);
/*調用Session的save方法把對象保存到數據庫*/
session.save(p);
/*提交事務*/
session.getTransaction().commit();
/*關閉*/
session.close();
sf.close();
}
}
其中實體類在Hibernate的有3種狀態,分別爲:瞬時態(Transient)、持久態(Persistent)、脫管態(Detached).處於持久態的對象也稱爲PO(PersistenceObject),瞬時對象和脫管對象也稱爲VO(ValueObject).
new 對象,而沒有將它和數據庫連接起來,沒有標識,這就叫做瞬時態。
瞬時態進行了save saveorUpdate方法後,與數據庫有了聯繫,這就是持久態,
當關閉session 或者清除,但是還有和數據庫聯繫的標識,這就是託管態,或者是遊離態。
Product p = new Product();
p.setName("iphone2000");
p.setPrice(666);
//此時p是瞬時狀態
s.save(p);
//此時p是持久狀態
s.getTransaction().commit();
s.close();
//此時p是脫管狀態
sf.close();
運行main方法
看到控制檯輸出
Hibernate: insert into product (name, price) values (?, ?)
查看數據庫
插入成功,大功告成!
下面是hibernate的根據主鍵查詢
首先Product類增加toString()方法
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
}
修改測試類
package com.hibernate.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.hibernate.pojo.Product;
public class Test {
public static void main(String[] args) {
/*獲取SessionFactory*/
SessionFactory sf = new Configuration().configure().buildSessionFactory();
/*通過SessionFactory 獲取一個Session*/
Session session = sf.openSession();
/*在Session基礎上開啓一個事務*/
session.beginTransaction();
/*調用Session的get方法,根據id來獲取對象。
*並且除了id之外,還需要傳遞該類對象*/
Product p1 = (Product) session.get(Product.class, 3);
/*輸出*/
System.out.println(p1.toString());
/*提交事務*/
session.getTransaction().commit();
/*關閉*/
session.close();
sf.close();
}
}
查看控制檯
成功!
其中通過這種方法來獲取對象還有另一種方法
是通過load的方法去獲取對象
Product p1 = (Product) session.get(Product.class, 3);
他們的結果是一樣的,但是他們不同的地方是:
get:是非延遲的加載,就是無論後面的代碼能不能訪問到屬性,屬性有沒有成功獲取等,都會直接執行sql語句
load:是延遲加載,就是隻有屬性被訪問到了纔會去調用sql語句
所以,如果我們用一個不存在的主鍵去獲取的話,兩種方式的結果就會不一樣
get(拋空指針null)
load(拋異常)
下面是刪除數據庫的一條數據
修改測試類
只需要在獲取到對象之後再加一行代碼
session.delete(p)
package com.hibernate.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.hibernate.pojo.Product;
public class Test {
public static void main(String[] args) {
/*獲取SessionFactory*/
SessionFactory sf = new Configuration().configure().buildSessionFactory();
/*通過SessionFactory 獲取一個Session*/
Session session = sf.openSession();
/*在Session基礎上開啓一個事務*/
session.beginTransaction();
/*調用Session的get方法,根據id來獲取對象。
*並且除了id之外,還需要傳遞該類對象*/
Product p1 = (Product) session.get(Product.class, 2);
/*刪除*/
session.delete(p1);
/*提交事務*/
session.getTransaction().commit();
/*關閉*/
session.close();
sf.close();
}
}
下面是修改數據庫的一條數據
package com.hibernate.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.hibernate.pojo.Product;
public class Test {
public static void main(String[] args) {
/*獲取SessionFactory*/
SessionFactory sf = new Configuration().configure().buildSessionFactory();
/*通過SessionFactory 獲取一個Session*/
Session session = sf.openSession();
/*在Session基礎上開啓一個事務*/
session.beginTransaction();
/*調用Session的get方法,根據id來獲取對象。
*並且除了id之外,還需要傳遞該類對象*/
Product p1 = (Product) session.get(Product.class, 2);
/*修改屬性值*/
p1.setName("xiaomi2000");
p1.setPrice(1999);
/*update,更新下*/
session.update(p1);
/*提交事務*/
session.getTransaction().commit();
/*關閉*/
session.close();
sf.close();
}
}