Hibernate:查詢


本文內容

  • OID查詢
  • 對象導航查詢
  • HQL查詢
  • QBC查詢
  • SQL查詢

 

首發日期:2018-07-31sql


hibernate的查詢方式:

hibernate有不少查詢方式session

  • OID查詢
  • 對象導航查詢:
  • HQL查詢:
  • QBC查詢:
  • SQL查詢:

OID查詢:

OID查詢:基於惟一標識屬性(主鍵)來查詢函數

  • 使用方法:session.get(持久類.class,主鍵值)或session.load(持久類.class,主鍵值)
public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Person p1 = session.get(Person.class, 1L);//由於我用的是Long,因此這裏給個1L
        Person p2 = session.load(Person.class, 2L);//不會當即發生sql語句
        System.out.println(p1);
        System.out.println(p2);//這裏才發送p2的查詢
    }

 

 

get和load的區別:

load是延遲加載的,意思是當調用load的時候,並不當即發送SQL語句,只有當使用了這個對象的時候纔去發送SQL語句。fetch

並且,get對於不存在的對象的查詢返回的是null,load會報錯。ui

 

 


對象導航查詢

對象導航查詢:利用對象之間的關係來獲取【前提--對象之間創建了關係,好比給某個學生選擇了班級,那麼就能夠經過這個學生來查詢到班級,而沒法經過這個學生查詢到沒有跟他綁定的班級】spa

  • 使用方法:利用對象的關係【參照例子幫助瞭解,以一對多關係爲例。】
public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Student student = session.get(Student.class, 1L);
        Grade grade = student.getGrade();
        System.out.println(grade);
        Grade grade2 = session.get(Grade.class, 1L);
        for (Student s : grade2.getStudents()) {
            System.out.println(s);
        }
        
    }

 

 


HQL查詢:

HQL是hibernate版本的SQL語句,HQL與SQL相像,不過它的表名變成了類名,字段名變成了屬性名。hibernate

  • 執行HQL查詢:Query query = session.createQuery(HQL語句);
  • 獲取結果:query.list()【獲取結果集】、query.unique()【若是隻查單行單列數據,用這個】

 

查詢全部:

HQL中的"from 類名"至關於SQL中的「select * from 表名」code

public void test3() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student ");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }
        
    }

 

別名查詢

HQL中也給能夠給類名指定一個別名。對象

public void test4() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select s from Student s ");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }

 

排序查詢:

HQL的排序查詢也相似於SQL,不過它的排序條件是類的屬性名blog

public void test5() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student order by id desc");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }

 

條件查詢:

HQL的條件查詢也相似於SQL,不過它的條件中字段名是類的屬性名

條件都是跟在from 類名後面,不過設置值的方法有三種:

  1. 直接設置
  2. 使用?佔位,而後使用setParameter(下標,值)設置【不過好像一些版本再也不支持這個】
  3. 使用:XXX佔位,而後是setParameter(XXX,值)設置
public void test6() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //方式1
//        Query query = session.createQuery("from Student where id = 1");
        //方式2
//        Query query = session.createQuery("from Student where name = ?");
//        query.setParameter(0, "李白");
        //方式3
        Query query = session.createQuery("from Student where id = :aaa");
        query.setParameter("aaa", 1L);
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }
    }

 

 

投影查詢:

投影查詢就是查詢對象的某個或某些屬性,這個用法與SQL基本相同。不過這個時候使用query.list得出的結果是Object類型的。

public void test7() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select name from Student");
        List<Object> list = query.list();
        //若是你的Student有合適參數的構造函數,那麼你能夠這樣用,這會幫你封裝到對象中,返回的也是Student對象
//        Query query = session.createQuery("select new Student(id,name) from Student");
//        List<Student> list = query.list();
        
        for(Object s :list) {
            System.out.println(s);
        }
    }

 

 

分頁查詢:

HQL分頁查詢的核心函數是setMaxResult(一頁顯示的條數),setFirstResult(第一條記錄的索引值)

public void test8() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student");
        query.setMaxResults(3);
        query.setFirstResult(0);
        List<Student> list = query.list();
        
        for(Student s :list) {
            System.out.println(s);
        }
    }

 

 

分組統計查詢:

HQL分組統計查詢與SQL的分組統計查詢的語法相相似。

public void test9() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select count(*) from Student group by grade");//這樣得出的是Object[]類型的數據
        List<Object > list = query.list();
        
        for(Object o :list) {
            System.out.println(o);
        }
    }

 

 

多表查詢:

HQL的多表查詢有幾個不一樣

1.它不是使用表名,它使用持久類的類名

2.它可使用映射外鍵,好比:from Student s inner join Grade g on s.grade=g.id

3.使用持久類的類名以後,它能夠直接利用關聯關係來進行鏈接,例如:from Student s inner join s.grade

public void test10() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //內鏈接
//        Query query = session.createQuery("from Student s inner join s.grade");//這樣得出的是Object[]類型的數據
//        Query query = session.createQuery("from Student s inner join Grade g on s.grade=g.id");//這樣得出的是Object[]類型的數據
//        List<Object[] > list = query.list();
//        for(Object[] o :list) {
//            System.out.println(Arrays.toString(o));
//        }
        //左外鏈接
//        Query query = session.createQuery("from Student s left  join s.grade");//這樣得出的是Object[]類型的數據
//        Query query = session.createQuery("from Student s left  join Grade g on s.grade=g.id");//這樣得出的是Object[]類型的數據
//        List<Object[] > list = query.list();
//        for(Object[] o :list) {
//            System.out.println(Arrays.toString(o));
//        }
        //右外鏈接差很少,這裏不講了
    }

 

多表查詢中有兩個特殊的鏈接:迫切內鏈接和迫切左外鏈接。當利用關聯關係來鏈接的時候,在後面那個關聯以前加個fetch,效果是把後面那個關聯持久類的內容封裝到前面那個類的實體中。

好比:

image

 

補充:

  • 不少時候都要依靠query.list()來獲取結果,那麼怎麼判斷返回的結果是什麼類型的呢?
    • 查詢結果是單列的時候,是Object
    • 查詢結果是一個個持久類對象的時候,返回的是持久類
    • 查詢結果是多列數據,並且不全是某個持久類的全部數據的時候,返回的是Object[]


QBC查詢

  • QBC(Query By Criteria)查詢是面向對象的查詢
  • 使用方法:Criteria criteria = session.createCriteria(持久類.class);
  • 獲取結果: criteria.list();

 

 

查詢全部:

 

public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }

 

排序查詢:

在查詢全部的基礎上,調用criteria.addOrder()來進行排序,參數Order.desc(根據哪一個字段排序)、Order.asc(根據哪一個字段排序)

public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.addOrder(Order.desc("id"));
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

條件查詢:

在查詢全部的基礎上,調用criteria.add()來增長條件,參數是Restrictions.xxx

Restrictions.xxx經常使用的有

Restrictions.eq(屬性名,值):至關於條件 where 字段名 =值

Restrictions.gt(屬性名,值):至關於條件 where 字段名 >值

Restrictions.ge(屬性名,值):至關於條件 where 字段名 >=值

Restrictions.lt(屬性名,值):至關於條件 where 字段名 <值

Restrictions.in(屬性名,集合):至關於條件 where 字段名 in 值

默認狀況下,增長的每個都是與的條件,要想添加或的條件,要使用Restrictions.or(多個Restrictions.xxxx),這樣裏面的條件都是或的了。

public void test4() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("name", "李白"));
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

分頁查詢:

criteria調用setFirstResult(第一條記錄的索引),調用setMaxResults(一頁顯示的數量)來進行分頁。

public void test3() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.setFirstResult(0);//第一條記錄的索引
        criteria.setMaxResults(3);//一頁顯示多少
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

統計查詢:

criteria調用setProjection(Projections.XXX)來進行統計查詢

Projections.XXX有

image

public void test5() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.setProjection(Projections.rowCount());
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        
    }

 

補充:

  • QBC中還有個離線條件查詢DetachedCriteria,這裏暫時不講,之後有空再加上。

 


SQL查詢

SQL查詢就是直接使用SQL語句來查詢

進行查詢:SQLQuery sqlQuery = session.createSQLQuery(SQL語句)

獲取結果:sqlQuery.list()

 

相信你是已經學過SQL語句的。因此這裏就給出怎麼用,不詳細介紹各類查詢了。

直接使用的時候,返回結果是一個個Object[]

public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //發現提示用法過時了,不過仍是介紹一下
        SQLQuery sqlQuery = session.createSQLQuery("select * from student");
        List<Object[] > list = sqlQuery.list();
        for(Object[] o:list) {
            System.out.println(Arrays.toString(o));
        }
    }
但可使用sqlQuery.addEntity(持久類.class)來把數據封裝到對象中;
public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //發現提示用法過時了,不過仍是介紹一下
        SQLQuery sqlQuery = session.createSQLQuery("select * from student");
        sqlQuery.addEntity(Student.class);
        List<Student > list = sqlQuery.list();
        for(Student s:list) {
            System.out.println(s);
        }
    }
相關文章
相關標籤/搜索