查看“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>: ## '''显示内连接''': ##: <syntaxhighlight lang="Java" highlight="9,10-13"> @Test /** *HQL的多表的连接查询:显示内连接 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list(); for(Object[] objects : list){ System.out.println(Arrays.tostring(objects)); } tx.commit(); } </syntaxhighlight> ## '''隐式内连接''': ## <span style="color: blue">'''迫切内连接'''</span>: ##: <syntaxhighlight lang="Java" highlight="9,10-13"> @Test /** *HQL的多表的连接查询:迫切内连接 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkMans").list(); for(Customer customer : list){ System.out.println(Arrays.tostring(objects)); } tx.commit(); } </syntaxhighlight> # <big>'''外连接'''</big>: ## '''左外连接''': ## <span style="color: blue">'''迫切左外连接'''</span>: ## '''右外连接''': ==== 迫切连接 ==== 迫切连接:在连接语句中加入<span style="color: blue">“fetch”</span>关键字(非 SQL 关键字,只能在 HQL 中使用) “迫切连接”与“非迫切连接”,生成的底层 SQL 和查询得到的结果集都是一样的,二者主要区别在于'''封装数据''': # 迫切连接:封装的时候将属于各自对象的数据封装到各自的对象中,最后得到一个 <span style="color: blue">'''List<Object[]>'''</span>。 # 非迫切连接:封装数据到对象中,最后得到一个 <span style="color: blue">'''List<实体类名>'''</span>。 #* 会出现重复数据,所以一般通过 '''distinct''' 去掉重复值: #*: <syntaxhighlight lang="Java" highlight="1"> List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list(); </syntaxhighlight> == 抓取策略 == “抓取策略”(查询策略):当应用程序需要在关联关系间进行导航的时候,如何获取关联对象的策略。 —— 即:“<span style="color: blue">'''查询到某个对象的时候,如何抓取其关联对象'''</span>” 其作用是“提升性能”:可以在获取关联对象的时候,对发送的语句进行'''优化''',但是往往需要和'''延迟加载'''一起使用来提升性能。 === 延迟加载('''lazy 属性''') === 延迟加载(懒加载,lazy load)是 Hibernate 关联关系对象默认的加载方式:'''在需要数据的时候,才真正执行数据加载操作'''。 其作用是为了避免无谓的性能开销。 延迟加载分为两类: # <span style="color: blue">'''类级别延迟'''</span>:查询某个对象(load 方法加载数据)的时候,是否采用有延迟。 #: <syntaxhighlight lang="Java" highlight=""> Customer customer = session.load(Customer.class,11); </syntaxhighlight> #* 通常在 <span style="color: blue">'''<class>'''</span> 标签上配置 lazy 属性。 # <span style="color: blue">'''关联级别的延迟'''</span>:查询一个对象的关联对象的时候是否采用延迟加载。 #: <syntaxhighlight lang="Java" highlight=""> Customer customer = session.get(Customer.class,11); Set<LinkMan> linkMans = customer.getLinkMans(); </syntaxhighlight> #* 通常在 '''<set>''' 或 '''<many-to-one>''' 上配置 lazy 属性。 #** <span style="color: blue">'''<set>'''</span> 标签中 '''lazy''' 属性的取值: #**# '''true''':(默认值)采用延迟加载; #**# '''false''':检索关联对象的时候,不采用延迟加载; #**# '''extra''':及其懒惰的。 #** <span style="color: blue">'''<many-to-one>'''</span> 标签中 '''lazy''' 属性的取值: #**# '''proxy''':(默认值)是否采用延迟取决于“一端”类上的 lazy 属性的值; #**# '''false''':检索关联对象的时候,不采用延迟加载; #**# '''no-proxy'''。 '''抓取策略主要在于“关联级别的延迟”。''' —— “类级别延迟”一般默认即可。 === 抓取策略('''fetch 属性''') === 通过在关联对象的 '''<set>''' 或 '''<many-to-one>''' 标签上配置 fetch 属性,以实现不同的效果。 <span style="color: blue">'''注意:fetch 取值为 join 时,lazy 将会失效。'''</span> # <span style="color: blue">'''<set>'''</span> 标签中 '''fetch''' 属性的取值: ## '''select''':(默认值)发送“'''普通 select 语句'''”来查询其关联对象; ## '''join''':发送“'''迫切左外连接'''”来查询其关联对象; ## '''subselect''':发送“'''子查询语句'''”来查询其关联对象。 # <span style="color: blue">'''<many-to-one>'''</span> 标签中 '''fetch''' 属性的取值: ## '''select''':(默认值)发送“'''普通 select 语句'''”来查询其关联对象; ## '''join''':发送“'''迫切左外连接'''”来查询其关联对象; === 示例 === # '''<set>''' 标签,以“查询 1 号客户,并获取其联系人数量”为例: ## (默认情况)fetch="select",lazy="true": ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号客户,同时查询1号客户的联系人的数量 *(默认情况)<set>配置:fetch="select",lazy="true" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询客户 Customer customer = session.get(Customer.class,11); //发送一条“普通select”:查询客户 //获取客户的联系人数量 System.out.println(customer.getLinkMans().size()); //发送一条“普通select”:查询客户的所有联系人 tx.commit(); } </syntaxhighlight> ## fetch="select",lazy="false": ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号客户,同时查询1号客户的联系人的数量, * <set>配置:fetch="select",lazy="false" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询客户 Customer customer = session.get(Customer.class,11); //发送两条“普通select”:1、查询客户,2、查询客户的所有联系人 //获取客户的联系人数量 System.out.println(customer.getLinkMans().size()); //不发送语句 tx.commit(); } </syntaxhighlight> ## fetch="select",lazy="extra": ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号客户,同时查询1号客户的联系人的数量 * <set>配置:fetch="select",lazy="extra" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询客户 Customer customer = session.get(Customer.class,l1); //发送一条“普通select”:查询客户 //获取客户的联系人数量 System.out.println(customer.getLinkMans().size()); //发送一条“普通select”:用 count(*) 语句统计联系人个数 tx.commit(); } </syntaxhighlight> ## fetch="join",lazy 失效: ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号客户,同时查询1号客户的联系人的数量. * <set>配置:fetch="join",lazy 失效 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询客户 Customer customer = session.get(Customer.class,1l); //发送一条“迫切左外连接”:查询客户及其关联对象 //获取客户的联系人数量 System.out.println(customer.getLinkMans().size()); //不发送语句 tx.commit(); } </syntaxhighlight> ## fetch="subselect",lazy="true": ##: <syntaxhighlight lang="Java" highlight=""> @SuppressWarnings ("unchecked") @Test /** * 查询1号客户,同时查询1号客户的联系人的数量. * <set>配置:fetch="subselect",lazy="true" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询所有客户(子查询不能查询某一个对象,查询多个对象来测试) List<Customer> list = session.createQuery("from Customer").list(); //发送一条“普通select”:查询所有客户 for (Customer customer : list){ System.out.println(customer.getLinkMans().size()); //发送一条“子查询”:查询客户的所有联系人 } tx.commit(); } </syntaxhighlight> ## fetch="subselect",lazy="false": ##: <syntaxhighlight lang="Java" highlight=""> @SuppressWarnings ("unchecked") @Test /** *查询1号客户,同时查询1号客户的联系人的数量. *<set>配置:fetch="subselect",lazy="false" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询所有客户(子查询不能查询某一个对象,查询多个对象来测试) List<Customer> list = session.createQuery("from Customer").list(); //发送:1、“普通select”:查询所有客户,2、“子查询”:查询客户的联系人 for (Customer customer : list){ System.out.println(customer.getLinkMans().size()); } tx.commit(); } </syntaxhighlight> # '''<many-to-one>''' 标签,以“查询 1 号联系人,并获取其客户信息”为例: ## (默认情况)fetch="select",lazy="proxy": ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号联系人,同时查询1号联系人所关联客户的信息 *(默认情况)<many-to-one>配置:fetch="select",lazy="proxy" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询联系人 LinkMan linkMan = session.get(LinkMan.class,1l); //发送一条“普通select”:查询联系人 //获取关联的客户信息 System.out.printin(linkMan.getCustomer().getCust_name()); //发送一条“普通select”:查询对应客户的信息 tx.commit(); } </syntaxhighlight> ## fetch="select",lazy="false": ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号联系人,同时查询1号联系人所关联客户的信息 * <many-to-one>配置:fetch="select",lazy="false" */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询联系人 LinkMan linkMan = session.get(LinkMan.class,1l); //发送两条“普通select”:1、查询联系人,2、查询对应客户的信息 //获取关联的客户信息 System.out.println(linkMan.getCustomer().getCust_name()); //不发送 tx.commit(); } </syntaxhighlight> ## fetch="join",lazy 失效: ##: <syntaxhighlight lang="Java" highlight=""> @Test /** * 查询1号联系人,同时查询1号联系人所关联客户的信息 * <many-to-one>配置:fetch="join",lazy 失效 */ public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //查询联系人 LinkMan linkMan = session.get(LinkMan.class,1l); //发送一条“迫切左外连接”:查询联系人及其关联客户 //获取关联的客户信息 System.out.println(linkMan.getCustomer().getCust_name()); //不发送 tx.commit(); } </syntaxhighlight> == 批量抓取 == '''批量抓取''':就是<span style="color: blue">'''同时查询多个对象的关联对象的时候'''</span>。 可以通过配置 <span style="color: blue; font-size: 150%">'''batch-size'''</span> 属性来配置一次抓取的量。 === “一端”批量抓取 === 在“一端”的 <span style="color: blue">'''<set>'''</span> 标签中配置 <span style="color: blue">'''batch-size'''</span> 即可。 对于代码:(查询客户,批量抓取联系人) : <syntaxhighlight lang="Java" highlight=""> @Test //查询客户,并获取关联的联系人 public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<Customer> list = session.createQuery("from Customer").list(); for (Customer customer : list){ System.out.println("客户名称:" + customer.getCust_name()); for(LinkMan linkMan : customer.getLinkMans()) System.out.println("客户对应的联系人的名称:" + linkMan.getLkm_name()): } tx.commit(); } </syntaxhighlight> # 未使用 batch-size: #: 效果:先查询所有客户,再'''分别'''对每个客户查询联系人 #: <syntaxhighlight lang="Java" highlight=""> Hibernate: select ... from cst customer customer0 客户名称:中国移动 Hibernate: select ... from cst_linkman linkmans0 where linkmans0_.1km_cust_id=? 客户对应的联系人的名称:老张 客户对应的联系人的名称:小李 客户名称:中国联通 Hibernate: select ... from cst linkman linkmans0 where linkmans0.1km cust id=? 客户对应的联系人的名称:老王 </syntaxhighlight> # 使用 batch-size: #: <syntaxhighlight lang="xml" highlight="2"> <!--配置关联关系映射--> <set name="LinkMans" batch-size="2"> <key column="..."/> <one-to-many class="..."/> </set> </syntaxhighlight> #: 效果:先查询所有客户,再查询'''所有'''客户的联系人 #: <syntaxhighlight lang="Java" highlight=""> Hibernate: select ... from cst_customer customer0_ 客户名称:中国移动 Hibernate: select ... from cst linkman linkmans0 where linkmans0.1km_cust_id in ( ?,? ) 客户对应的联系人的名称:老张 客户对应的联系人的名称:小李 客户名称:中国联通 客户对应的联系人的名称:老王 </syntaxhighlight> === “多端”批量抓取 === 在“一端”的 <span style="color: blue">'''<class>'''</span> 标签中配置 <span style="color: blue">'''batch-size'''</span> 即可。 对于代码:(查询联系人,批量抓取客户) : <syntaxhighlight lang="Java" highlight=""> @Test //查询联系人,并获取关联的客户 public void demo(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<LinkMan> list = session.createQuery("from LinkMan").list(); for (LinkMan linkMan : list){ System.out.println("联系人名称:" + linkMan.getLkm_name()); System.out.println("联系人对应的客户名称:" + linkMan.getCustomer()getCust_name()): } tx.commit(); } </syntaxhighlight> # 未使用 batch-size: #: 效果:先查询所有联系人,再'''分别'''对每个联系人查询客户 #: <syntaxhighlight lang="Java" highlight=""> Hibernate: select ... from cst linkman linkmane 联系人名称:老张 Hibernate: select ... from cst_customer customer0_ where customer0_.cust id=? 联系人对应的客户名称:中国移动 联系人名称:小李 Hibernate: select ... from cst customer customer0 where customer0_.cust_id=? 联系人对应的客户名称:中国移动 联系人名称:老王 Hibernate: select ... from cst_customer customer0_ where customer0_.cust id=? 联系人对应的客户名称:中国联通 </syntaxhighlight> # 使用 batch-size: #: <syntaxhighlight lang="xml" highlight="1"> <class name="..." table="cst_customer" batch-size="2"> ... </syntaxhighlight> #: 效果:先查询所有联系人,再查询'''所有'''联系人的客户 #: <syntaxhighlight lang="Java" highlight=""> Hibernate: select ... from cst_linkman linkman0_ 联系人名称:老张 Hibernate: select ... from cst_customer customer0 where customer0.custid in ( ?,? ) 联系人对应的客户名称:中国移动 联系人名称:小李 联系人对应的客户名称:中国移动 联系人名称:老王 联系人对应的客户名称:中国联通 </syntaxhighlight>
返回至“
Hibernate笔记 6:查询相关
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息