??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
?hibernate的reference 中提到过hql是可以直接用distinct?br />
--
关键字distinct与all 也可以用,它们h与SQL相同的语?
select distinct cat.name from Cat cat
select count(distinct cat.name), count(cat) from Cat cat
--
所?我就试使用
select distinct c.* from Column c, 在hql?使用 * 必须要用到别名的
查询出的l果?null来的.
在mysql ?q种写法是没有错?..然后我再试了一?br />
select distinct c from Column c , q样得出的结果是非null,是正的.
]]>
HQL中关键字是不区分大小写的Q但是属性和cd是区分大写的?br />
1>.单属性查?br />
1>).单一属性查?q回l果集属性列?元素cd和实体类中相应的属性类型一致。如Q?br />
session = HibernateUtils.getSession();
session.beginTransaction();
//q回l果集属性列表,元素cd和实体类中相应的属性类型一?br />
List students = session.createQuery("select name from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
session.getTransaction().commit();
2>).多个属性查?q回的集合元素是对象数组Q数l元素的cd和对
应的属性在实体cM的类型一_数组的长度取决于select中属性的个数。如Q?br />
List students = session.createQuery("select id, name from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
3>).如果认ؓq回数组不够对象化,可以采用HQL动态实例化Student对象Q?br />
但是StrudentcM必须提供相应的构造函数。如Q?br />
List students = session.createQuery("select new Student(id, name) from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getId() + "," + student.getName());
}
2>.实体对象查询
1>).q回Student对象的集?可以忽略select,表可以用别?别名可以用as也可以不用。如Q?br />
List students = session.createQuery("from Student s").list();
//List students = session.createQuery("from Student as s").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
2>).q回Student对象的集?使用select查询实体对象Q必采用别名。如Q?br />
List students = session.createQuery("select s from Student as s").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
3>).不支持select * from .....q样的查询语句。如Q下面的语句是错误的
List students = session.createQuery("select * from Student").list();
4>).list和iterator的区?
我们知道,session.createQuery()得到个Query,而从Hibernate API中我们可
以发现Query有两个方法list()和iterator()用于q回l果集。它们的区别?br />
于:
*list每次都会发出sql语句Qlist会向~存中放入数据,而不利用~存中的数据
*iterator在默认情况下利用~存数据,但如果缓存中不存在数据有可能出现N+1问题
5>).N+1问题
在默认情况下,使用query.iterator()查询Q有可能出现N+1问题
1: 首先发出一条查询对象id列表的sql语句
N: Ҏid列表到缓存中查询,如果~存中不存在与之匚w的数?那么会根?br />
id发出相应的sql语句
如:
Iterator iter = session.createQuery("from Student").iterate();
while(iter.hasNext()) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
3>.条g查询
1>).可以采用拼字W串的方式传递参数。如Q?br />
List students = session.createQuery("select s.id, s.name from Student s where s.name like '%1%'").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
2>).可以使用Q方式传递参?参数的烦引从0开?传递的参数值如果是字符型的Q不?br />
单引号引h;可以使用Ҏ铄E。如Q?br />
List students = session.createQuery("select s.id, s.name from Student s where s.name like ?")
.setParameter(0, "%1%")
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
3>).可以使用 Q参数名U?的方式传递参数倹{如Q?br />
List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname")
.setParameter("myname", "%1%")
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
4>).如果传递多个参敎ͼ可以使用setParameterListҎ。如Q?br />
List students = session.createQuery("select s.id, s.name from Student s where s.id in(:myids)")
.setParameterList("myids", new Object[]{1, 2, 3, 4, 5})
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
5>).在HQL中可以用数据库的函?像mysql中的date_format。如Q?br />
List students = session.createQuery("select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?")
.setParameter(0, "2008-02")
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
6>).查询某个日期D늚数据。如Q?br />
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//查询2008-01-10?008-02-15创徏的学?br />
List students = session.createQuery("select s.id, s.name from Student s where s.createTime between ? and ?")
.setParameter(0, sdf.parse("2008-01-10 00:00:00"))
.setParameter(1, sdf.parse("2008-02-15 23:59:59"))
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
4>.Hibernate也支持直接用sql查询。如Q?br />
List students = session.createSQLQuery("select * from t_student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
5>.外置命名查询,主要完成hql语句和程序的解耦合.
1>).在映文件中采用<query>标签来定义HQL语句。如Q?br />
<query name="searchStudents">
<![CDATA[
SELECT s FROM Student s where s.id<?
]]>
</query>
2>).在程序中采用session.getNamedQuery()Ҏ得到HQL查询丌Ӏ如Q?br />
List students = session.getNamedQuery("searchStudents")
.setParameter(0, 10)
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
6>.查询qo?br />
1>).在媄文件中定义qo器参数。如Q?br />
<filter-def name="filtertest">
<filter-param name="myid" type="integer"/>
</filter-def>
2>).在类的媄中使用q些参数。如Q?br />
<filter name="filtertest" condition="id < :myid"/><!--<转义字符"<"-->
3>).在程序中启用qo器。如Q?br />
session.enableFilter("filtertest")
.setParameter("myid", 10);
List students = session.createQuery("from Student").list();//会在该session中所有的查询后自动加上过滤器中的条g
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
参见:Student.hbm.xml,FilterQueryTest.java
7>.分页查询
1>).setFirstResult()?开?br />
2>).setMaxResults每页昄多少条数据。如Q?br />
List students = session.createQuery("from Student")
.setFirstResult(1)
.setMaxResults(2)
.list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
8>.对象D查询
Hibernate支持对象的,因此可以用对象导航查询。如Q?br />
StudentcLLClassescd的属性classesQ而ClassescLname属性。我们通过classes的name来查询student:
List students = session.createQuery("select s.name from Student s where s.classes.name like '%1%'").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
9>.q接查询
1>).内连?只是把两辚w有的记录查出?可以省略innerQƈ且只要媄文件中已经讑֥了表之间的关p,无须用on表示查询条g。如Q?br />
//List students = session.createQuery("select c.name, s.name from Student s join s.classes c").list();
List students = session.createQuery("select c.name, s.name from Student s inner join s.classes c").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
2>).外左q接:把左边表的所有记录都昄出来。如Q?br />
List students = session.createQuery("select c.name, s.name from Classes c left join c.students s").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
3>).外右q接:把右边表的所有记录都昄出来。如Q?br />
List students = session.createQuery("select c.name, s.name from Classes c right join c.students s").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + "," + obj[1]);
}
10>.l计查询
1>).count。如Q?br />
Long count = (Long)session.createQuery("select count(*) from Student").uniqueResult();//q回的是单条记录
System.out.println(count);
2>).group by。如Q?br />
List students =session.createQuery("select c.name, count(s) from Student s join s.classes c " +
"group by c.name order by c.name").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + ", " + obj[1]);
}
11>.DML风格的操?量用,因ؓ~存不同?
update和delete只会更新数据库中的数?而缓存中不会改,此时如果取得该数据还是缓存中?而不会是更新后的Q因此缓
存中的数据就成了脏数据了。如果批量更新的话,q会l内存带来很大压力。如Q?br />
session.createQuery("update Student s set s.name=? where s.id < ?")
.setParameter(0, "李四")
.setParameter(1, 5)
.executeUpdate();
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/yangfeitarena/archive/2009/04/17/4086334.aspx
2、当对象.hbm.xml配置文g<class>元素的lazy属性设|ؓtrueӞ调用load()Ҏ时则q回持久对象的代理类实例Q此时的代理cd例是p行时动态生成的c,该代理类实例包括原目标对象的所有属性和ҎQ该代理cd例的属性除了ID不ؓnull外,所在属性ؓnull|查看日志q没有Hibernate SQL输出Q说明没有执行查询操作,当代理类实例通过getXXX()Ҏ获取属性值时QHiberante才真正执行数据库查询操作。当对象.hbm.xml配置文g<class>元素的lazy属性设|ؓfalseӞ调用load()Ҏ则是立即执行数据库ƈ直接q回实体c,q不q回代理cR而调用get()Ҏ时不lazyZ|都直接返回实体类?/p>
3、load()和get()都会先从Session~存中查找,如果没有扑ֈ对应的对象,则查询Hibernate二~存Q再找不到该对象Q则发送一条SQL语句查询?/p>
解决办法
当你使用手动事务模式Ӟ必须?strong>SelectMethod 属性的D|ؓ Cursor, 或者是保在你的连接只有一个STATEMENT操作?/p>
修改url
加入SelectMethod=cursor卛_
在eclipse下通过在cfg文g中uri加入卛_