四、HQLjava
一、基本查詢sql
一、不帶條件的查詢數組
session = HibernateUtil.openSession(); //對於HQL而言,都是基於對象進行查詢的 Query<Special> query = session.createQuery("from Special",Special.class); List<Special> spes = query.getResultList(); for(Special spe:spes) { System.out.println(spe.getName()); }
try { session = HibernateUtil.openSession(); //對於HQL而言,都是基於對象進行查詢的 //不能使用select * 進行查詢 // Query<Special> query = session.createQuery("select * from Special",Special.class); //可使用鏈式查詢的方式 List<Special> spes = session.createQuery("select spe from Special spe", Special.class) .getResultList(); for(Special spe:spes) { System.out.println(spe.getName()); }
二、帶條件的查詢session
session = HibernateUtil.openSession(); /** * 帶條件的查詢 * 若是直接在代碼中加條件可能存在SQL注入攻擊,通常不使用這種方式傳條件 * 和sql差很少,也是使用where加條件 */ List<Student> stus = session.createQuery("from Student where name like '%王%'", Student.class) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
三、經過參數進行查詢函數
session = HibernateUtil.openSession(); /** * 使用參數進行查詢 * 基於?的條件的查詢,特別注意:jdbc設置參數的最小下標是1,Hibernate是0 * 查詢方法和JDBC相似,特別注意下標從0開始 */ List<Student> stus = session.createQuery("from Student where name like ?", Student.class) .setParameter(0, "%張%") .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
四、經過命名參數進行查詢this
session = HibernateUtil.openSession(); /** * 還能夠基於別名進行查詢,使用:xxx來講明別名的名稱 * HQL支持鏈操做 */ List<Student> stus = session.createQuery("from Student where name like :name and sex=:sex", Student.class) .setParameter("name", "%張%") .setParameter("sex", "男") .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
五、查詢空(null)元素hibernate
session = HibernateUtil.openSession(); /** * 查詢null元素,最好使用is null,(雖然可使用=null,可是不建議使用) */ List<Student> stus = session.createQuery("from Student where classroom is null", Student.class) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
二、經常使用查詢ssr
一、列表查詢(in ())code
session = HibernateUtil.openSession(); /** * 在HQL中也支持in查詢,正常的查詢通常都是會傳遞一個列表或者數組 * 此時就必須使用參數命名查詢 * 這種方式在權限控制中是常常使用的 * 特別注意:參數設置是setParameterList,參數值new Integer[]{1,2}必須是一個Collection或者Object[] */ List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.id in (:clas)", Student.class) .setParameterList("clas", new Integer[]{1,2}) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
二、投影查詢對象
session = HibernateUtil.openSession(); /** * 基於投影的查詢,經過在列表中存儲一個對象的數組 * 對象數組的第一個元素就是第一個投影的值... */ List<Object[]> stus = session.createQuery("select stu.sex,count(*) from Student stu group by stu.sex", Object[].class) .getResultList(); for(Object[] obj:stus) { System.out.println(obj[0]+":"+obj[1]); }
三、投影一個元素查詢(注意:不能使用select * 來查詢)
Session session = null; try { session = HibernateUtil.openSession(); /** * 使用getSingleResult()能夠返回惟一的一個值 * 查詢count(*),只有一個元素時就不是對象數組了,若是是count就是Long類型的值 */ Long stus = session.createQuery("select count(*) from Student where classroom is null", Long.class) .getSingleResult(); System.out.println(stus);
四、投影其它類型
session = HibernateUtil.openSession(); /** * 使用getSingleResult()能夠返回惟一的一個值 * 查詢一個投影,一個投影也不是對象數組 * stu是Student類型的值 */ Student stu = session.createQuery("select stu from Student stu where id=:id", Student.class) .setParameter("id", 1) .getSingleResult(); System.out.println(stu.getName());
五、單個元素查詢(getSingleResult())
session = HibernateUtil.openSession(); /** * 若是查詢出來的數據只有一條記錄可使用getSingleResult()來查詢 * 特別注意不能使用select * */ Student stu = session.createQuery("select stu from Student stu where id=:id", Student.class) .setParameter("id", 1) .getSingleResult(); System.out.println(stu.getName()); session = HibernateUtil.openSession(); /** * 若是要查詢count也可使用getSingleResult() */ Long stus = session.createQuery("select count(*) from Student where classroom is null", Long.class) .getSingleResult(); System.out.println(stus);
六、分頁查詢
session = HibernateUtil.openSession(); /** * 使用setFirstResult和setMaxResults能夠完成分頁的offset和pageSize的設置 */ List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.id in (:clas)", Student.class) .setParameterList("clas", new Integer[]{1,2}) .setFirstResult(0).setMaxResults(15) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
七、導航查詢(詳見3.2:對象導航鏈接)
/** * 若是對象中存在相應的導航對象,能夠直接導航完成查詢 */ List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.name=? and stu.name like ?", Student.class) .setParameter(0, "計算機教育班").setParameter(1, "%張%") .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
三、鏈接查詢
3.一、基於SQL的查詢
鏈接的三種方式:
一、內鏈接(鏈接的兩張表都有數據的鏈接)
SELECT * FROM t_stu t1 JOIN t_classroom t2 ON(t1.cid=t2.id)
以上獲得的數據是t_stu和t_classroom中都有的數據。
二、左外鏈接
SELECT * FROM t_classroom t1 LEFT JOIN t_stu t2 ON(t1.id=t2.cid)
以上獲得的結果是左邊這張表的全部數據來鏈接右邊這張表的數據,若是右表沒有數據,會直接使用
null來填充,這種在作統計時很是有用。
SELECT t1.name,COUNT(t2.id) FROM t_classroom t1 LEFT JOIN t_stu t2 ON (t1.id=t2.cid) GROUP BY t1.id /* * COUNT(t2.id):必須是第二張表單的id,此時爲null的值就會統計出0 * 根據t1.id進行分組,其實也就等於根據班級進行分組 * 以上實現了某一個班的人數的統計 */
三、右外鏈接
SELECT * FROM t_classroom t1 RIGHT JOIN t_stu t2 ON(t1.id=t2.cid)
以上獲得的是右表的全部數據,若是左表沒有,就使用null來填充。
3.二、基於Hibernate的鏈接查詢
一、使用對象導航鏈接(比較方便的一種操做方式),侷限:只是內鏈接。
/** * 在Hibernate中能夠直接使用對象的導航語句來完成查詢 * 這種方式稱爲內部鏈接查詢。 * 使用的是內鏈接。 * stu.classroom.name=?:使用對象導航來完成鏈接,此時等於內鏈接 * */ List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.name=? and stu.name like ?", Student.class) .setParameter(0, "計算機教育班").setParameter(1, "%張%") .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
二、使用鏈接操做方式
session = HibernateUtil.openSession(); /** * 在Hibernate中也能夠直接使用join來查詢 * 這種方式能夠直接選擇是使用left join仍是right join或者join * 如下方式使用的內鏈接 * 此處若是不寫投影(stu),默認會將兩個對象都查詢出來,獲得的結果就是Object[] * 若是但願查詢某個對象,須要指明投影 * stu:必須指明投影對象,否則就是全部鏈接對象的投影數組 * join stu.classroom cla:不使用on,直接鏈接導航對象 */ List<Student> stus = session.createQuery("select stu from Student stu join stu.classroom cla where cla.id=2", Student.class) .setFirstResult(0).setMaxResults(15) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
三、使用左鏈接(和sql徹底一致)
session = HibernateUtil.openSession(); /** * 在Hibernate中也能夠直接使用join來查詢 * 這種方式能夠直接選擇是使用left join仍是right join或者join * 使用left join */ List<Student> stus = session.createQuery("select stu from Student stu left join stu.classroom cla where cla.id=2", Student.class) .setFirstResult(0).setMaxResults(15) .getResultList(); for(Student stu:stus) { System.out.println(stu.getName()); }
四、使用右鏈接
session = HibernateUtil.openSession(); /** * 在Hibernate中也能夠直接使用join來查詢 * 這種方式能夠直接選擇是使用left join仍是right join或者join * 使用right join */ List<Object[]> stus = session.createQuery("select cla.name,count(stu.classroom.id) from Student stu right join stu.classroom cla group by cla.id", Object[].class) .getResultList(); for(Object[] stu:stus) { System.out.println(stu[0]+","+stu[1]); }
五、使用DTO對象鏈接查詢
建立DTO對象:
/** * DTO對象沒有存儲的意義,僅僅是用來進行數據的傳輸的 * @author PM * */ public class StudentDto { private int sid; private String sname; private String sex; private String cname; private String spename; public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public String getSpename() { return spename; } public void setSpename(String spename) { this.spename = spename; } public StudentDto(int sid, String sname, String sex, String cname, String spename) { super(); this.sid = sid; this.sname = sname; this.sex = sex; this.cname = cname; this.spename = spename; } public StudentDto() { }
使用new XXXObject完成查詢:
session = HibernateUtil.openSession(); /** * 直接可使用new XXXObject完成查詢,注意,必定要加上Object的完整包名 * 這裏使用的new XXX,必須在對象中加入相應的構造函數 */ List<StudentDto> stus = session.createQuery("select new org.pm.hibernate.model.StudentDto " + "(stu.id as sid,stu.name as sname,stu.sex as sex,cla.name as cname,spe.name as spename) " + "from Student stu left join stu.classroom cla left join cla.special spe", StudentDto.class) .getResultList(); for(StudentDto stu:stus) { System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex()+","+stu.getCname()+","+stu.getSpename()); }
六、分組查詢
session = HibernateUtil.openSession(); /** * having是爲group來設置條件的 */ List<Object[]> stus = session.createQuery("select spe.name,count(stu.classroom.special.id) from " + "Student stu right join stu.classroom.special spe " + "group by spe having count(stu.classroom.special.id)>150", Object[].class) .getResultList(); for(Object[] stu:stus) { System.out.println(stu[0]+","+stu[1]); }
session = HibernateUtil.openSession(); /** * 分組查詢 */ List<Object[]> stus = session.createQuery("select stu.sex,spe.name,count(stu.classroom.special.id) from " + "Student stu right join stu.classroom.special spe " + "group by spe,stu.sex", Object[].class) .getResultList(); for(Object[] stu:stus) { System.out.println(stu[0]+","+stu[1]+","+stu[2]); }