查看“Hibernate笔记 6:查询相关”的源代码
←
Hibernate笔记 6:查询相关
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Hibernate]] == 单表查询 == Hibernate 的检索方式主要有 5 种:分别为“'''导航对象图查询'''”、“'''OID 查询'''”、“'''HQL 查询'''”、“'''QBC 查询'''”和“'''SQL 查询'''”。 === 导航对象图查询 === ---- 导航对象图查询:根据已经加载的对象,导航到他的关联对象。【利用类与类之间的关系来检索对象】 前提是必须在对象关系映射文件上配置了关联关系。 示例: : <syntaxhighlight lang="Java" highlight=""> LinkMan linkMan = (LinkMan)session.get(LinkMan.class, 11); Customer customer = linkMan.getCustomer(); </syntaxhighlight> === OID 查询 === ---- OID 查询:主要指用 Session 的 get() 和 load() 方法加载某条记录对应的对象。【利用 OID 检索对象】 示例: : <syntaxhighlight lang="Java" highlight=""> Customer customer = (Customer)session.get(Customer.class, 1); Customer customer = (Customer)session.load(Customer.class, 1); </syntaxhighlight> === HQL 查询 === ---- HQL(Hibernate Query Language)是'''面向对象'''的查询语言,它和 SQL 查询语言有些相似,但<span style="color: blue">'''它使用的是类、对象和属性的概念,而没有表和字段的概念'''</span>。 在 Hibernate 提供的各种检索方式中,HQL 是官方推荐的查询语言,也是使用最广泛的一种检索方式。 它具有如下功能: * 在查询语句中设定各种'''查询条件'''。 * 支持'''投影查询''',即仅检索出对象的部分属性。 * 支持'''分页查询'''。 * 支持'''分组查询''',允许使用 group by 和 having 关键字。 * 提供内置'''聚集函数''',如 sum()、min() 和 max()。 * 能够调用'''自定义 SQL 函数'''。 * 支持'''子查询''',即嵌套查询。 * 支持'''动态绑定参数'''。 Hibernate 提供的 Query 接口是专门的 HQL 查询接口,它能够执行各种复杂的 HQL 查询语句。 完整的 HQL 语句结构如下: : <syntaxhighlight lang="SQL" highlight=""> select ... from ... where ... group by ... having ... order by ... asc/desc </syntaxhighlight> :* 通常情况下,当检索数据表中的所有记录时,select 关键字可以省略; :** 不支持“select *”。 :* HQL 中使用的是类名,而非表名; :** 类名需要区分大小写。 ==== 基本查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** * HQL:基本检索 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // 查询所有 //Query query = session.createQuery("from Customer"); // 使用别名 //Query query = session.createQuery("from Customer c"); Query query = session.createQuery("select c from Customer c"); List<Customer> list = query.list(); for (Customer customer : list){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> ==== 排序查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** * HQL:排序检索 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("from Customer order by cust_id desc"); List<Customer> list = query.list(); for (Customer customer : list){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> ==== 条件查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *HQL:条件查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // 按位置绑定参数 Query query1 = session.createQuery("from Customer where cust name =?"); //query.setString(0,"中国移动"); // 按类型设置参数 query.setParameter(0,"中国移动"): List<Customer> list = query1.list(); for (Customer customer : list){ System.out.println(customer); } //按名称绑定参数 Query query2 = session.createQuery("from Customer where cust name = :name"); query.setParameter("name","中国联通"); Customer customer = (Customer)query2.uniqueResult(); System.out.println(customer); tx.commit(); } </syntaxhighlight> ==== 分页查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *HQL:分页查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("from LinkMan order by lkm_id desc"); query.setFirstResult(5); query.setMaxResults(5); List<LinkMan> list = query.list(); for (LinkMan linkMan : list){ System.out.printIn(linkMan); } tx.commit(); } </syntaxhighlight> ==== 统计查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *HQL:统计查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("select count(*)from Customer"); Long num = (Long)query.uniqueResult(); System.out.println(num); tx.commit(); } </syntaxhighlight> ==== 投影查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *HQL:投影查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // 投影查询一列 List<String> list1 = session.createQuery("select cust_name from Customer").list(); for (String string : list1){ System.out.println(string); } // 投影查询多列: List<Object>[] list2 = session.createQuery("select cust id,cust name from Customer").list(); for (Object[] objects : list2){ System.out.println(Arrays.tostring(objects)); } // 投影的构造的方式查询:【!!!】 List<Customer> list3 = session.createQuery("select new Customer(cust id,cust name) from Customer").list(); for (Customer customer : list3){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> === QBC 查询 === ---- QBC(Query By Criteria)是 Hibernate 提供的另一种检索对象的方式,它主要由 '''Criteria''' 接口、'''Criterion''' 接口和 '''Expression''' 类组成。 Criteria 接口是 Hibernate API 中的一个查询接口,它需要由 session 进行创建。 Criterion 是 Criteria 的查询条件,在 Criteria 中提供了 add(Criterion criterion) 方法来添加查询条件。 Restrictions 类中提供了大量的静态方法来创建查询条件: :{| class="wikitable" ! 方法 !! 描述 |- | '''Restrictions.eq''' || 等于 |- | '''Restrictions.allEq''' || 使用 Map,使用 key/value 进行多个等于的比较 |- | '''Restrictions.gt''' || 大于 > |- | '''Restrictions.ge''' || 大于等于 >= |- | '''Restrictions.lt''' || 小于 |- |''' Restrictions.le''' || 小于等于 <= |- | '''Restrictions.between''' || 对应 SQL 的 between 子句 |- | '''Restrictions.like''' || 对应 SQL 的 like 子句 |- | '''Restrictions.in''' || 对应 SQL 的 in 子句 |- | '''Restrictions.and''' || and 关系 |- | '''Restrictions.or''' || or 关系 |- | '''Restrictions.sqlRestriction''' || SQL 限定查询 |} ==== 基本查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *QBC:简单查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); List<Customer> list = criteria.list(); for (Customer customer : list){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> ==== 条件查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *QBC:条件查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); //设置条件: //criteria.add(Restrictions.eg("cust name","老张")); criteria.add(Restrictions.like("cust name","老")); criteria.add(Restrictions.gt("cust id",11)); List<Customer> list = criteria.list(); for (Customer customer : list){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> ==== 分页查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *QBC:分页查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(LinkMan.class); //设置分页: criteria.setFirstResult(5); criteria.setMaxResults(5); List<LinkMan>list = criteria.list(); for (LinkMan linkMan : list){ System.out.println(linkMan); } tx.commit(); } </syntaxhighlight> ==== 排序查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *QBC:排序查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(LinkMan.class); //设置排序: criteria.addorder(Order.desc("1kmid")); List<LinkMan>list = criteria.list(); for (LinkMan linkMan : list){ System.out.println(linkMan); } tx.commit(); } </syntaxhighlight> ==== 统计查询 ==== 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *QBC:统计查询 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(LinkMan.class); criteria.setProjection(Projections.rowCount()); Long count = (Long)criteria.uniqueResult(); System.out.println(count); tx.commit(); } </syntaxhighlight> ==== '''离线条件查询(DetachedCriteria)''' ==== DetachedCriteria 翻译为离线条件查询,因为它是'''可以脱离 Session 来使用的一种条件查询对象''': Criteria 对象必须由 Session 对象来创建,即:必须先有 Session 才可以生成 Criteria 对象。而 DetachedCriteria 对象可以在其他层对条件进行封装。 主要优点: 在做一些特别复杂的条件查询的时候,往往会在 WEB 层向业务层传递很多的参数,业务层又会将这些参数传递给 DAO 层,最后在 DAO 中拼接 SQL 完成查询。 有了离线条件查询对象后,'''可以直接在 WEB 层将数据封装好''',传递到业务层,再由业务层传递给 DAO 完成查询。 示例: : <syntaxhighlight lang="Java" highlight=""> @Test /** *离线条件查询:DetachedCriteria * */ public void demo(){ //获得一个离线条件查询的对象 DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class); detachedCriteria.add(Restrictions.eg("cust_name","中国移动")); Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //离线条件查询对象与session绑定 List<Customer> list = detachedCriteria.getExecutableCriteria(session).list(); for (Customer customer : list){ System.out.println(customer); } tx.commit(); } </syntaxhighlight> == '''多表查询''' == === SQL 连接查询 === # <big>'''交叉连接'''</big>:交叉连接返回的结果是被连接的两个表中所有数据行的'''笛卡尔积''',也就是返回“第一个表中符合查询条件的数据行数”乘以“第二个表中符合查询条件的数据行数”。 #: 语法格式: #: <syntaxhighlight lang="SQL" highlight=""> SELECT * from 表1 CROSS JOIN 表2; # 或 SELECT * from 表1, 表2; </syntaxhighlight> #* 在实际开发中这种业务需求是很少见的,一般不会使用交叉连接,而是使用具体的条件对数据进行有目的的查询。 # <big>'''内连接'''</big>(“简单连接”或“自然连接”):使用比较运算符对两个表中的数据进行比较,并列出与连接条件匹配的数据行,组合成新的记录 —— 即:只有满足条件的记录才能出现在查询结果中。 #: 语法格式: #: <syntaxhighlight lang="SQL" highlight=""> SELECT 查询字段 FROM 表1 [INNER] JOIN 表2 ON 表1.关系字段 = 表2.关系字段 </syntaxhighlight> #* 内连接其实还可以细分为如下两类: #*# '''隐式内连接''':在语句中使用关键字“'''where'''”替代“inner join”。 #*#: <syntaxhighlight lang="SQL" highlight=""> SELECT * from 表1, 表2 where 表1.关系字段 = 表2.关系字段; </syntaxhighlight> #*# '''显示内连接''':在语句中明显的调用了“'''inner join'''”的关键字。 #*#: <syntaxhighlight lang="SQL" highlight=""> SELECT * from 表1 inner join 表2 on 表1.关系字段 = 表2.关系字段; SELECT * from 表1 join 表2 on 表1.关系字段 = 表2.关系字段; </syntaxhighlight> # <big>'''外连接'''</big>:返回查询结果中不仅包含符合条件的数据,而且还包括'''左表'''(“左连接”或“左外连接”)、'''右表'''(“右连接”或“右外连接”)或'''两个表'''(“全外连接”)中的所有数据。 #: 语法格式: #: <syntaxhighlight lang="SQL" highlight=""> SELECT 所查字段 FROM 表1 LEFT|RIGHT [OUTER] JOIN 表2 ON 表1.关系字段 = 表2.关系字段 WHERE 条件 </syntaxhighlight> #* 对于“左连接”和“右连接”,其查询结果是不一致的: #*# '''左连接'''('''LEFT JOIN'''):返回包括左表中的所有记录和右表中符合连接条件的记录。 #*#: <syntaxhighlight lang="SQL" highlight=""> SELECT * from 表1 1eft outer join 表2 on 表1.关系字段 = 表2.关系字段; SELECT * from 表1 1eft join 表2 on 表1.关系字段 = 表2.关系字段; </syntaxhighlight> #*# '''右连接'''('''RIGHT JOIN'''):返回包括右表中的所有记录和左表中符合连接条件的记录。 #*#: <syntaxhighlight lang="SQL" highlight=""> SELECT * from 表1 right outer join 表2 on 表1.关系字段 = 表2.关系字段; SELECT * from 表1 right join 表2 on 表1.关系字段 = 表2.关系字段; </syntaxhighlight> === HQL 连接查询 === Hibernate 进行多表查询与 SQL 其实是很相似的,但是 HQL 会在原来 SQL 分类的基础上又多出来一些操作。 # <big>'''交叉连接'''</big>: # <big>'''内连接'''</big>: ## '''显示内连接''': ## '''隐式内连接''': ## <span style="color: blue">'''迫切内连接'''</span>: # <big>'''外连接'''</big>: ## '''左外连接''': ## <span style="color: blue">'''迫切左外连接'''</span>: ## '''右外连接''': == 查询策略 ==
返回至“
Hibernate笔记 6:查询相关
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息