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>
相关文章
相关标签/搜索