本文共 9210 字,大约阅读时间需要 30 分钟。
延迟加载的概述
通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。 通过或者在上通过fetch属性进行设置 fetch和这些标签上的lazy如何设置优化发送的SQL语句 1.3.1.1什么是延迟加载 延迟加载:lazy(懒加载)。执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。 1.3.1.2延迟加载的分类指的是通过load方法查询某个对象的时候,是否采用延迟。session.load(Customer.class,1l);
类级别延迟加载通过上的lazy进行配置,如果让lazy失效 将lazy设置为false 将持久化类使用final修饰 Hibernate. Initialize() 立即加载指的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。
Customer customer = session.get(Customer.class,1l); customer.getLinkMans(); ----通过客户获得联系人的时候,联系人对象是否采用了延迟加载,称为是关联级别的延迟。 抓取策略往往会和关联级别的延迟加载一起使用,优化语句。 抓取策略 1.3.2.1抓取策略的概述 通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。 通过或者上通过fetch属性进行设置 fetch和这些标签上的lazy如何设置优化发送的SQL语句fetch:抓取策略,控制SQL语句样式,可选的值如下
select :默认值,发送普通的select语句,查询关联对象 join :发送一条迫切左外连接查询关联对象 (当选择这个属性时,只有一种情况,不存在1*3 三种) subselect :发送一条子查询查询其关联对象 (效率很慢,能用多表查询尽量用 多表查询) lazy:延迟加载,控制查询关联对象的时候是否采用延迟,可选的值如下 (控制发送的时机) true :默认值,查询关联对象的时候,采用延迟加载 false :查询关联对象的时候,不采用延迟加载 extra :及其懒惰。在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。
配置代码:
fetch (只有两种):抓取策略,控制SQL语句格式。
select :默认值,发送普通的select语句,查询关联对象。 join :发送一条迫切左外连接。 lazy :延迟加载,控制查询关联对象的时候是否采用延迟。 proxy :默认值,proxy具体的取值,取决于另一端的上的lazy的值。 1 理解为 true:false :查询关联对象,不采用延迟。
no-proxy :(不会使用) 在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。什么是批量抓取
在抓取的策略中有一种叫做批量抓取,就是同时查询多个对象的关联对象的时候, 可以采用批量抓取进行优化。当然这个不是特别重要。 如果要实现批量的抓取效果,可以通过配置batch-size来完成。 1.3.3.2测试批量抓取 【查询客户批量抓取练习人】 @SuppressWarnings(“unchecked”) @Test public void FetchDemo4() throws Exception { /* * 查询客户, 客户关联的联系人是否查询: * 在Customer.hbm.xml中 集合上配置batch-size=“4”; * */ //获得链接对象: Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction();//查询客户: 客户关联的联系人: Listlist = 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();}
在没有设置batch-size之前运行以上代码,会出现如下的效果:
select
customer0_.cust_id as cust_id1_0_, customer0_.cust_name as cust_nam2_0_, customer0_.cust_source as cust_sou3_0_, customer0_.cust_industry as cust_ind4_0_, customer0_.cust_level as cust_lev5_0_, customer0_.cust_phone as cust_pho6_0_, customer0_.cust_mobile as cust_mob7_0_ from cst_customer customer0_ 客户的名称:何老师 Hibernate: select linkmans0_.lkm_cust_id as lkm_cus10_1_0_, linkmans0_.lkm_id as lkm_id1_1_0_, linkmans0_.lkm_id as lkm_id1_1_1_, linkmans0_.lkm_name as lkm_name2_1_1_, linkmans0_.lkm_gender as lkm_gend3_1_1_, linkmans0_.lkm_phone as lkm_phon4_1_1_, linkmans0_.lkm_mobile as lkm_mobi5_1_1_, linkmans0_.lkm_email as lkm_emai6_1_1_, linkmans0_.lkm_qq as lkm_qq7_1_1_, linkmans0_.lkm_position as lkm_posi8_1_1_, linkmans0_.lkm_memo as lkm_memo9_1_1_, linkmans0_.lkm_cust_id as lkm_cus10_1_1_ from cst_linkman linkmans0_ where linkmans0_.lkm_cust_id=? 客户对应的联系人的名称:翠花3 客户对应的联系人的名称:翠花6 客户的名称:毕老师 Hibernate: select linkmans0_.lkm_cust_id as lkm_cus10_1_0_, linkmans0_.lkm_id as lkm_id1_1_0_, linkmans0_.lkm_id as lkm_id1_1_1_, linkmans0_.lkm_name as lkm_name2_1_1_, linkmans0_.lkm_gender as lkm_gend3_1_1_, linkmans0_.lkm_phone as lkm_phon4_1_1_, linkmans0_.lkm_mobile as lkm_mobi5_1_1_, linkmans0_.lkm_email as lkm_emai6_1_1_, linkmans0_.lkm_qq as lkm_qq7_1_1_, linkmans0_.lkm_position as lkm_posi8_1_1_, linkmans0_.lkm_memo as lkm_memo9_1_1_, linkmans0_.lkm_cust_id as lkm_cus10_1_1_ from cst_linkman linkmans0_ where linkmans0_.lkm_cust_id=?
客户对应的联系人的名称:凤姐花5
客户对应的联系人的名称:凤姐花3 客户的名称:王八蛋3 Hibernate: select linkmans0_.lkm_cust_id as lkm_cus10_1_0_, linkmans0_.lkm_id as lkm_id1_1_0_, linkmans0_.lkm_id as lkm_id1_1_1_, linkmans0_.lkm_name as lkm_name2_1_1_, linkmans0_.lkm_gender as lkm_gend3_1_1_, linkmans0_.lkm_phone as lkm_phon4_1_1_, linkmans0_.lkm_mobile as lkm_mobi5_1_1_, linkmans0_.lkm_email as lkm_emai6_1_1_, linkmans0_.lkm_qq as lkm_qq7_1_1_, linkmans0_.lkm_position as lkm_posi8_1_1_, linkmans0_.lkm_memo as lkm_memo9_1_1_, linkmans0_.lkm_cust_id as lkm_cus10_1_1_ from cst_linkman linkmans0_ where linkmans0_.lkm_cust_id=? 客户对应的联系人的名称:蛋网吧3 查询结果分析: 目前数据库中有三个用户, 那么会发现执行代码会发生三条sql语句。我们想能不能发送一条SQL直接将两个客户的关联的联系人一起查询出来呢? 此时我们可以在标签上设置batch-size实现优化的效果。实现配置如下:Customer.hbm.xml当中的set标签上设置:
配置后运行,发送的sql语句如下:
select customer0_.cust_id as cust_id1_0_, customer0_.cust_name as cust_nam2_0_, customer0_.cust_source as cust_sou3_0_, customer0_.cust_industry as cust_ind4_0_, customer0_.cust_level as cust_lev5_0_, customer0_.cust_phone as cust_pho6_0_, customer0_.cust_mobile as cust_mob7_0_ from cst_customer customer0_客户的名称:何老师Hibernate: select linkmans0_.lkm_cust_id as lkm_cus10_1_1_, linkmans0_.lkm_id as lkm_id1_1_1_, linkmans0_.lkm_id as lkm_id1_1_0_, linkmans0_.lkm_name as lkm_name2_1_0_, linkmans0_.lkm_gender as lkm_gend3_1_0_, linkmans0_.lkm_phone as lkm_phon4_1_0_, linkmans0_.lkm_mobile as lkm_mobi5_1_0_, linkmans0_.lkm_email as lkm_emai6_1_0_, linkmans0_.lkm_qq as lkm_qq7_1_0_, linkmans0_.lkm_position as lkm_posi8_1_0_, linkmans0_.lkm_memo as lkm_memo9_1_0_, linkmans0_.lkm_cust_id as lkm_cus10_1_0_ from cst_linkman linkmans0_ where linkmans0_.lkm_cust_id in ( ?, ?, ? )
客户对应的联系人的名称:翠花2
客户对应的联系人的名称:翠花4 客户的名称:毕老师 客户对应的联系人的名称:凤姐花2 客户对应的联系人的名称:凤姐花6 客户的名称:王八蛋3 客户对应的联系人的名称:蛋网吧3 分析运行的sql语句: 发送的sql语句发生了变化,当数据量越大的时候, 效果越是明显。这是在查询所有的客户的时候批量抓取联系人。那么如果我们要实现查询多个联系人的时候,抓取联系人对应的客户呢? 同样需要设置batch-size。但是不是在上设置, 还是在客户的一端的 上设置即可。 【查询联系人批量抓取客户】 @SuppressWarnings(“unchecked”) @Test public void FetchDemo5() throws Exception { /* * 查询联系人,批量抓取客户 * 在Customer.hbm.xml中 * 注意: 如果在查询的过程当中出现了NullPointerException: 说明联系人的外键是null,没有关联的用户信息。 */ //获得链接对象: Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction();//查询联系人信息: Listlist = session.createQuery("from LinkMan").list(); //遍历联系人信息: for(LinkMan linkMan : list){ System.out.println(linkMan.getLkm_name()); //打印联系人对应的客户的名称 System.out.println(linkMan.getCustomer().getCust_name()); } tx.commit();}
运行的结果分析:
select linkman0_.lkm_id as lkm_id1_1_, linkman0_.lkm_name as lkm_name2_1_, linkman0_.lkm_gender as lkm_gend3_1_, linkman0_.lkm_phone as lkm_phon4_1_, linkman0_.lkm_mobile as lkm_mobi5_1_, linkman0_.lkm_email as lkm_emai6_1_, linkman0_.lkm_qq as lkm_qq7_1_, linkman0_.lkm_position as lkm_posi8_1_, linkman0_.lkm_memo as lkm_memo9_1_, linkman0_.lkm_cust_id as lkm_cus10_1_ from cst_linkman linkman0_翠花0Hibernate: select customer0_.cust_id as cust_id1_0_0_, customer0_.cust_name as cust_nam2_0_0_, customer0_.cust_source as cust_sou3_0_0_, customer0_.cust_industry as cust_ind4_0_0_, customer0_.cust_level as cust_lev5_0_0_, customer0_.cust_phone as cust_pho6_0_0_, customer0_.cust_mobile as cust_mob7_0_0_ from cst_customer customer0_ where customer0_.cust_id=?何老师翠花1何老师翠花2何老师Hibernate: select customer0_.cust_id as cust_id1_0_0_, customer0_.cust_name as cust_nam2_0_0_, customer0_.cust_source as cust_sou3_0_0_, customer0_.cust_industry as cust_ind4_0_0_, customer0_.cust_level as cust_lev5_0_0_, customer0_.cust_phone as cust_pho6_0_0_, customer0_.cust_mobile as cust_mob7_0_0_ from cst_customer customer0_ where customer0_.cust_id=?毕老师蛋网吧Hibernate: select customer0_.cust_id as cust_id1_0_0_, customer0_.cust_name as cust_nam2_0_0_, customer0_.cust_source as cust_sou3_0_0_, customer0_.cust_industry as cust_ind4_0_0_, customer0_.cust_level as cust_lev5_0_0_, customer0_.cust_phone as cust_pho6_0_0_, customer0_.cust_mobile as cust_mob7_0_0_ from cst_customer customer0_ where customer0_.cust_id=?王八蛋3蛋网吧2王八蛋3配置批量抓取:运行结果如下: select linkman0_.lkm_id as lkm_id1_1_, linkman0_.lkm_name as lkm_name2_1_, linkman0_.lkm_gender as lkm_gend3_1_, linkman0_.lkm_phone as lkm_phon4_1_, linkman0_.lkm_mobile as lkm_mobi5_1_, linkman0_.lkm_email as lkm_emai6_1_, linkman0_.lkm_qq as lkm_qq7_1_, linkman0_.lkm_position as lkm_posi8_1_, linkman0_.lkm_memo as lkm_memo9_1_, linkman0_.lkm_cust_id as lkm_cus10_1_ from cst_linkman linkman0_翠花0Hibernate: select customer0_.cust_id as cust_id1_0_0_, customer0_.cust_name as cust_nam2_0_0_, customer0_.cust_source as cust_sou3_0_0_, customer0_.cust_industry as cust_ind4_0_0_, customer0_.cust_level as cust_lev5_0_0_, customer0_.cust_phone as cust_pho6_0_0_, customer0_.cust_mobile as cust_mob7_0_0_ from cst_customer customer0_ where customer0_.cust_id in ( ?, ?, ? )
分析结果: 发送的语句和之前发生了变化, 这些优化都是Hibernate提升自身性能的手段。
转载地址:http://ywqen.baihongyu.com/