持久層ORM框架Hibernate框架的使用及搭建方式
前言
hibernate的概念:
hibernate是一個(gè)ormapping框架(ORM框架,全自動(dòng)ORM框架)
hibernate是一個(gè)數(shù)據(jù)庫(kù)的操作框架即持久層框架
Hibernate是一個(gè)開放源代碼的對(duì)象關(guān)系映射框架,它對(duì)JDBC進(jìn)行了非常輕量級(jí)的對(duì)象封裝,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來操縱數(shù)據(jù)庫(kù)(SQL語句由Hibernate根據(jù)對(duì)象自動(dòng)生成)。 Hibernate可以應(yīng)用在任何使用JDBC的場(chǎng)合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應(yīng)用中使用.。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、Hibernate的優(yōu)點(diǎn)?
1、Hibernate的代碼是比較簡(jiǎn)單的。
2、Hibernate是面向?qū)ο蟮牟僮鳌?br />
3、Hibernate的數(shù)據(jù)庫(kù)移動(dòng)植性很強(qiáng)。
4、Hibernate的緩存是世界級(jí)的。
二、Hibernate的缺點(diǎn)
1、不能干預(yù)sql語句的生成所以如果一個(gè)項(xiàng)目中,如果對(duì)sql語句的優(yōu)化要求比較高,那么不適合用hibernate
2、如果一張表中有千萬級(jí)別的數(shù)據(jù)量,也不適合用hibernate(因?yàn)榫彺鏅C(jī)制,它會(huì)將大量數(shù)據(jù)放入緩存)
3、hibernate適合用中小型企業(yè)開發(fā)軟件
4、hibernate不適合處理復(fù)雜SQL。
三、搭建Hibernate項(xiàng)目架構(gòu)
項(xiàng)目目錄

1、第一步導(dǎo)包

2、第二步編寫Hibernate的配置文件
我用的是Mysql數(shù)據(jù)庫(kù),你要是用別的把數(shù)據(jù)源驅(qū)動(dòng)信息改一下即可。
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--創(chuàng)建數(shù)據(jù)源-->
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/MySql</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- SQL 方言 -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- 是否顯示SQL -->
<property name="show_sql">true</property>
<!-- 實(shí)現(xiàn)格式化的sql -->
<property name="format_sql">true</property>
<!-- 是否自動(dòng)生成對(duì)象
create 表示每次都重新建立所需對(duì)象
update表示如果有就直接使用,如果修改則更新,如果沒有則創(chuàng)建
<property name="hbm2ddl.auto">update</property>
-->
<!--配置hibernate映射文件 -->
<!--配置映射文件-->
<mapping resource="com/zrrd/mapper/Dept.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
關(guān)于方言可以參考下面的圖片,根據(jù)項(xiàng)目需求配置即可。

3、第三步:編寫持久化類(pojo類)
package com.zrrd.vo;
public class Dept {
private Integer deptno;
private String dname;
private String loc;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
//直接轉(zhuǎn)換,看著方便
@Override
public String toString() {
return "Dept{" +
"deptno=" + deptno +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
public Dept() {
super();
}
public Dept(Integer deptno, String dname, String loc) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
}
4、第四步:編寫Hibernate映射文件(*.hbm.xml)
該文件完成 持久化類和數(shù)據(jù)庫(kù)中指定表的映射。說白了就是說明持久化類對(duì)應(yīng)數(shù)據(jù)庫(kù)中的哪張表,類中的每個(gè)屬性都對(duì)應(yīng)數(shù)據(jù)庫(kù)中的那些字段。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- package="com.javashidai.hibernate001.domain" 指明持久化類所在的包 --> <hibernate-mapping package="com.zrrd.vo"> <!-- name="Dept" 表示類名 table="dept" 對(duì)應(yīng)的表名 --> <class name="Dept" table="dept" > <!-- 指明主鍵對(duì)應(yīng)的屬性和字段 name="deptno" 表示持久化類中的deptno對(duì)應(yīng)主鍵字段 column="deptno"表示是主鍵字段 --> <id name="deptno" column="deptno"> <!-- 主鍵生成策略 :序列 --> <generator class="sequence"> <!-- 指明所需的序列名 --> <param name="sequence">SEQ_DEPT</param> </generator> </id> <!-- property指明非主鍵列 name="dname"表示持久化類中的屬性名 length="14"指明數(shù)據(jù)庫(kù)中對(duì)應(yīng)字段接收的長(zhǎng)度 column="dname" 指明對(duì)應(yīng)數(shù)據(jù)庫(kù)中的什么字段 type="string" 對(duì)應(yīng)的數(shù)據(jù)類型 --> <property name="dname" length="14" column="dname" type="string"/> <property name="loc" length="13" column="loc" type="string"/> </class> </hibernate-mapping>
5、第五步:編寫測(cè)試類完成對(duì)數(shù)據(jù)庫(kù)的操作
package com.zrrd.text;
import com.zrrd.vo.Dept;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Text {
public static void main(String[] args){
//讀取Hibernate.cfg.xml配置文件
Configuration configuration=new Configuration();
configuration.configure("hibernate.cfg.xml");
//創(chuàng)建sessionfactory工程
SessionFactory sessionFactory=configuration.buildSessionFactory();
//創(chuàng)建Session對(duì)象
Session session=sessionFactory.openSession();
//創(chuàng)建實(shí)體對(duì)象(與數(shù)據(jù)庫(kù)中表對(duì)應(yīng)的vo對(duì)象為實(shí)體對(duì)象,進(jìn)而操作數(shù)據(jù)庫(kù)(由Hibernate自動(dòng)創(chuàng)建SQL語句)
Dept dept=session.get(Dept.class,1);
System.out.println(dept);
session.close();
sessionFactory.close();
}
}
執(zhí)行結(jié)果圖

數(shù)據(jù)庫(kù)存的數(shù)據(jù)

四、Hibernate核心接口的介紹
Hibernate的核心接口一共有6個(gè),分別為:Session、SessionFactory、
Transaction、Query、Criteria和Configuration。這6個(gè)核心接口在任何開發(fā)中都會(huì)用到。通過這些接口,不僅可以對(duì)持久化對(duì)象進(jìn)行存取,還能夠進(jìn)行事務(wù)控制。
1.Session
Session接口負(fù)責(zé)執(zhí)行被持久化對(duì)象的CRUD操作(CRUD的任務(wù)是完成與數(shù)據(jù)庫(kù)的交流,包含了很多常見的SQL語句。)。但需要注意的是Session對(duì)象是非線程安全的。同時(shí),Hibernate的session不同于JSP應(yīng)用中的HttpSession。這里當(dāng)使用session這個(gè)術(shù)語時(shí),其實(shí)指的是Hibernate中的session,而以后會(huì)將HttpSession對(duì)象稱為用戶session。
2.SessionFactory
SessionFactory接口負(fù)責(zé)初始化Hibernate。它充當(dāng)數(shù)據(jù)存儲(chǔ)源的代理,并負(fù)責(zé)創(chuàng)建Session對(duì)象。這里用到了工廠模式。需要注意的是SessionFactory并不是輕量級(jí)的,因?yàn)橐话闱闆r下,一個(gè)項(xiàng)目通常只需要一個(gè)SessionFactory就夠,當(dāng)需要操作多個(gè)數(shù)據(jù)庫(kù)時(shí),可以為每個(gè)數(shù)據(jù)庫(kù)指定一個(gè)SessionFactory。
3.Transaction
Transaction 接口是一個(gè)可選的API,可以選擇不使用這個(gè)接口,取而代之的是Hibernate 的設(shè)計(jì)者自己寫的底層事務(wù)處理代碼。 Transaction 接口是對(duì)實(shí)際事務(wù)實(shí)現(xiàn)的一個(gè)抽象,這些實(shí)現(xiàn)包括JDBC的事務(wù)、JTA 中的UserTransaction、甚至可以是CORBA 事務(wù)。之所以這樣設(shè)計(jì)是能讓開發(fā)者能夠使用一個(gè)統(tǒng)一事務(wù)的操作界面,使得自己的項(xiàng)目可以在不同的環(huán)境和容器之間方便地移植。
4.Query
Query接口讓你方便地對(duì)數(shù)據(jù)庫(kù)及持久對(duì)象進(jìn)行查詢,它可以有兩種表達(dá)方式:HQL語言或本地?cái)?shù)據(jù)庫(kù)的SQL語句。Query經(jīng)常被用來綁定查詢參數(shù)、限制查詢記錄數(shù)量,并最終執(zhí)行查詢操作。
5.Criteria
Criteria接口與Query接口非常類似,允許創(chuàng)建并執(zhí)行面向?qū)ο蟮臉?biāo)準(zhǔn)化查詢。值得注意的是Criteria接口也是輕量級(jí)的,它不能在Session之外使用。
6.Configuration
Configuration 接口的作用是對(duì)Hibernate 進(jìn)行配置,以及對(duì)它進(jìn)行啟動(dòng)。在Hibernate 的啟動(dòng)過程中,Configuration 類的實(shí)例首先定位映射文檔的位置,讀取這些配置,然后創(chuàng)建一個(gè)SessionFactory對(duì)象。雖然Configuration 接口在整個(gè)Hibernate 項(xiàng)目中只扮演著一個(gè)很小的角色,但它是啟動(dòng)hibernate 時(shí)所遇到的第一個(gè)對(duì)象。
五、封裝Hibernate的工具類
當(dāng)然我們?cè)趯?shí)際開發(fā)的項(xiàng)目當(dāng)中肯定不會(huì)CRUD的時(shí)候都去寫測(cè)試類里面的代碼,這樣會(huì)導(dǎo)致項(xiàng)目代碼量巨大而且可移植性太差,所以我們要封裝一下寫一個(gè)工具類,用的時(shí)候直接調(diào)用即可。
public class HibernateUtil {
//一個(gè)Hibernate容器中只需要一個(gè)SessionFactory
private static SessionFactory sessionFactory;
//利用靜態(tài)代碼框創(chuàng)建SessionFactory對(duì)象
static
{
//創(chuàng)建Configuration對(duì)象
Configuration conf = new Configuration();
//加載Hibernate配置文件
conf.configure();//默認(rèn)加載src下的hibernate.cfg.xml
//創(chuàng)建SessionFactory對(duì)象
sessionFactory = conf.buildSessionFactory();
}
//得到Session對(duì)象
public static Session getSession()
{
return sessionFactory.openSession();
}
}
六、常用的CRUD操作
我都已經(jīng)寫好啦相關(guān)執(zhí)行的方法,你只要改改返回的類型就可以啦,就像Jpa框架那樣,直接在你的項(xiàng)目中使用就可以啦。不用太感謝我,為人民服務(wù)!
1.根據(jù)主鍵查詢對(duì)象
public Dept selectOne(int deptno)
{
Dept dept= null;
//得到session對(duì)象
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//根據(jù)主鍵得到對(duì)應(yīng)的信息
dept = (Dept) session.get(Dept.class, deptno);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
return dept;
}
2.查詢?nèi)康男畔?/p>
public static List<Dept> queryDept()
{
List<Dept> deptList = null;
//聲明session
Session session = null;
try
{
//創(chuàng)建Session對(duì)象
session= HibernateUtil.getSession();
//聲明HQL :其中Dept為實(shí)體類
String hql="from Dept ";//from后寫的是類名
//得到Query對(duì)象
Query query = session.createQuery(hql);
//執(zhí)行查詢
deptList = query.list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
return deptList;
}
3.條件查詢
public List<Dept> queryDeptByLoc(String loc)
{
List<Dept> deptList = null;
//聲明session
Session session = null;
try
{
//創(chuàng)建Session對(duì)象
session= HibernateUtil.getSession();
//聲明HQL :其中Dept為實(shí)體類
String hql="from com.zrrd.vo.Dept where loc=:loc ";//:loc表示是參數(shù)
//得到query對(duì)象
Query query = session.createQuery(hql);
//給參數(shù)賦值
query.setString("loc", loc);//給指定參數(shù)賦值
//查詢返回List<Dept>
deptList = query.list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
return deptList;
}
4.根據(jù)主鍵刪除
public void deleteDept(int deptno)
{
//聲明Session對(duì)象
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//開啟事務(wù)保護(hù)
Transaction ta = session.beginTransaction();
//根據(jù)id得到對(duì)應(yīng)的值
Dept deleteObj = (Dept) session.get(Dept.class, deptno);
//刪除該對(duì)應(yīng)
session.delete(deleteObj);
//提交事務(wù)
ta.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
}
5.根據(jù)指定條件刪除
/**
* 利用Hql進(jìn)行刪除
* 根據(jù)部門編號(hào)進(jìn)行刪除
*/
public int deleteDeptByLoc(String loc)
{
int result =0;
//聲明Session對(duì)象
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//開啟事務(wù)保護(hù)
Transaction ta = session.beginTransaction();
//編寫刪除使用的HQL 這里的:loc表示參數(shù)名
String hql="delete com.zrrd.vo.Dept where loc=:loc";
//得到Query對(duì)象
Query query =session.createQuery(hql);
//給參數(shù)賦值
query.setString("loc", loc);
//執(zhí)行DML語句
result = query.executeUpdate();
//提交事務(wù)
ta.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
return result;
}
6.修改單個(gè)對(duì)象
public static void updateDept(Dept dept)
{
//聲明Session對(duì)象
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//開啟事務(wù)保護(hù)
Transaction ta = session.beginTransaction();
//根據(jù)持久化對(duì)象進(jìn)行修改
session.update(dept);
//提交事務(wù)
ta.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
}
7.根據(jù)條件進(jìn)行修改(HQL)
public static int updateDeptLoc(String oldLoc,String newLoc)
{
int result =0;
//聲明Session對(duì)象
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//開啟事務(wù)保護(hù)
Transaction ta = session.beginTransaction();
//編寫刪除使用的HQL 這里的:loc表示參數(shù)名
String hql="update Dept set loc=:newLoc where loc=:oldLoc";
//得到Query對(duì)象
Query query =session.createQuery(hql);
//給參數(shù)賦值
query.setString("newLoc", newLoc);
query.setString("oldLoc", oldLoc);
//執(zhí)行DML語句
result = query.executeUpdate();
//提交事務(wù)
ta.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
return result;
}
8.將對(duì)象存入數(shù)據(jù)庫(kù)
public static void saveDept(Dept dept)
{
Session session = null;
try
{
//得到Session對(duì)象
session = HibernateUtil.getSession();
//得到事務(wù)對(duì)象
Transaction ta = session.beginTransaction();
//將持久化對(duì)象存入 數(shù)據(jù)庫(kù)
session.save(dept);
//提交事務(wù)
ta.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(session != null)
{
session.close();
}
}
}
七、主鍵生成機(jī)制
1、increment:表示hibernate調(diào)用所連接的數(shù)據(jù)庫(kù)的加一機(jī)制為該字段生成信息(即生成主鍵)
2、identity:表示由所連接的數(shù)據(jù)本身調(diào)用自加一機(jī)制為該字段生成信息(即生成主鍵)
Increment 和identity的區(qū)別在于前者是由hibernate調(diào)用生成機(jī)制,后者是數(shù)據(jù)庫(kù)本身調(diào)用生成機(jī)制(即您在建表的時(shí)候就聲明該字段是自動(dòng)加一的)。但是以上兩種主鍵生成機(jī)制在連接Oracle時(shí)都不適用。因?yàn)镺racle沒有自動(dòng)加一機(jī)制。如果Oracle要用自動(dòng)加一機(jī)制就必須依靠。
3、sequence:表示該字段由數(shù)據(jù)的序列生成,如果不想指定特定的序列則在Oracle中該序列名字必須叫HIBERNATE_SEQUENCE 用于默認(rèn)選擇。


4、uuid:根據(jù)UUID算法生成生成32位字符類型的主鍵信息。

5、guid:利用數(shù)據(jù)庫(kù)提供的sys_guid 函數(shù)生成主鍵。但是要注意不是所有數(shù)據(jù)庫(kù)都有sys_guid函數(shù)的。所以首選還是uuid

6、native:根據(jù)具體連接的數(shù)據(jù)庫(kù)從identity, sequence或者h(yuǎn)ilo選擇一種來生成主鍵。適用的數(shù)據(jù)庫(kù)根據(jù)選擇的生成方式確定。(這個(gè)情況數(shù)據(jù)庫(kù)是可以跨越的,因?yàn)樗茏詣?dòng)選擇生成方案),在Oracle中就必須有名字叫HIBERNATE_SEQUENCE的序列
assigned: 交給應(yīng)用自己給主鍵賦值。要注意的是賦值必須在調(diào)用save()方法之前完成。適用的數(shù)據(jù)庫(kù)根據(jù)選擇的生成方式確定。
八、Hibernate的類型
在Hibernate中可以使用純java類型和Hibernate指定類型。在Hibernate框架的內(nèi)部可以自動(dòng)對(duì)Java類型或者Hibernate類型完成對(duì)表的對(duì)應(yīng)。建議在開發(fā)中使用java類型,效率比較快

總結(jié)
以上文章只是其中的一部分只是教你如何實(shí)現(xiàn)框架實(shí)現(xiàn)CRUD的操作,最重要的是后續(xù)我要寫的知識(shí)點(diǎn):反向創(chuàng)建Hibernate工程、對(duì)象(DO對(duì)象)的三種狀態(tài)、一對(duì)多關(guān)系(在主對(duì)象設(shè)計(jì)從對(duì)象集合屬性)、多對(duì)多、懶加載(延遲加載)、抓取策略、Hibernate的一級(jí)緩存(Session緩存)、Hibernate的二級(jí)緩存、HQL、Query.list和query.iterator等等,這些才是重中之重,任重而道遠(yuǎn)。
到此這篇關(guān)于持久層ORM框架Hibernate框架的使用及搭建方式的文章就介紹到這了,更多相關(guān)ORM框架Hibernate框架使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis圖文并茂講解注解開發(fā)一對(duì)多查詢
這篇文章主要介紹了SpringBoot中Mybatis注解一對(duì)多查詢的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
java判斷各類型字符個(gè)數(shù)實(shí)例代碼
大家好,本篇文章主要講的是java判斷各類型字符個(gè)數(shù)實(shí)例代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12

