zoukankan      html  css  js  c++  java
  • Hibernate 中批量处理数据

    一、批量处理操作

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

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

    (2)使用JDBC API进行批量操作  数据库层面

    (3)使用Session进行批量操作   会进缓存

    1.使用HQL进行批量操作

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

    以Emp和Dept为例:

    例:批量添加3个部门

            @Test
        public void addTest(){
            String hql="insert into Dept(deptName) select d.deptName||d.deptNo from Dept d where d.deptNo>0";
            Query query=session.createQuery(hql);
            int count=query.executeUpdate();
            System.out.println("add ok!!");
        }

    输出结果:

    2.使用JDBC  API进行批量操作

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

    例:实现批量修改部门名称

    将部门编号大于3的修改为开发部

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

      @Test
        public void updateTest(){
            final String sql="update Dept set deptname=? where deptno>?";
            Work work=new Work(){
                public void execute(Connection con) throws SQLException{
                    PreparedStatement ps = con.prepareStatement(sql);
                
                    ps.setString(1,"开发部");
                    ps.setInt(2, 3);
                    
                    int count=ps.executeUpdate();
                    //System.out.println(count);
                }
            };
            session.doWork(work);
            System.out.println("update ok!!!");
        
        }
    复制代码

    实现效果:

    3、实现session进行批量操作

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

    例:批量添加15个员工

      /*
         * session 实现批量添加15个员工
         */
        
        @Test
        public void addSessionTest(){
            for(int i=0;i<=15;i++){
                Emp emp=new Emp();
                emp.setEmpName("呵呵"+i);
                
                Dept dept=new Dept();
                dept.setDeptNo(1);
                
                emp.setDept(dept);
                
                session.save(emp);
                
                if(i%10==0){
                    session.flush();
                    session.clear();
                }
            }
            System.out.println("add ok!!");
        }
    复制代码

    输出结果:

    二、HQL连接查询

    HQL提供的连接方式如下表所示:

    内连接:

    语法:

    from Entity inner join Entity.property

    例:使用内连接查询员工隶属的部门

    list集合中的每个元素都是一个Object数组,from后面紧接的是部门 则输出的先是部门的内存地址

        /*
          * 内连接  员工隶属的部门
          */
        
        @Test
        public void innerTest(){
            
            Query query=session.createQuery("from Dept d inner join d.emps");
              List<Object[]> list = query.list();
              for (Object[] item : list) {
                  //一个item就是一个数组
                 System.out.println(((Dept)item[0]).getDeptName()+"	"+((Emp)item[1]).getEmpName());
              }
              
        }

    输出结果:

    隐式内连接:

    在HQL查询语句中,如果对Emp类赋别名为”e”,可以通过e.dept.deptName的形式访问dept对象的deptName属性。使用隐式内连接按部门查询员工信息。

    例:按部门条件查询员工信息

      /*
         * 隐式内连接 按部门条件查询员工信息
         */
            
            @Test
            public void hideTest(){
                
                Query query=session.createQuery("from Emp e where e.dept.deptName='开发部'");
                  List<Emp> list = query.list();
                  for (Emp item : list) {
                      //一个item就是一个数组
                     System.out.println(item.getEmpName());
                  }
            }
            

    输出结果:

    3、迫切内连接

    例:查询所有的雇员名称和隶属部门名称  需使用关键字fetch

      /*
             * 迫切内连接  查询所有的雇员名称和隶属部门名称 
             */
            
            @Test
            public void FetchTest(){
                Query query=session.createQuery("from Dept d inner join fetch d.emps");
                List<Dept> list=query.list();
                for (Dept item : list) {
                    System.out.println(item.getDeptName()+"	"+item.getEmps().iterator().next().getEmpName());
                }
            }
    复制代码

  • 相关阅读:
    《构建之法》阅读笔记02
    《构建之法》阅读笔记01
    学习进度
    “校园知网”端午假期冲刺计划书
    学习进度
    计算最长英语单词链
    第一周冲刺_周日总结
    构建之法阅读笔记03
    第一周冲刺_周六总结
    软件工程概论第十四周学习进度
  • 原文地址:https://www.cnblogs.com/ckwblogs/p/6376933.html
Copyright © 2011-2022 走看看