成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Hibernate【查詢、連接池、逆向工程】

ZoomQuiet / 579人閱讀

摘要:因此,需要我們自己添加如果需要更新,如果想要體現(xiàn)對應(yīng)的關(guān)聯(lián)關(guān)系的話,請參考該博文如果文章有錯的地方歡迎指正,大家互相交流。

前言

在Hibernate的第二篇中只是簡單地說了Hibernate的幾種查詢方式....到目前為止,我們都是使用一些簡單的主鍵查詢阿...使用HQL查詢所有的數(shù)據(jù)....本博文主要講解Hibernate的查詢操作,連接池,逆向工程的知識點...

get/load主鍵查詢

由于主鍵查詢這個方法用得比較多,于是Hibernate專門為我們封裝了起來...

get()立即查詢

load()懶加載

對象導(dǎo)航查詢

如果對象與對象之前存在一對多、多對一的關(guān)系的時候

在以前SQL查詢的時候:我們?nèi)绻?strong>想要得到當(dāng)前對象與另一對象的關(guān)聯(lián)關(guān)系的時候,就必須用多表查詢來得到數(shù)據(jù)

Hibernate提供了對象導(dǎo)航查詢:我們可以使用主鍵查詢完之后,得到的對象,直接使用對象得到集合...就可以得到對應(yīng)的數(shù)據(jù)了。

        // 對象導(dǎo)航查詢
        Dept dept =  (Dept) session.get(Dept.class, 12);
        System.out.println(dept.getDeptName());

        //這里就可以得到部門對應(yīng)的所有員工
        System.out.println(dept.getEmps());
HQL查詢

Hibernate的前面章節(jié)中已經(jīng)講解過了基本的概念了。在這里我們就直接看看怎么使用了。

值得注意的是:

在hbm.xml文件中的auto-import="true" 要設(shè)置true。當(dāng)然了,默認(rèn)值就是ture

如果是false,寫hql的時候,要指定類的全名

查詢?nèi)苛?/b>
    //方式一:直接寫對象
    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查詢指定的列,返回的是對象數(shù)組Object[]

        //只查詢name和eatBanana列
        Query query = session.createQuery("select m.name,m.eatBanana from Monkey m");
        System.out.println(query.list());

封裝對象

前面測試了查詢指定的列的時候,返回的是對象數(shù)組...可是對象數(shù)組我們不好操作啊...Hibernate還提供了將對象數(shù)組封裝成對象的功能

JavaBean要有對應(yīng)的構(gòu)造函數(shù)

        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());

命名參數(shù)

HQL還支持命名參數(shù)查詢!下面我們來看一下怎么用:

語法::命名

        Query query = session.createQuery("from Monkey m where m.name=:monkeyName");
        //HQL是從0開始的
        query.setParameter("monkeyName", "大猴子");
        System.out.println(query.list());

范圍查詢

范圍查詢就是使用between and關(guān)鍵字來查詢特定范圍的數(shù)據(jù)。。和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關(guān)鍵字進(jìn)行查詢,和SQL也是一樣的。

%號要寫在參數(shù)上,不能寫帶SQL上!

        //模糊
        Query q = session.createQuery("from Dept d where deptName like ?");
        q.setString(0, "%部%");
        System.out.println(q.list());
聚合函數(shù)統(tǒng)計

我們也經(jīng)常會查詢數(shù)據(jù)庫中一共有多少條記錄這樣的需求。那么在HQL中怎么用呢?

HQL提供了uniqueResult()這么一個方法,返回只有一條記錄的數(shù)據(jù)

        Query query = session.createQuery("select COUNT(*) from Monkey");
        Object o = query.uniqueResult();
        System.out.println(o);

分組查詢

分組查詢和SQL是一樣的...

        //-- 統(tǒng)計t_employee表中,每個部門的人數(shù)
        //數(shù)據(jù)庫寫法: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());
連接查詢

連接查詢也就是多表查詢...多表查詢有三種

內(nèi)連接【等值連接】

左外連接

有外鏈接

值得注意的是:連接查詢返回的也是對象數(shù)組!

        //1) 內(nèi)連接   【映射已經(jīng)配置好了關(guān)系,關(guān)聯(lián)的時候,直接寫對象的屬性即可】
        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();
        
迫切連接

由于連接查詢返回的是對象數(shù)組,我們使用對象數(shù)組來操作的話會很不方便...既然是連接查詢,那么對象與對象是肯定有關(guān)聯(lián)關(guān)系的...于是乎,我們想把左表的數(shù)據(jù)填充到右表中,或者將右表的數(shù)據(jù)填充到左表中...使在返回的時候是一個對象、而不是對象數(shù)組!HQL提供了fetch關(guān)鍵字供我們做迫切連接

        //1) 迫切內(nèi)連接    【使用fetch, 會把右表的數(shù)據(jù),填充到左表對象中!】
        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是一種完全面向?qū)ο蟮牟樵?/strong>...

Criteria使用的是add()來添加條件。條件又使用一個Restrictions類來封裝

        Criteria criteria = session.createCriteria(Monkey.class);
        criteria.add(Restrictions.eq())

我們來簡單看一下Restrictions的方法:

都是一些大于、小于、等于之類的....Criteria查詢就使用不了分組、連接查詢了。

SQLQuery本地SQL查詢

有的時候,我們可能表的結(jié)構(gòu)十分復(fù)雜,如果使用關(guān)聯(lián)映射的話,配置文件是十分臃腫的...因此,我們并不是把全部的數(shù)據(jù)表都使用映射的方式來創(chuàng)建數(shù)據(jù)表...

這時,我們就需要用到SQLQuery來維護(hù)我們的數(shù)據(jù)了..

SQLQuery是不能跨數(shù)據(jù)庫的,因為Hibernate在配置的時候就指定了數(shù)據(jù)庫的“方言”...

        SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM monkey_ limit 0,3");

        System.out.println(sqlQuery.list());

返回的也是對象數(shù)組:

Hibernate也支持在SQLQuery中對數(shù)據(jù)進(jìn)行對象封裝..只要添加類型就行了

        SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM monkey_ limit 0,3").addEntity(Monkey.class);

        System.out.println(sqlQuery.list());

分頁查詢

傳統(tǒng)的SQL我們在DAO層中往往都是使用兩個步驟來實現(xiàn)分頁查詢

得到數(shù)據(jù)庫表中的總記錄數(shù)

查詢起始位置到末尾位數(shù)的數(shù)據(jù)

Hibernate對分頁查詢也有很好地支持,我們來一下:

        Query query = session.createQuery("from Monkey");

        //得到滾動結(jié)果集
        ScrollableResults scroll = query.scroll();
        //滾動到最后一行
        scroll.last();
        int i = scroll.getRowNumber() + 1;
        System.out.println("總計路數(shù):" + i);

        //設(shè)置分頁位置
        query.setFirstResult(0);
        query.setMaxResults(3);

        System.out.println(query.list());

提供了方法讓我們設(shè)置起始位置和結(jié)束位置

提供了ScrollableResults來得到滾動結(jié)果集,最終得到總記錄數(shù)

值得注意的是,滾動結(jié)果集是從0開始的,因此需要+1才可得到總記錄數(shù)!

如果我們們使用的是SELECT COUNT(*) FROM 實體,我們可以通過uniqueResult()方法獲取數(shù)據(jù)的唯一記錄,得到的數(shù)據(jù)轉(zhuǎn)換成Long類型即可。

    Long totalRecord = (Long) queryCount.uniqueResult();
Hibernate連接池

Hibernate自帶了連接池,但是呢,該連接池比較簡單..而Hibernate又對C3P0這個連接池支持...因此我們來更換Hibernate連接池為C3P0

查看Hibernate自帶的連接池

我們可以通過Hibernate.properties文件中查看Hibernate默認(rèn)配置的連接池

hibernate.properties的配置文件可以在projectetc找到

Hibernate的自帶連接池啥都沒有,就一個連接數(shù)量為1...

查看Hibernate對C3P0的支持

hibernate.c3p0.max_size 2 最大連接數(shù)

hibernate.c3p0.min_size 2 最小連接數(shù)

hibernate.c3p0.timeout 5000 超時時間

hibernate.c3p0.max_statements 100 最大執(zhí)行的命令的個數(shù)

hibernate.c3p0.idle_test_period 3000 空閑測試時間

hibernate.c3p0.acquire_increment 2 連接不夠用的時候, 每次增加的連接數(shù)

hibernate.c3p0.validate false

修改Hibernate連接池

我們在hibernate.cfg.xml中配置C3p0,讓C30P0作為Hibernate的數(shù)據(jù)庫連接池

查找Hibernate支持的連接池組件有什么

既然找到了,那么我們在hibernate.cfg.xml中配置對應(yīng)的類就和相關(guān)配置就行了

        
        
        org.hibernate.connection.C3P0ConnectionProvider
        
        2
        4
        5000
        10
        30000
        2
線程Session使用

我們創(chuàng)建Session的時候,有兩個方法

openSession()【每次都會創(chuàng)建新的Session】

getCurrentSession()【獲取當(dāng)前線程的Session,如果沒有則創(chuàng)建】

一般地,我們使用線程Session比較多

如果要使用getCurrentSession(),需要在配置文件中配置:

        
        thread
測試數(shù)據(jù)
@Test
    public void testSession() throws Exception {
        //openSession:  創(chuàng)建Session, 每次都會創(chuàng)建一個新的session
        Session session1 = sf.openSession();
        Session session2 = sf.openSession();
        System.out.println(session1 == session2);
        session1.close();
        session2.close();
        
        //getCurrentSession 創(chuàng)建或者獲取session
        // 線程的方式創(chuàng)建session  
        // 一定要配置:thread
        Session session3 = sf.getCurrentSession();// 創(chuàng)建session,綁定到線程
        Session session4 = sf.getCurrentSession();// 從當(dāng)前訪問線程獲取session
        System.out.println(session3 == session4);
        
        // 關(guān)閉 【以線程方式創(chuàng)建的session,可以不用關(guān)閉; 線程結(jié)束session自動關(guān)閉】
        //session3.close();
        //session4.close(); 報錯,因為同一個session已經(jīng)關(guān)閉了!
    }
為什么要使用逆向工程

由于我們每次編寫Hibernate的時候都需要寫實體,寫映射文件。而且Hibernate的映射文件也容易出錯。而逆向工程可以幫我們自動生成實體和映射文件,這樣就非常方便了。

使用PowerDesigner

在設(shè)計數(shù)據(jù)庫表時,我們使用PowerDesigner來生成概念模型物理模型...

設(shè)計一個人員組織架構(gòu):有機(jī)構(gòu)、部門、員工、領(lǐng)導(dǎo)、角色、權(quán)限。

一個機(jī)構(gòu)有多個部門

一個部門有多個員工

領(lǐng)導(dǎo)可以管理多個部門,同時領(lǐng)導(dǎo)他自己也是員工

一個員工可以有多個角色

一個角色可以分配給多個人

人員角色分配后可以設(shè)置是否有效,分配時間等

一個角色有多個權(quán)限

概念模型:

在PowerDesigner中,箭頭指向的方向永遠(yuǎn)是“一”的一方

生成物理模型:

最后生成物理模型是這樣子的:

生成sql語句

我們可以單個生成,一個一個復(fù)制

也可以把整個物理模型的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;

在數(shù)據(jù)庫生成八張表:

在Idea下使用Hibernate逆向工程

值得注意的是:Intellij idea下生成出來的映射文件是沒有對應(yīng)的關(guān)聯(lián)關(guān)系的。也就是說:一對多或多對多的關(guān)系,它是不會幫你自動生成的【好像是這樣子的】。。。因此,需要我們自己添加Set【如果需要】

更新,如果想要體現(xiàn)對應(yīng)的關(guān)聯(lián)關(guān)系的話,請參考該博文!

https://my.oschina.net/wangyu...

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68711.html

相關(guān)文章

  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評論0 收藏0
  • 納稅服務(wù)系統(tǒng)【總結(jié)】

    摘要:要是使用到日歷的話,我們想到使用這個日歷類上面僅僅是我個人總結(jié)的要點,如果有錯誤的地方還請大家給我指正。 納稅服務(wù)系統(tǒng)總結(jié) 納稅服務(wù)系統(tǒng)是我第一個做得比較大的項目(不同于javaWeb小項目),該項目系統(tǒng)來源于傳智Java32期,十天的視頻課程(想要視頻的同學(xué)關(guān)注我的公眾號就可以直接獲取了) 我跟著練習(xí)一步一步完成需求,才發(fā)覺原來Java是這樣用來做網(wǎng)站的,Java有那么多的類庫,頁面...

    ispring 評論0 收藏0
  • 構(gòu)建高性能Java持久層的14個建議

    摘要:系列文章地址原文地址一個高性能的數(shù)據(jù)訪問層需要很多關(guān)于數(shù)據(jù)庫的內(nèi)部結(jié)構(gòu)以及很多優(yōu)化商業(yè)應(yīng)用的技術(shù)建議。在語句中的表現(xiàn)最好,不過不能使用約束,數(shù)據(jù)完整性的控制較差。應(yīng)用層的緩存則利用高速副本的方式來保證低響應(yīng)時間。 Github系列文章地址 原文地址 Introduction 一個高性能的數(shù)據(jù)訪問層需要很多關(guān)于數(shù)據(jù)庫的內(nèi)部結(jié)構(gòu)、JDBC、JPA、Hibernate以及很多優(yōu)化商業(yè)應(yīng)用...

    shenhualong 評論0 收藏0
  • 一起來學(xué)SpringBoot | 第六篇:整合SpringDataJpa

    摘要:忽略該字段的映射省略創(chuàng)建數(shù)據(jù)訪問層接口,需要繼承,第一個泛型參數(shù)是實體對象的名稱,第二個是主鍵類型。 SpringBoot 是為了簡化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問題而誕生的產(chǎn)物,自動裝配的特性讓我們可以更好的關(guān)注業(yè)務(wù)本身而不是外部的XML配置,我們只需遵循規(guī)范,引入相關(guān)的依賴就可以輕易的搭建出一個 WEB 工程 上一篇介紹了Spring JdbcTempl...

    Dionysus_go 評論0 收藏0
  • 模仿hibernate框架,詳解hibernate部分方法設(shè)計

    摘要:導(dǎo)讀源碼地址公司的持久層采用的框架,這也是很多公司使用的一種持久層框架。配置文件本項目以為開發(fā)環(huán)境和以搭建的,分為包和包。一種是,這種是手動提交事務(wù)。返回結(jié)果分為兩種,一種是以實體類直接返回,調(diào)用方法。 導(dǎo)讀 源碼地址 公司的持久層采用的hibernate框架,這也是很多公司使用的一種持久層框架。它將瞬時態(tài)的javabean對象轉(zhuǎn)化為持久態(tài)數(shù)據(jù)表的字段對象、或?qū)⒊志脩B(tài)的字段對象轉(zhuǎn)化為瞬...

    王陸寬 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<