锁定老帖子 主题:Hibernate查询详解
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (7)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-25
Hibernate查询 首先介绍get()和load()方法的区别: get()方法和load()方法的区别主要在于对二级缓存的使用上。 load()方法会使用二级缓存,而get()方法在一级缓存没有找到会直接查询数据库,不会去二级缓存中查找。 get():如果在数据库中没有记录会返回空,get()无论如何都会返回数据. load():如果数据库中没有记录会抛出异常,如果有数据返回的是一个代理对象。 list和iterator()方法之间的区别:(N+1?) list()方法在执行时,直接运行查询结果所需要的查询语句。 iterator()方法则是先执行得到对象ID的查询,然后在根据每个ID值去取得所要查询的对象。 因此:对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数). 结果集的处理方法不同: list()方法会一次活的所有的结果集对象,而且他会依据查询的结果初始化所有的结果集对象。如果在结果集非常庞大的时候会占据非常多的内存,甚至会造成内存溢出的情况发生。 iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。一次在访问中可以控制缓存中对象的数量,以避免占用过多的缓存,导致内存溢出情况的发生。 HQL:HQL是一种面向对象的查询语言,HQL的操作对象是类、实例和属性等。 SQL:sql的操作对象是数据表和列等数据对象。 Hql是完全面向对象的查询语言,因此可以支持继承和多条等特征。 HQL查询依赖于Query类,每个Query实例对应一个查询对象。 定参数的功能,Query 接口才是真正的HQL查询接口。 //创建一个Query 对象 Query query = session.createQuery ("from Customer as c where c.name=:customerName and c.age=:customerAge"); //动态绑定参数 query.setString("customerName","Tom"); query.setInteger("customerAge",21); //执行查询语句,返回结果 List result = query.list(); HQL查询步骤: 1:获取Hibernate Session对象。 2:编写HQL语句。 3:以HQL语句作为参数,调用Session的createQuery方法创建查询对象。 4:如果HQL语句包含参数,调用Query的setXXX()方法为参数赋值。 5: 调用Query对象的list等方法遍历查询结果。 Query还包含两个方法: setFirstResult(int firstResult)://设置返回的结果集从第几条记录开始。 setMaxResults(int maxResults)://设置本次查询返回的结果数。 实体的删除和更新。 投影查询:只查询属性的一部分。 查询一个属性返回的是字符串 查询二个字段返回的是数组 动态构造查询:主要用于几十个表查询; 要构建一个新的对象,要加上一个构造函数; 在new对象的时候要加上包名 不要使用count(*) 要count(持久化对象) 分组与排序: Order by子句可以通过asc或desc关键字排序 如: form User u Order by u.name asc,u.age desc; Group by子句与统计查询: 如: String hql = "select count(u),u.age from User u group by u.age having count(u)>10"; List list = session.createQuery(hql).list(); 标准的SQL聚合函数都可以在HQL语句中使用,比如:count(),sum(),max(),min(),age()等 连接查询: 内连接:inner join 左外连接:left outer join 右外连接:right outer join 全连接:full join(不常用) 迫切外连接:left outer join fetch,left join fetch:用于一次性获取连接数据,特别是集合数据。减少与数据库交互的次数。 left out join:使用做外连接位于left join 左侧表的所有记录及对应的order类的记录信息都将显示出来。 right out join:与 left out join 正好相反,right out join 返回的是HQL右侧表中的所有记录以及对应的Customer对象记录信息。 获取集合数据的四种方式: 1:Hibernate.initialize(user.getOrder()); 2:user.getOrder().size(); 3:左右迫切连接 4:高级过滤器 条件查询语句(Criteria Queries):利用对象进行对象查询。 主要的接口有:Criteria、Criterion和expression_r和Restrictions类组成。能够支持在运行时动态生成SQL语句。 条件查询步骤: 1:通过seesion的CreateCriteria()方法,创建一个Criteria对象 2:设置查询对象,name指对象的属性 3:把查询条件添加到Criteria对象中 4:执行list()查询返回结果。 条件查询通过三个类完成: Criteria:代表一次查询. Criterion:代表一个查询条件. Restrictions:产生查询条件的工具类. 本地sql查询:使用手写的SQL来完成所有的create\update\delete操作也包括存储过程 本地sql步骤: 1:通过session创建一个SqlQuery对象。 2:编写sql语句 3:以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象 4:如果SQL语句包含参数,则调用Query的setXX方法为参数赋值 5:调用SQLQuery对象的addEntity或addScalar方法,将选出的结果与实体或标量值关联. 如:HQL的sql String sql = "select c.c_id as {c.id},c.c_name as {c.name} from CUSTOMER c where c.id = 1"; 注意:如果使用*,表的别名和类的别名要一致 String sql1 = "select {c.*} from CUSTOMER c where c.c_id=2 "; 如:条件查询的sql SQLQuery query = session.createSQLQuery(sql); query.addEntiy("c",Customer.class); 多态查询: 多态查询是指可以查询到当前类及所有子类的实例,HQL和条件查询都支持多态查询。 如:hql语句查询出所有的持久化对象 Query query = session.createQuery("from java.lang.object"); System.out.println(query.list()); HQL支持多态查询,多态查询是指查询出当前类及所有子类的实例, session.createQuery("from Employee"); or session.createCriteria(Employee.class); 如果Employee类有两个子类:HourlyEmployee和SalariedEmployee,那么这个查询语句会查出所有的Employee实例,以及HourlyEmployee类和SalariedEmployee类的实例。 session.createQuery("from HourlyEmployee"); session.createCriteria(HourlyEmployee.class);//只检索子类 查询结果集排序: Hql与条件查询都支持查询结果集排序,只是HQL采用Order by关键字,而条件查询采用order类进行查询结果排序。 分页查询: 分页查询是数据库应用中常见的处理方式,Query和Criteia接口都提供了用于分页查询的方法. setFistResult(int): //指定从哪一个对象开始查询,参数是索引位置从0开始。 setMaxResults(int): //指定一次最多查询的对象数量。 子查询: 1:查询有一个订单以上的客户。 如: from Customer c where 1<(select count(o) from c.orders o) hql子查询依赖于底层数据库 对子查询支持的能力。 所有的子查询可以使用连接查询和分组查询语句来代替。 如: select c from Customer c join c.orders o group by c.id having count(o)>1 如果子查询返回多条记录,可以使用关键字量化: 1:all 2:any 3:some 4:in 5:exists 如: //返回所有订单价格小于100的客户 from Customer c where 100>all(select o.price form c.orders o) //返回有一条订单的价格小于100的客户 from Customer c where 100>any(select o.price from c.orders o) //返回有一条订单的价格等于100的客户 from Customer c where 100=some(select o.price from c.order o) //返回有一条订单的价格等于100的客户 from Customer c where 100 = any (select o.prive from c.orders o) //返回有一条订单的价格等于100的客户 from Customer c where 100 in (select o.price from c.orders o) 参数绑定: 1:传统的JDBC的参数绑定 如: PrepareStatement pre = connection.prepare("select * from User where user.name = ?"); pre.setString(1,"Zhao"); ResultSet rs = pre.executeQuery(); Hibernate参数绑定:在hibernate中有4种参数绑定方式 1:按参数名称(命名参数)绑定,在语句中定义命名参数要用":"开头 2:按参数位置绑定 3:Hql查询中可以通过setParameter()方法绑定任意类型的参数 4:setProperties()方法,将命名参数与一个对象的属性值绑定在一起 如:参数":"开头 Query query = session.createQuery("from User user where user.name = customername and user.age = :customerage"); query.setString("customername",name); query.setInteger("customerage",age); 如:参数位置绑定 Query query = session.createQuery("from User user where user.name =? and user.age = ?"); query.setString(0,name); query.setInteger(1,age); 如:setParameter他有三个参数一般写两个参数 String hql = "from User user where user.name = :customername"; Query query = session.createQuery(hql); query.setParameter("customername",name,Hibernate.STRING); 如:setProperties Customer customer = new Customer(); customer.setName("sdsd"); customer.setAge(99); Query query = session.createQuery("from Customer c where c.name=:name and c.age = :age"); query.setProperties(customer); 定义命名查询: 命名的SQL语句不是放在程序中,而是放在配置文件中,这种方式是以松耦合的方式配置SQL语句,可以提高程序解耦. 在Customer.hbm.xml配置文件中 <query name="findCustomer"> <!CDAATA[from Customer c where c.name = :name] /> </query> 程序中的代码: Query query = session.getNamedQuery("findCustomer"); query.setString("name","tiger"); List list = query.list(); 命名的SQL语句: <sql-query name="mysqlquery"> <!-- 关联返回的结果与实体类 --> <return alias="s" class="com.lovo.po.Customer"> <!-- 定义命名SQL查询的SQL语句 --> select {c.*} from Customer Customer c where c.name like "刘德华" </sql-query> sql_query是hibernate-mapping元素的子元素,因此可以直接通过session访问 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-26
get。。同样会查二级缓存,这个我印象中做过实验。
可能早期版本不差,至少3.25以后应该查的。 |
|
返回顶楼 | |
发表时间:2010-11-26
啥意义没有
|
|
返回顶楼 | |
发表时间:2010-11-26
LZ 最近心情不错! 发帖率相当的高啊!
|
|
返回顶楼 | |
发表时间:2010-11-26
比较基础 楼主加油
|
|
返回顶楼 | |
发表时间:2010-11-26
aoliwen521 写道 get。。同样会查二级缓存,这个我印象中做过实验。
可能早期版本不差,至少3.25以后应该查的。 同意。get和load都可以取缓存 |
|
返回顶楼 | |
发表时间:2010-11-27
jiayj198609 写道 get()方法和load()方法的区别主要在于对二级缓存的使用上。 load()方法会使用二级缓存,而get()方法在一级缓存没有找到会直接查询数据库,不会去二级缓存中查找。 人云亦云,虾扯蛋 get/load 主要区别在于是否能lazy |
|
返回顶楼 | |
发表时间:2010-11-29
我也记得get方法是可以去查二级缓存的 先是查一级缓存然后二级
|
|
返回顶楼 | |
发表时间:2010-11-29
请问楼主的头像是不是真人版的?
|
|
返回顶楼 | |
发表时间:2010-12-14
jiasky 写道 请问楼主的头像是不是真人版的?
哥们你见过这样的程序员么? |
|
返回顶楼 | |