Hibernate多表查詢、查詢優化策略(四)

多表HQLweb

private static void innerJoin(){
        //sql內鏈接  隱式內鏈接 select * from A,B where b.aid = a.id
        //          顯示內鏈接 select * from A inner join B on b.aid = a.id
        //hql內鏈接 =>相似原生sql 返回合併的
        Query query = session.createQuery("from Category c inner join c.products");
        List<Object> objs = query.list();
        for(Object o : objs){
            System.out.println(o);
        }
    }
    private static void innerJoinfetch(){
        //迫切hql內鏈接 =>幫我進行封裝
        Query query = session.createQuery("from Category c inner join fetch c.products");
        List<Category> categorys = query.list();
        for(Category o : categorys){
            System.out.println(o.getCname());
            for(Product p : o.getProducts()){
                System.out.println(p.getPname());
            }
        }
    }
    private static void leftJoin(){
        //外鏈接 左外鏈接 select * from A left [outer] join B on b.aid = a.id
        //hql 左鏈接
        Query query = session.createQuery("from Category c left join c.products");
        List<Object> objs = query.list();
        for(Object o : objs){
            System.out.println(o);
        }
    }

    private static void leftJoinfetch(){
        //hql 左鏈接 迫切
        Query query = session.createQuery("from Category c left join fetch c.products");
        List<Category> categorys = query.list();
        for(Category o : categorys){
            System.out.println(o.getCname());
            for(Product p : o.getProducts()){
                System.out.println(p.getPname());
            }
        }
    }
    private static void rightJoin(){
        //外鏈接 右外鏈接 select * from A right [outer] join B on b.aid = a.id
        //hql右鏈接
        Query query = session.createQuery("from Category c right join c.products");
        List<Object> objs = query.list();
        for(Object o : objs){
            System.out.println(o);
        }
    }

    private static void rightJoinfetch(){
        //外鏈接 右外鏈接 select * from A right [outer] join B on b.aid = a.id
        //hql右鏈接 迫切
        Query query = session.createQuery("from Category c right join fetch c.products");
        List<Category> categorys = query.list();
        for(Category o : categorys){
            System.out.println(o.getCname());
            for(Product p : o.getProducts()){
                System.out.println(p.getPname());
            }
        }
    }

 

Criteria(QBC)離線查詢對象sql

        //傳統criteria是依賴於session的
        Criteria criteria = session.createCriteria(Category.class);
        criteria.add(Restrictions.eq("cid",1));
        Category c = (Category) criteria.uniqueResult();
        System.out.println(c.getCname());

        //離線的criteria 憑空建立
        //service/web層
        DetachedCriteria dc = DetachedCriteria.forClass(Category.class);
        dc.add(Restrictions.gt("cid",0));
        //dao層
        Criteria criter = dc.getExecutableCriteria(session);
        List<Category> categories =  criteria.list();
        for(Category ca : categories){
            System.out.println(ca.getCname());
            for(Product p : ca.getProducts()){
                System.out.println(p.getPname());
            }
        }

 

查詢優化策略數據庫

懶加載(延遲加載):使用hibernate查詢一個對象的時候,查詢其關聯對象,應該如何查詢。是hibernate的一種優化手段。session

類級別查詢app

  session對象的load方法默認就是延遲加載, 能夠在對象對應的配置文件中 class節點中配置lazy屬性控制是否啓用。若是false則會跟get沒有任何區別。dom

    public static void main(String[] args) {
        Session session = HibernateUtils.openSession();
        //get方法:當即加載,執行時當即發送sql語句
        Category c = session.get(Category.class,1);
        System.out.println(c);

        //延遲加載:僅僅得到沒有使用,不會查詢 返回代理對象
        Category c1 = session.load(Category.class,2);
        //在使用對象的屬性時纔會進行查詢
        System.out.println(c1.getCname());
    }

關聯級別查詢fetch

  集合關聯級別優化

public static void main(String[] args) {
        Session session = HibernateUtils.openSession();
        //只返回Category表
        Category c = session.get(Category.class,1);
        System.out.println(c.getCname());
        //懶加載 與此Category表相關聯的Product表 使用時 纔去加載
        Set<Product> ps  = c.getProducts(); //集合關聯級別
        for(Product p : ps){
            System.out.println(p.getPname());
        }

    }

附上配置文件Category.hbm.xmlspa

<hibernate-mapping package="com.hibernate.domain">
    <class name="Category" table="Category" lazy="true">
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <property name="cname"/>
        <!--lazy:集合關聯級別 是否懶加載 true(默認) false extra(極其懶惰-若是隻得到集合的size,他會用count去查詢)
            fetch(加載策略-使用什麼類型的sql語句加載集合數據):
                select(默認):單表查詢加載
                join:使用多表查詢加載集合(不管是否啓用懶加載,都一下多表查詢回來)
                subselect:使用子查詢加載集合(調用集合時,使用子查詢語句)
            -->
        <set name="products" inverse="true" lazy="true" fetch="select">
            <key column="cpid"></key>
            <one-to-many class="Product"></one-to-many>
        </set>
    </class>
</hibernate-mapping>

  關聯屬性級別hibernate

    public static void main(String[] args) {
        Session session = HibernateUtils.openSession();
        Product p = session.get(Product.class,1);
        //根據產品去得到分類信息 執行以下時纔會去數據庫獲取
        Category c = p.getCategory(); //屬性關聯級別
        System.out.println(c.getCname());
    }

  配置xml解析

<hibernate-mapping package="com.hibernate.domain">
    <class name="Product" table="Product">
        <id name="pid">
            <generator class="native"/>
        </id>
        <property name="pname"/>

        <!--fetch(加載的sql語句):
                select(默認):使用單表查詢
                join:使用多表查詢
            lazy(加載時機):
                proxy(默認):由Category的類級別加載策略(Category中 class元素中 lazy)決定
                false:當即加載
        -->
        <many-to-one name="category" class="Category" column="cpid" fetch="" lazy=""></many-to-one>
    </class>
</hibernate-mapping>

 

批量抓取

public static void main(String[] args) {
        Session session = HibernateUtils.openSession();
        Query query = session.createQuery("from Category");
        List<Category> categories = query.list();
        for(Category c : categories){
            for(Product p : c.getProducts()){ //categories數量爲幾 這裏就要執行幾回sql查詢c.getProducts()
                System.out.println(p.getPname());
            }
        }
    }

category.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
    <class name="Category" table="Category" lazy="true">
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <property name="cname"/>
        <!--batch-size:查詢集合時一次查詢多少個 默認1個 因此每次都會生成sql語句 -->
        <set name="products" inverse="true" lazy="true" fetch="select" batch-size="10">
            <key column="cpid"></key>
            <one-to-many class="Product"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
相關文章
相關標籤/搜索