`

第十六章 批量插入,多类分页查询

阅读更多
批量插入
有时候我们需要做导入的功能,那么这个时候就需要批量插入数据到数据库,在Hibernate中怎么样达到一个批量插入的效果呢,很简单,请看下面的示例:

我们还是以学生班级为例子
请看下面的配置文件:
Student.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="chapter2.model">
<class name="Student" table="students">
<id name="id" type="string">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="name" type="string">
<column name="name" length="20" />
</property>
<property name="age" type="integer">
<column name="age" />
</property>
<property name="birthday" type="date">
<column name="birthday" length="10" />
</property>
<many-to-one name="myclass" class="Myclass">
<column name="class_id" length="32" />
</many-to-one>
</class>
</hibernate-mapping>
Myclass.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="chapter2.model">
<class name="Myclass" table="my_class">
<id name="id" type="string" column="id" length="32">
<generator class="uuid.hex" />
</id>
<property name="name" type="string">
<column name="name" length="20" />
</property>
<set name="students">
<key column="class_id" />
<one-to-many class="Student" />
</set>
</class>
</hibernate-mapping>

可以看到现在的配置文件和以前有点不一样了,可以看到这里:
<hibernate-mapping package="chapter2.model">
我们给标签加了一个package属性,这里指定了一个包名,那么此时在此文件中就可以不在引用包名,而可以直接使用类名.像我们以前
name="chapter1.model.Student"简写为: class name="Student"
还有就是指定属性类型时的变化:
以前写法: property name="name" type="java.lang.String"
现在写法: property name="name" type="string"
但是请看清楚java.lang.String和string的区别,一个大写,一个小写,可以使用alt+/自动提示将简写的代码提示出来,以下是几个常用的对应关系.
java.lang.String string
java.lang.Integer integer
java.util.Date date

接下来,我们需要做一个操作,向数据库插入十万个学生信息,如果我们还是像以下面的create方法来插入数据,性能上肯定会有很大的问题,因为此时一个事务开始与提交之间只插入了一条数据
public void create(Student student) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(student);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

Hibernate中怎么样批量插入数据呢?
设置批量大小开关:
<property name="jdbc.batch_size">20</property>
保证插入动作在一个事务内完成, 通常批量插入用在导入功能上, 请看下面的示例:
Transaction tx = session.beginTransaction();  
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
        //flush a batch of inserts and release memory:
        //将本批插入的对象立即写入数据库并释放内存
        session.flush();
        session.clear();
    }
}
tx.commit();
批量操作的核心就在于这一块
if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
        //flush a batch of inserts and release memory:
        //将本批插入的对象立即写入数据库并释放内存
        session.flush();
        session.clear();
}
因为在一个事务范围内,只有当tx.commit();事务提交时,数据才会保存到数据库中,并且我们还知道,在一个事务范围内,会有一级缓存存在,当你save一个对象时,就会保存一个对象到一级缓存,如果一级缓存内的对象容量超过了内存剩余容量大小时,就会出现内存溢出的问题,这时,我们就需要到达一定数量的时候就同步数据库,
session.flush();//刷新缓存,将缓存中的内容同步到数据库中
session.clear();//强制清除缓存
这就是批量操作的一个重点.

批量插入的代码:
public void batchCreate(Myclass myclass) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();


for (int i = 0; i < 1000; i++) {
Student student = new Student(myclass, "张三" + i, i, new Date());
session.save(student);
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

多类分页查询:
public List<Student> findByPage(int pageSize, int currentPageNo)
throws Exception {
Session session = null;
Transaction transaction = null;
List<Student> list = new ArrayList<Student>();
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
Query query = session
.createQuery("from Student as s,Myclass as m where s.myclass.id = m.id");
query.setFirstResult((currentPageNo - 1) * pageSize); // 设置开始行数
query.setMaxResults(pageSize); // 设置每页大小
List<Object[]> temp = query.list(); // //这里每一行都是一个1维数组
for (int i = 0; i < temp.size(); i++) {
Object[] objtemp = temp.get(i);

Student student = (Student) (objtemp[0]);
student.setMyclass((Myclass) objtemp[1]);//这一句其实可以不需要
list.add(student);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return list;
}
一定要记住,返回的是一个Object[]数组,塞值给对象时,要记住强转.
分享到:
评论

相关推荐

    2019最新 SSM实现的进销存系统.docx

    第十六讲进货单查看功能设计实现及库存实体、数据库设计实现 第十七讲库存盘点控制器设计及页面设计实现 第十八讲商品批量去重入库功能设计实现 第十九讲库存盘点功能设计实现 第二十讲进货退货单实体、service设计...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    第16章 C#对MongoDB的基本操作实例 16.1 C#快速入门 16.1.1 下载驱动和配置开发环境 16.1.2 访问控制 16.1.3 C#对数据库的基础操作 16.2 C#驱动一致性 16.3 C#常用操作 16.3.1 对MongoDB的操作...

    深入云计算 MongoDB管理与开发实战详解pdf.part2

    第16章 C#对MongoDB的基本操作实例 16.1 C#快速入门 16.1.1 下载驱动和配置开发环境 16.1.2 访问控制 16.1.3 C#对数据库的基础操作 16.2 C#驱动一致性 16.3 C#常用操作 16.3.1 对MongoDB的操作...

    MySQL5 权威指南第3版中文版_part1

     第16章 Perl  16.1 编程技巧  16.2 示例:删除无效的数据记录(mylibrary)  16.3 CGI示例:图书管理(mylibrary)  16.4 CGI Unicode示例  第17章 Java(JDBC和Connector/J)  17.1 基础知识  17.2 程序...

    C#程序开发范例宝典(第2版).part08

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

    MySQL 5权威指南(第3版) 中文版 下载地址

     第16章 Perl  16.1 编程技巧  16.2 示例:删除无效的数据记录(mylibrary)  16.3 CGI示例:图书管理(mylibrary)  16.4 CGI Unicode示例  第17章 Java(JDBC和Connector/J)  17.1 基础知识  17.2...

    PHP程序开发范例宝典III

    第8章 SQL查询相关技术 305 8.1 数据库操作 306 实例193 创建数据库 306 实例194 查看数据库 307 实例195 删除数据库 308 8.2 数据表操作 308 实例196 创建数据表 309 实例197 查看数据表 310 实例...

    C#程序开发范例宝典(第2版).part12

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

    低清版 大型门户网站是这样炼成的.pdf

    5.6.1 批量插入 322 5.6.2 批量更新 323 5.6.3 批量删除 324 5.7 hibernate的事务管理 325 5.7.1 事务边界声明 325 5.7.2 并发控制 326 5.7.3 悲观锁 327 5.7.4 乐观锁 328 5.8 hibernate的缓存机制 332 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    第6章 多线程技术 158 6.1 线程的基础 159 实例123 新建无返回值的线程 159 实例124 查看线程的运行状态 160 实例125 查看JVM中的线程名 161 实例126 查看和修改线程名称 163 实例127 查看和修改线程优先级 165 实例...

Global site tag (gtag.js) - Google Analytics