zoukankan      html  css  js  c++  java
  • HQL连接查询

    HQL提供了连接查询机制如内连接,外连接,,还允许显示指定迫切内连接,和迫切外联结。

    连接类型

    内连接 inner join 或join

    迫切内链接 inner join fetch

    左外联结  left outer join 或 join

    迫切左外连接 left outer join fetch 或 left join fetch

    右外连接 right outer join 或 right join

    1.内连接

     @Test
        //02.隐式内连接
        public void testHideInnerJoin(){
            Query query = session.createQuery("from Emp e where e.dept.deptName='开发部'");
            List<Emp> list = query.list();
            for (Emp emp : list) {
                System.out.println(emp.getEmpName());
            }
        }

    2.迫切内连接

     @Test
        public void innerJoinTest(){
            Query query = session.createQuery("select distinct d from Dept d inner join  d.emps");
            List<Dept> list = query.list();
            for (Dept dept : list) {
         System.out.println(dept.getDeptName());
                for (Emp emp : dept.getEmps()) {
                    System.out.println(emp.getEmpName());
                }
            }
        }

    3.左外连接

    from Entity left join [fetch] Entity.propert

    右外连接

     from Entity right join Entity.property

    注意:fetch关键字只对inner join 和 left join 有效。对于righ join 而言,由于作为关联对象

    容器的“左边”对象可能为null,所以也就是无法通过fatch关键字强制Hibernate进行填充操作。

    二,查询性能优化

    1.Hibernate主要从以下方面查询性能。

    使用迫切左外连接或迫切内连接查询缓存方式,减少select语句的数目,降低访问数据库的频率。

    2.使用延迟加载策略方式避免加载多余的不需要访问的数据。

    3.使用Query接口的iterator()方法减少select语句中的字段,从而降低访问数据库的数据量。

     解析:第一次使用list()方法查询时,Hibernate从数据库查询Emp,对象,把所有的Emp对象放入Session缓存中,第二次使用list()查询shi2,Hibernate仍然从数据库查询Emp对象,而不是从Session缓存中获取Emp对象。

    HQL优化:

    HQL优化是Hibernate程序性能优化的一个方面HQL的语法与SQL非常相似。HQL是基于SQL的,只是增加了面向对象的封装。如果抛开HQLHibernate本身一些缓存机制的关联,HQL的优化技巧同SQL的优化技巧一样。在编写HQL时,需注意以下几个原则:

    (1)避免or操作的使用不当

    (2)避免使用not

    (3)避免使用like的特殊形式,例如 “%”或者”_”开头

    (4)避免having字句

    (5)避免distinct

    (6)索引在以下情况下失效,应注意使用

       1.只要对字段使用函数,该字段的索引将不起作用,如substring(aa,1,2)=’xx’

       2.只要对字段进行计算,该字段的索引将不起作用,如Price+10

    三批量处理数据
    批量处理数据是指在一个事务场景中处理大量数据。在应用程序中难以避免进行批量操作,Hibernate提供了一下方式进行批量处理数据。

    1.使用HQL进行批量操作 数据层面 executeUpdate()

    1.使用HQL进行批量操作

        HQL可以查询数据,也可以批量插入、更新和删除数据。HQL批量操作实际上直接在数据库中完成,处理的数据不需要加载到 Session缓存中。使用Query接口的executeUpdate()方法执行用于插入、更新和删除的HQL语句。

    01批量插入数据

     @Test
        //03.HQL 批量添加
        public void multiInsertTest(){
            String hql="insert into Dept(deptName) select d.deptName||d.deptNo from Dept d where d.deptNo>0";
            session.createQuery(hql).executeUpdate();
        }

    02.批量更新数据  @Test
        //03.HQL 批量修改
        public void multiUpdateTest(){
            String hql="update Dept set deptName=:name where deptNo>2";
            session.createQuery(hql).setParameter("name","财务部").executeUpdate();
        }

    03.批量删除

       @Test
        //03.HQL 批量删除
        public void multiDeleteTest(){
            String hql="delete from Dept d where d.deptNo>:deptNo";
            session.createQuery(hql).setParameter("deptNo",20).executeUpdate();
        }

    2.使用JDBC API进行操作。数据库层面

    Hibernate应用中使用JDBC API批量执行插入、修改和删除语句时,需要使用SessiondoWork(Work work)方法执行Work对象指定的操作,即调用Work对象的execute()方法。Session把当前使用的数据库连接传给execute()方法,执行持久化操作。

      @Test
        //04.JDBC API 批量修改
        public void insertTest(){
            Work work=new Work() {
                public void execute(Connection connection) throws SQLException {
                    PreparedStatement ps = connection.prepareStatement("update DEPTY2163Session  set deptName='业务部'where DEPTNO>?");
                    ps.setInt(1,1);
                    ps.executeUpdate();
                }
            };
            //session
            session.doWork(work);
        }

    注意:该方式使用的连接依然是最初的连接对象,并且命令对象依然是根据连接创建的,注意这里是SQL语句,不是HQL语句

    3。使用Session 进行操作 会进缓存。

    使用Session对象也可以进行批量操作。使用Session对象处理大量持久化对象,需及时从缓存中清空已经处理完毕并且不会再访问的对象。可以在处理完成一个对象或小批量对象后,调用flush()方法强制同步缓存和数据库,然后调用clear()方法清空缓存。

     //05.Session 方案 进入缓存
        @Test
        public void insertUseSessionTest() {
            Emp emp=null;
            for (int i = 0; i < 100; i++) {
                emp=new Emp(i, "emp"+i);
                session.save(emp);
                if (i%30==0) {
                    session.flush();
                    session.clear();
                }
            }
        }

  • 相关阅读:
    技术文章应该怎么写?
    后退时保存表单状态
    [原]长表头表格 竖直仅滚动内容区 水平滚动表头和内容区
    IE7不经提示关闭浏览器窗口
    meta 标记
    demo : 简单的 xslt 递归解析 xml 成 tree
    使用iframe和table模拟frameset的resize功能.html
    一个下划线(_)引发的"疑难杂症"
    几点小东西
    使用 ActiveReports 的 subReport 几点疑惑
  • 原文地址:https://www.cnblogs.com/xiaoyu1997/p/6378182.html
Copyright © 2011-2022 走看看