• Hibernate多表查询、查询优化策略(四)


    多表HQL

    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)离线查询对象

            //传统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对象的load方法默认就是延迟加载, 可以在对象对应的配置文件中 class节点中配置lazy属性控制是否启用。如果false则会跟get没有任何区别。

        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());
        }

    关联级别查询

      集合关联级别

    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.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"/>
            <!--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>

      关联属性级别

        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>
  • 相关阅读:
    jquery学习笔记
    javascript中的面向对象—— 学习1
    Sql Sever语句 (续2)
    Sql sever 常用语句(续)
    SqlSever 查询基本
    Microsoft SqlSever 数据库--软谋1
    如何编写高质量的Javascript代码
    要当好JavaScript程序员:5个debug技巧
    深入理解js构造函数
    命名空间$.fn
  • 原文地址:https://www.cnblogs.com/baidawei/p/9064758.html
Copyright © 2020-2023  润新知