摘要:因此,需要我們自己添加如果需要更新,如果想要體現對應的關聯關系的話,請參考該博文如果文章有錯的地方歡迎指正,大家互相交流。
前言
在Hibernate的第二篇中只是簡單地說了Hibernate的幾種查詢方式....到目前為止,我們都是使用一些簡單的主鍵查詢阿...使用HQL查詢所有的數據....本博文主要講解Hibernate的查詢操作,連接池,逆向工程的知識點...
get/load主鍵查詢由于主鍵查詢這個方法用得比較多,于是Hibernate專門為我們封裝了起來...
get()立即查詢
load()懶加載
對象導航查詢如果對象與對象之前存在一對多、多對一的關系的時候
在以前SQL查詢的時候:我們如果想要得到當前對象與另一對象的關聯關系的時候,就必須用多表查詢來得到數據
Hibernate提供了對象導航查詢:我們可以使用主鍵查詢完之后,得到的對象,直接使用對象得到集合...就可以得到對應的數據了。
// 對象導航查詢 Dept dept = (Dept) session.get(Dept.class, 12); System.out.println(dept.getDeptName()); //這里就可以得到部門對應的所有員工 System.out.println(dept.getEmps());HQL查詢
在Hibernate的前面章節中已經講解過了基本的概念了。在這里我們就直接看看怎么使用了。
值得注意的是:
在hbm.xml文件中的auto-import="true" 要設置true。當然了,默認值就是ture
如果是false,寫hql的時候,要指定類的全名
查詢全部列//方式一:直接寫對象 Query q = session.createQuery("from Dept"); //方式二:可以為對象取別名 Query q = session.createQuery("select d from Dept d");
值得注意的是:HQL不支持*號,下面的代碼是錯誤的。
//不能用* Query q = session.createQuery("select * from Dept d");查詢指定的列
值得注意的是:使用HQL查詢指定的列,返回的是對象數組Object[]
//只查詢name和eatBanana列 Query query = session.createQuery("select m.name,m.eatBanana from Monkey m"); System.out.println(query.list());封裝對象
前面測試了查詢指定的列的時候,返回的是對象數組...可是對象數組我們不好操作啊...Hibernate還提供了將對象數組封裝成對象的功能
JavaBean要有對應的構造函數
Query query = session.createQuery("select new Monkey(m.name,m.eatBanana )from Monkey m");條件查詢
在SQL中條件查詢我們也用得比較多,我們來看看HQL中的條件查詢有什么新特性。
占位符占位符就是指?號,我們在SQL中也常常用...
Query query = session.createQuery("from Monkey m where m.name=?"); //HQL是從0開始的 query.setParameter(0, "大猴子"); System.out.println(query.list());命名參數
HQL還支持命名參數查詢!下面我們來看一下怎么用:
語法::命名
Query query = session.createQuery("from Monkey m where m.name=:monkeyName"); //HQL是從0開始的 query.setParameter("monkeyName", "大猴子"); System.out.println(query.list());范圍查詢
范圍查詢就是使用between and關鍵字來查詢特定范圍的數據。。和SQL是一樣的...
Query q = session.createQuery("from Dept d where deptId between ? and ?"); q.setParameter(0, 1); q.setParameter(1, 20); System.out.println(q.list());模糊查詢
模糊查詢就是使用Like關鍵字進行查詢,和SQL也是一樣的。
%號要寫在參數上,不能寫帶SQL上!
//模糊 Query q = session.createQuery("from Dept d where deptName like ?"); q.setString(0, "%部%"); System.out.println(q.list());聚合函數統計
我們也經常會查詢數據庫中一共有多少條記錄這樣的需求。那么在HQL中怎么用呢?
HQL提供了uniqueResult()這么一個方法,返回只有一條記錄的數據
Query query = session.createQuery("select COUNT(*) from Monkey"); Object o = query.uniqueResult(); System.out.println(o);分組查詢
分組查詢和SQL是一樣的...
//-- 統計t_employee表中,每個部門的人數 //數據庫寫法:SELECT dept_id,COUNT(*) FROM t_employee GROUP BY dept_id; // HQL寫法 Query q = session.createQuery("select e.dept, count(*) from Employee e group by e.dept"); System.out.println(q.list());連接查詢
連接查詢也就是多表查詢...多表查詢有三種
內連接【等值連接】
左外連接
有外鏈接
值得注意的是:連接查詢返回的也是對象數組!
//1) 內連接 【映射已經配置好了關系,關聯的時候,直接寫對象的屬性即可】 Query q = session.createQuery("from Dept d inner join d.emps"); //2) 左外連接 Query q = session.createQuery("from Dept d left join d.emps"); //3) 右外連接 Query q = session.createQuery("from Employee e right join e.dept"); q.list();迫切連接
由于連接查詢返回的是對象數組,我們使用對象數組來操作的話會很不方便...既然是連接查詢,那么對象與對象是肯定有關聯關系的...于是乎,我們想把左表的數據填充到右表中,或者將右表的數據填充到左表中...使在返回的時候是一個對象、而不是對象數組!HQL提供了fetch關鍵字供我們做迫切連接~
//1) 迫切內連接 【使用fetch, 會把右表的數據,填充到左表對象中!】 Query q = session.createQuery("from Dept d inner join fetch d.emps"); q.list(); //2) 迫切左外連接 Query q = session.createQuery("from Dept d left join fetch d.emps"); q.list();查詢語句放在配置文件中【命名查詢】
我們可以在具體的映射配置文件中存放一些常用的語句。以Dept為例
在程序中,我們可以獲取配置文件配置的語句
Query q = session.getNamedQuery("getAllDept"); q.setParameter(0, 10); System.out.println(q.list());Criteria 查詢
Criteria是一種完全面向對象的查詢...
Criteria使用的是add()來添加條件。條件又使用一個Restrictions類來封裝
Criteria criteria = session.createCriteria(Monkey.class); criteria.add(Restrictions.eq())
我們來簡單看一下Restrictions的方法:
都是一些大于、小于、等于之類的....Criteria查詢就使用不了分組、連接查詢了。
SQLQuery本地SQL查詢有的時候,我們可能表的結構十分復雜,如果使用關聯映射的話,配置文件是十分臃腫的...因此,我們并不是把全部的數據表都使用映射的方式來創建數據表...
這時,我們就需要用到SQLQuery來維護我們的數據了..
SQLQuery是不能跨數據庫的,因為Hibernate在配置的時候就指定了數據庫的“方言”...
SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM monkey_ limit 0,3"); System.out.println(sqlQuery.list());
返回的也是對象數組:
Hibernate也支持在SQLQuery中對數據進行對象封裝..只要添加類型就行了
SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM monkey_ limit 0,3").addEntity(Monkey.class); System.out.println(sqlQuery.list());分頁查詢
傳統的SQL我們在DAO層中往往都是使用兩個步驟來實現分頁查詢
得到數據庫表中的總記錄數
查詢起始位置到末尾位數的數據
Hibernate對分頁查詢也有很好地支持,我們來一下:
Query query = session.createQuery("from Monkey"); //得到滾動結果集 ScrollableResults scroll = query.scroll(); //滾動到最后一行 scroll.last(); int i = scroll.getRowNumber() + 1; System.out.println("總計路數:" + i); //設置分頁位置 query.setFirstResult(0); query.setMaxResults(3); System.out.println(query.list());
提供了方法讓我們設置起始位置和結束位置
提供了ScrollableResults來得到滾動結果集,最終得到總記錄數
值得注意的是,滾動結果集是從0開始的,因此需要+1才可得到總記錄數!
如果我們們使用的是SELECT COUNT(*) FROM 實體,我們可以通過uniqueResult()方法獲取數據的唯一記錄,得到的數據轉換成Long類型即可。
Long totalRecord = (Long) queryCount.uniqueResult();Hibernate連接池
Hibernate自帶了連接池,但是呢,該連接池比較簡單..而Hibernate又對C3P0這個連接池支持...因此我們來更換Hibernate連接池為C3P0
查看Hibernate自帶的連接池我們可以通過Hibernate.properties文件中查看Hibernate默認配置的連接池
hibernate.properties的配置文件可以在projectetc找到
Hibernate的自帶連接池啥都沒有,就一個連接數量為1...
查看Hibernate對C3P0的支持hibernate.c3p0.max_size 2 最大連接數
hibernate.c3p0.min_size 2 最小連接數
hibernate.c3p0.timeout 5000 超時時間
hibernate.c3p0.max_statements 100 最大執行的命令的個數
hibernate.c3p0.idle_test_period 3000 空閑測試時間
hibernate.c3p0.acquire_increment 2 連接不夠用的時候, 每次增加的連接數
hibernate.c3p0.validate false
修改Hibernate連接池我們在hibernate.cfg.xml中配置C3p0,讓C30P0作為Hibernate的數據庫連接池
查找Hibernate支持的連接池組件有什么:
既然找到了,那么我們在hibernate.cfg.xml中配置對應的類就和相關配置就行了
線程Session使用org.hibernate.connection.C3P0ConnectionProvider 2 4 5000 10 30000 2
我們創建Session的時候,有兩個方法
openSession()【每次都會創建新的Session】
getCurrentSession()【獲取當前線程的Session,如果沒有則創建】
一般地,我們使用線程Session比較多
如果要使用getCurrentSession(),需要在配置文件中配置:
測試數據thread
@Test public void testSession() throws Exception { //openSession: 創建Session, 每次都會創建一個新的session Session session1 = sf.openSession(); Session session2 = sf.openSession(); System.out.println(session1 == session2); session1.close(); session2.close(); //getCurrentSession 創建或者獲取session // 線程的方式創建session // 一定要配置:為什么要使用逆向工程thread Session session3 = sf.getCurrentSession();// 創建session,綁定到線程 Session session4 = sf.getCurrentSession();// 從當前訪問線程獲取session System.out.println(session3 == session4); // 關閉 【以線程方式創建的session,可以不用關閉; 線程結束session自動關閉】 //session3.close(); //session4.close(); 報錯,因為同一個session已經關閉了! }
由于我們每次編寫Hibernate的時候都需要寫實體,寫映射文件。而且Hibernate的映射文件也容易出錯。而逆向工程可以幫我們自動生成實體和映射文件,這樣就非常方便了。
使用PowerDesigner在設計數據庫表時,我們使用PowerDesigner來生成概念模型物理模型...
設計一個人員組織架構:有機構、部門、員工、領導、角色、權限。
一個機構有多個部門
一個部門有多個員工
領導可以管理多個部門,同時領導他自己也是員工
一個員工可以有多個角色
一個角色可以分配給多個人
人員角色分配后可以設置是否有效,分配時間等
一個角色有多個權限
概念模型:在PowerDesigner中,箭頭指向的方向永遠是“一”的一方
生成物理模型:最后生成物理模型是這樣子的:
生成sql語句我們可以單個生成,一個一個復制
也可以把整個物理模型的sql語句一起生成:
/*==============================================================*/ /* DBMS name: MySQL 5.0 */ /* Created on: 2017/6/5 20:22:52 */ /*==============================================================*/ drop table if exists person_role; drop table if exists t_company; drop table if exists t_dept; drop table if exists t_employee; drop table if exists t_person; drop table if exists t_privilege; drop table if exists t_role; drop table if exists t_role_privilege; /*==============================================================*/ /* Table: person_role */ /*==============================================================*/ create table person_role ( person_id varchar(32) not null, role_id varchar(32) not null, state varchar(32), primary key (person_id, role_id) ); /*==============================================================*/ /* Table: t_company */ /*==============================================================*/ create table t_company ( company_id varchar(32) not null, name varchar(32), primary key (company_id) ); /*==============================================================*/ /* Table: t_dept */ /*==============================================================*/ create table t_dept ( dept_id varchar(32) not null, company_id varchar(32) not null, name varchar(32), primary key (dept_id) ); /*==============================================================*/ /* Table: t_employee */ /*==============================================================*/ create table t_employee ( person_id varchar(32) not null, dept_id varchar(32), name varchar(32), employee_id varchar(32), primary key (person_id) ); /*==============================================================*/ /* Table: t_person */ /*==============================================================*/ create table t_person ( person_id varchar(32) not null, dept_id varchar(32) not null, name varchar(32), primary key (person_id) ); /*==============================================================*/ /* Table: t_privilege */ /*==============================================================*/ create table t_privilege ( privilege_id varchar(32) not null, name varchar(32), primary key (privilege_id) ); /*==============================================================*/ /* Table: t_role */ /*==============================================================*/ create table t_role ( role_id varchar(32) not null, name varchar(32), primary key (role_id) ); /*==============================================================*/ /* Table: t_role_privilege */ /*==============================================================*/ create table t_role_privilege ( role_id varchar(32) not null, privilege_id varchar(32) not null, primary key (role_id, privilege_id) ); alter table person_role add constraint FK_person_role foreign key (person_id) references t_person (person_id) on delete restrict on update restrict; alter table person_role add constraint FK_person_role2 foreign key (role_id) references t_role (role_id) on delete restrict on update restrict; alter table t_dept add constraint FK_companty_dept foreign key (company_id) references t_company (company_id) on delete restrict on update restrict; alter table t_employee add constraint FK_inherit foreign key (person_id) references t_person (person_id) on delete restrict on update restrict; alter table t_person add constraint FK_dept_person foreign key (dept_id) references t_dept (dept_id) on delete restrict on update restrict; alter table t_role_privilege add constraint FK_belong foreign key (role_id) references t_role (role_id) on delete restrict on update restrict; alter table t_role_privilege add constraint FK_own foreign key (privilege_id) references t_privilege (privilege_id) on delete restrict on update restrict;
在數據庫生成八張表:
在Idea下使用Hibernate逆向工程值得注意的是:Intellij idea下生成出來的映射文件是沒有對應的關聯關系的。也就是說:一對多或多對多的關系,它是不會幫你自動生成的【好像是這樣子的】。。。因此,需要我們自己添加Set【如果需要】
更新,如果想要體現對應的關聯關系的話,請參考該博文!
https://my.oschina.net/wangyu...
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68711.html
摘要:前言由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 前言 由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導航哦~想要獲取最新原創的技術文章歡迎關注我的公眾號:Java3y Java3y文章目錄導航 Java基礎 泛型就這么簡單 注解就這么簡單 Druid數據庫連接池...
摘要:要是使用到日歷的話,我們想到使用這個日歷類上面僅僅是我個人總結的要點,如果有錯誤的地方還請大家給我指正。 納稅服務系統總結 納稅服務系統是我第一個做得比較大的項目(不同于javaWeb小項目),該項目系統來源于傳智Java32期,十天的視頻課程(想要視頻的同學關注我的公眾號就可以直接獲取了) 我跟著練習一步一步完成需求,才發覺原來Java是這樣用來做網站的,Java有那么多的類庫,頁面...
摘要:系列文章地址原文地址一個高性能的數據訪問層需要很多關于數據庫的內部結構以及很多優化商業應用的技術建議。在語句中的表現最好,不過不能使用約束,數據完整性的控制較差。應用層的緩存則利用高速副本的方式來保證低響應時間。 Github系列文章地址 原文地址 Introduction 一個高性能的數據訪問層需要很多關于數據庫的內部結構、JDBC、JPA、Hibernate以及很多優化商業應用...
摘要:忽略該字段的映射省略創建數據訪問層接口,需要繼承,第一個泛型參數是實體對象的名稱,第二個是主鍵類型。 SpringBoot 是為了簡化 Spring 應用的創建、運行、調試、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規范,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 上一篇介紹了Spring JdbcTempl...
摘要:導讀源碼地址公司的持久層采用的框架,這也是很多公司使用的一種持久層框架。配置文件本項目以為開發環境和以搭建的,分為包和包。一種是,這種是手動提交事務。返回結果分為兩種,一種是以實體類直接返回,調用方法。 導讀 源碼地址 公司的持久層采用的hibernate框架,這也是很多公司使用的一種持久層框架。它將瞬時態的javabean對象轉化為持久態數據表的字段對象、或將持久態的字段對象轉化為瞬...
閱讀 1317·2021-11-24 10:24
閱讀 4147·2021-11-22 15:29
閱讀 1088·2019-08-30 15:53
閱讀 2794·2019-08-30 10:54
閱讀 1983·2019-08-29 17:26
閱讀 1287·2019-08-29 17:08
閱讀 608·2019-08-28 17:55
閱讀 1583·2019-08-26 14:01