【Hibernate】Hibernate的聚類查詢、分組查詢、排序與時間之差,hibernate聚類

來源:互聯網
上載者:User

【Hibernate】Hibernate的聚類查詢、分組查詢、排序與時間之差,hibernate聚類

在Hibernate中的HQL語句其實能夠基本能夠實現SQL語句所做的事情,正如jQuery至於javascript一樣。雖然HQL語句是對類的查詢,但是HQL在實行聚類查詢、分組查詢、排序與時間之差等查詢,也無須把查詢結果查詢出來,再通過對List的處理才得到結果。

比如有一張如下的Testtable表:


要像《【Mysql】求出離最近相差X天的項,sql語句關於日期的比對》(點擊開啟連結)一樣,查詢date欄位離現在具有30年的項有多少,SQL語句則這樣寫:

select count(*) from testtable where timestampdiff(year,date,now())<30;
其查詢結果如:


在Hibernate中的Java語句則如下實現,同時這樣輸出:

String hql="select count(*) from Testtable t where timestampdiff(year,t.date,now())<30"String result=session.createQuery(hql).uniqueResult().toString();System.out.println(result);
這裡利用了純粹的HQL查詢,同時返回結果唯一。省略Hibernate的初始化與配置等。

直接利用uniqueResult()的方法即可。

如果,查詢結果是多行的情況,比如還是對剛才的Testtable表進行查詢,

這次查詢的是在《【Mysql】利用group by附帶having進行聚類查詢》(點擊開啟連結)查詢過的,在username出現次數多於1次,不含1次的項,並且降序排列,那麼sql語句則這樣寫:

select username,count(*) from testtablegroup by username having coutn(*)>1order by count(*) desc
其查詢結果如:


在Hibernate中的Java程式則如下寫,關鍵是把查詢結果的每一行轉化成Object數組,則對Object數組的每一項進行強制類型的轉化,則可以完成處理:

String hql="SELECT t.username,count(*) FROM Testtable t group by t.username having count(*)>1 order by count(*) desc"List<Object> resultList = session.createQuery(hql).list();for (int i = 0; i < resultList.size(); i++) {Object[] obj = (Object[])resultList.get(i);System.out.println(obj[0]+","+obj[1]);}
這裡利用了純粹的HQL查詢,也省略Hibernate的初始化與配置等。如果你要利用到查詢結果做後續工作,

則可以,這樣處理:

String username=(String)obj[0];


可以看出,HQL語句其實與SQL沒有什麼差別,SQL的所有關鍵字在HQL裡面都是存在的,只是有少許改變,

關鍵是,在要查詢的類中,後面補一個替換名稱,比如Testtable就替換為t,就可以順利操作了。

上述省略整個HQL初始化與布置的過程,具體請看《【Hibernate】Hibernate的層次劃分,Hibernate4.3的初始化的新寫法》(點擊開啟連結),不再贅述。

其中,這裡的目錄結構是這樣的:


其中,

dbDAO.java,資料庫業務類,一字未改,多次複用:

import org.hibernate.*;import org.hibernate.cfg.*;import org.hibernate.service.*;import org.hibernate.boot.registry.*;public class dbDAO {private Session session;// 建構函式,初始化Session,相當於串連資料庫public dbDAO() {//這裡使用了Hibernate4.3.8的寫法,這裡Hibernate又把初始化的方法修改了,非常蛋疼Configuration cfg = new Configuration().configure();ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);this.session = sessionFactory.openSession();}// 執行查詢public Query query(String hql){return session.createQuery(hql);}// 執行插入、修改public void save(Object object){Transaction transaction=session.beginTransaction();  session.save(object);transaction.commit(); }// 執行刪除public void delete(Object object){Transaction transaction=session.beginTransaction(); session.delete(object);transaction.commit(); }// 解構函式,中斷Session,相當於中斷資料庫的串連protected void finalize() throws Exception {if (session.isConnected() || session != null) {session.close();}}}
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.password">admin</property><!--所用的資料庫名稱為test,根據實際更改 --><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property><!--所用的資料庫使用者名稱  --><property name="hibernate.connection.username">pc</property><!--所用的資料庫方言,與所用資料庫驅動一樣,可以在網上查到,這裡是mysql --><property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property><property name="hibernate.format_sql">true</property><!--如果是update表明Hibernate將保留原來的資料記錄,插入時把新記錄添加到已有的表,--><!--如果是create,則總是建立新的表,如果原來資料庫已有的這個表,則這個表的記錄會被全部清洗  --><property name="hibernate.hbm2ddl.auto">update</property><!--羅列Testtable表與Java檔案的映射,這裡就Testtable.java的一張表,所以就寫一個Testtable.java  --><mapping class="Testtable" /></session-factory></hibernate-configuration>
Testtable.java,資料庫持久化類的內容如下,只是把資料庫中的testtable表的所有東西映射過來:

import javax.persistence.*;@Entity@Table(name = "testtable")public class Testtable {private int id;private String username;private String number;private String date;// 表示主鍵與自動產生項@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}@Column(name = "username")public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}@Column(name = "number")public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}@Column(name = "date")public String getDate() {return date;}public void setDate(String date) {this.date = date;}@Overridepublic String toString() {return id + "," + username + "," + number + "," + date;}}
最關鍵的是控制層方法實作類別,HQL.java,就是把上面所介紹的Hibernate的聚類查詢、分組查詢、排序與時間之差查詢利用dbDAO.java的封裝,一一實現:

import java.util.*;@SuppressWarnings("unchecked")public class HQL {public static void main(String[] args) {// 建立DAO類dbDAO db = new dbDAO();// 如果傳回值是唯一的,則用uniqueResult()方法String result = db.query("select count(*) from Testtable t where timestampdiff(year,t.date,now())<30").uniqueResult().toString();System.out.println(result);System.out.println();// 排序與聚類查詢(分組查詢)List<Object> resultList = db.query("SELECT t.username,count(*) FROM Testtable t group by t.username having count(*)>1 order by count(*) desc").list();for (int i = 0; i < resultList.size(); i++) {Object[] obj = (Object[]) resultList.get(i);System.out.println(obj[0] + "," + obj[1]);}}}
運行結果如:


相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.