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()+"\t"+((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()+"\t"+item.getEmps().iterator().next().getEmpName());
            }
        }
复制代码

时间: 2024-10-09 12:10:45

Hibernate 中批量处理数据的相关文章

向mysql中批量插入数据的性能分析

MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下   CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 50 ) NOT NULL,value VARCHAR( 50 ) NOT NULL,other_value VARCHAR( 50 ) NOT NULL) 通常情况下单条插入的sql语句我们会这么写: 代码如下   INSERT INTO example(example_id, name, valu

关于项目中批量修改数据

一.在项目中批量修改数据时应该写一条Update的Sql语句来执行,不能先将所要修改的数据筛选出来,然后再遍历修改. 原因: 1.这样只操作一次数据库,而后者需要操作无数次,性能很差. 2.绕圈子.需要修改数据时直接修改就行,不需要先全部查出来再逐条修改. 3.修改数据时时可以使用join的,例如: 1 update acc set acc.Creator = '滕晓梅' 2 from Accidents acc 3 inner join CompensationCase cc on acc.I

数据库中批量导入数据,有两列的值需要从其他表中查出来,我现在没有思路,求解惑

我现在批量往数据库里导正式数据(sql insert),但是数据中有三列分别是岗位,办事处,大区,给的数据中只给了岗位的值,办事处的值可以通过岗位值在岗位表查到,大区的值可以通过办事处的值在办事处表里查到.现在我已经把其他数据都导进去了,只剩办事处和大区没有值,我该如何批量更新这两列的值啊 导入的数据的表: 岗位表: 办事处表: 本人sql不是很好,希望sql大神能给出来解惑一下,拜谢~ 数据库中批量导入数据,有两列的值需要从其他表中查出来,我现在没有思路,求解惑 >> mysql 这个答案描

.Net中批量更新数据(没有数据就添加)

方法一:使用SqlBulkCopy实现批量更新或添加数据. SqlBulkCopy类一般只能用来将数据批量插入打数据库中,如果数据表中设置了主键,出现重复数据的话会报错,如果没有设置主键,那么将会添加同样的数据,导致数据重复.这里有两种方案可实行方案,实现批量将数据更新到数据表中.如果数据存在,就更新数据:如果不存在,则添加一条新的数据 这两种方案都需要添加一个新的用作临时存储数据的表,假如有两个表 BatchTableTemp和BatchTable, SqlBulkCopy类先批量将数据添加到

.Net中批量添加数据的几种实现方法比较

在.Net中经常会遇到批量添加数据,如将Excel中的数据导入数据库,直接在DataGridView控件中添加数据再保存到数据库等等. 方法一:一条一条循环添加 通常我们的第一反应是采用for或foreach循环一条一条的添加. for (int i = 0; i < dgv.Rows.Count; i++) { string sql = "insert into ....."; SqlHelper.ExcuteNonQuery(CommandType.Text, sql, nu

MyBatis中批量插入数据对插入记录数的限制

<基于Mybatis框架的批量数据插入的性能问题的探讨>(作者:魏静敏 刘欢杰 来源:<计算机光盘软件与应用> 2013 年第 19 期)中提到批量插入的记录数不能超过1000条,实测可以插入超过1000条. 原文地址:https://www.cnblogs.com/huangzejun/p/8143043.html

使用bulkload向hbase中批量写入数据

1.数据样式 写入之前,需要整理以下数据的格式,之后将数据保存到hdfs中,本例使用的样式如下(用tab分开): row1 N row2 M row3 B row4 V row5 N row6 M row7 B 2.代码 假设要将以上样式的数据写入到hbase中,列族为cf,列名为colb,可以使用下面的代码(参考) 1 package com.testdata; 2 3 import java.io.IOException; 4 import org.apache.hadoop.conf.Co

【实验总结二】如何从文本中批量导入数据

前言:我的mysql装的时候没有配置导入数据,所以贸然导入会报错,我可是为那个错误纠结了好久,现在和朋友们分享一下我实验中遇到的坑: mysql --enable-local-infile -u root -p (这一句一定要写,如果网上的方法你都试了一遍仍说和version不兼容的话,一定要试一试这一句). LOAD DATA local INFILE '完整路径' INTO table: 大功告成咯,注意文本中条目之间tab隔开(一个tab就好,忽略对齐问题,要和表的结构对应哦,还有一点,表

MySQL 使用while语句向数据表中批量插入数据

1.创建一张数据表 mysql> create table test_while ( -> id int primary key) charset = utf8; Query OK, 0 rows affected (0.28 sec) 查看数据表的结构 mysql> desc test_while; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Ext