hibernate

 

9月12日
完成Hibernate 对象查询语言 HQL 实验 - Finished tests with Hibernate Query Language

 

 

 

"select c.name, count(s) from Student s join s.classes c " + "group by c.name order by c.name"

很有意思吧,其中Student是对象哦,不是表。

 

刚才完成了关于 Hibernate中 HQL [一个类似于sql语法的] 的实验。

hql很强大,很好用,也很对象。

image

 

现在喜欢把概念,管它什么东西都画成图,画图后就清楚了很多。每天画几幅图,感觉小时候真应该去学画画和文科。><

所以以后编程的时候就在参考图,没办法,无数学头脑。

 

hql 用起来的感觉,很像在 传统的sql 语句中 把每个表,每个field,换成是面向对象世界中的 实体和 实体.引用实体.属性。

本质很简单,到头来,他们全部都是 sql, 只是 hibernate 把sql的感觉 包装成了 对象的感觉。

 

也就是你写一个hql,然后hibernate按照规则,把你写的hql 转成 sql,向数据库发, and vise versa.

 

hql主题包含 11 大点,每天有很多小细节,每个小细节构成一个小实验。实验的数据都是 “学生和班级”模型。

真实情况下,差不太多,所有的对象无非就是各种对象组成的,比如学生和班级 是典型的 双N-1 关系。

有些细节比如:

1. method chain programming convention

2. 如果处理 日期

3. 处理 ? ,很重要,因为查询条件都是由 用户从网络另一段通过 页面 html过来的。

4. 如何处理 范围, 分组, 排序。重要,因为用户天天就在做这些。

-----------------------------------------------------------------

以下是知识点部分。

hibernate查询语言hql

在hql中关键字不区分大小写,但是属性和类名区分大小写

1、简单属性查询【重要】

* 单一属性查询,返回结果集属性列表,元素类型和实体类中相应的属性类型一致

* 多个属性查询,返回的集合元素是对象数组,数组元素的类型和对应的属性在实体类中的类型一致

数组的长度取决与select中属性的个数

* 如果认为返回数组不够对象化,可以采用hql动态实例化Student对象。首先在Student类中构建一个constructor - Student(id, name),然后就可以在下面使用,amazing,此时返回的 list中为Student对象集合

参见:SimplePropertyQueryTest.java

2、实体对象查询【重要】

* N + 1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题

所谓的N+1是在查询的时候发出了N+1sql语句

1: 首先发出一条查询对象id列表的sql

N: 根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句

* list和iterate的区别?

* list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据

* iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题

参见:SimpleObjectQueryTest1.java/SimpleObjectQueryTest2.java

-hiberanate session和 cpu的 一级cache绑定,就是看一级cache又没有数据,没有就发sql

-Query的 Iterator 接口使用缓存

-通过执行一次list(),一次iterator()消除N+1问题

-如果执行2次list(),虽然第一次数据已经在first level cache,但是list()还是会重新发sql,因为list()只往cache中放数据,但是不会利用cache.

3、条件查询【重要】

* 可以采用拼字符串的方式传递参数

* 可以采用 ?来传递参数(索引从0开始),注意使用“方法chain”编程

-List students = session.createQuery("select s.id, s.name from Student s where s.name like ?") .setParameter(0, "%1%")

.list();

* 可以采用 :参数名 来传递参数 – 如:myname

* 如果传递多个参数,可以采用setParamterList方法

* 在hql中可以使用数据库的函数,如:date_format

-"select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?" 查询比如20082月注册的学生

-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(); 查询在2个时间点之间注册的学生

参见:SimpleConditionQueryTest.java

4、hibernate也支持直接使用sql进行查询

-List students = session.createSQLQuery("select * from t_student").list();

以前的项目常使用hibernate和jdbc/sql/dao混杂的编程,对于效率问题

参见:SqlQueryTest.java

5、外置命名查询

* 在映射文件中采用<query>标签来定义hql

* 在程序中采用session.getNamedQuery()方法得到hql查询串

-session.getNamedQuery("searchStudents").setParameter(0, 10)

.list()

参见:Student.hbm.xml、NameQueryTest.java

6、查询过滤器 – 知道就行,用的时候再去查;

* 在映射文件中定义过滤器参数

* 在类的映射中使用这些参数

* 在程序中启用过滤器

-用途比如 过滤登陆用户输入的内容,过滤其他人,其实就是传入自己的id

参见:Student.hbm.xml、FilterQueryTest.java

7、分页查询【很重要】

* setFirstResult(),从0开始

* setMaxResults,每页显示多少条数据

-List students = session.createQuery("from Student")

.setFirstResult(1)

.setMaxResults(2)

.list();

参见:PageQueryTest.java

8、对象导航查询,在hql中采用 . 进行导航【重要】

-List students = session.createQuery("select s.name from Student s where s.classes.name like '%1%'").list();

参见:ObjectNavQueryTest.java

9、连接查询【重要】on … = … condition

* 内连

* 外连接(左连接/右连接)

-普通内连"select c.name, s.name from Student s inner join s.classes c"

对应sql: Hibernate: select classes1_.name as col_0_0_, student0_.name as col_1_0_ from t_student student0_ inner join t_classes classes1_ on student0_.classesid=classes1_.id

-左外连接"select c.name, s.name from Classes c left join c.students s"

Hibernate: select classes0_.name as col_0_0_, students1_.name as col_1_0_ from t_classes classes0_ left outer join t_student students1_ on classes0_.id=students1_.classesid

-右边外连接"select c.name, s.name from Classes c right join c.students s"

Hibernate: select classes0_.name as col_0_0_, students1_.name as col_1_0_ from t_classes classes0_ right outer join t_student students1_ on classes0_.id=students1_.classesid

参见:JoinQueryTest.java

10、统计查询【重要】但较少用hibernate做统计,主要是用一些市场上专门做报表的中间件。

-"select count(*) from Student" hql中可以使用sql函数

-"select c.name, count(s) from Student s join s.classes c " + "group by c.name order by c.name" 计算每个班多少学生,inner join

参见:StatQueryTest.java

11、DML风格的操作,批量操作(尽量少用,因为和缓存不同步)

-"update Student s set s.name=? where s.id < ?"

参见:DMLQueryTest.java

 

- reference to sxt's source package and doc

- time consumed in this update : 10 mins

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值