Hibernate:查詢
本文內容
- OID查詢
- 對象導航查詢
- HQL查詢
- QBC查詢
- SQL查詢
首發日期:2018-07-31
hibernate的查詢方式:
hibernate有很多查詢方式
- 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語句。
而且,get對於不存在的對象的查詢返回的是null,load會報錯。
對象導航查詢
對象導航查詢:利用對象之間的關系來獲取【前提--對象之間建立了關系,比如給某個學生選擇了班級,那麽就可以通過這個學生來查詢到班級,而無法通過這個學生查詢到沒有跟他綁定的班級】
- 使用方法:利用對象的關系【參照例子幫助了解,以一對多關系為例。】
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相像,不過它的表名變成了類名,字段名變成了屬性名。
- 執行HQL查詢:Query query = session.createQuery(HQL語句);
- 獲取結果:query.list()【獲取結果集】、query.unique()【如果只查單行單列數據,用這個】
查詢所有:
HQL中的"from 類名"相當於SQL中的“select * from 表名”
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,不過它的排序條件是類的屬性名
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 類名後面,不過設置值的方法有三種:
- 直接設置
- 使用?占位,然後使用setParameter(下標,值)設置【不過好像一些版本不再支持這個】
- 使用: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,效果是把後面那個關聯持久類的內容封裝到前面那個類的實體中。
比如:
補充:
- 很多時候都要依靠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有
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); } }
Hibernate:查詢