- 浏览: 35249 次
- 性别:
- 来自: 浮云
文章分类
最新评论
-
ReusCMD:
写得很好, 很有用, 支持一下!!!
notepad++ 运行 Java 程序 -
Mr0o0rM:
...
SP CP -
659的典藏:
mhnewer 写道回复:
w
服务器港:w
回复:
w
...
java socket -
nrxqq:
在传输中文的时候貌似会乱码怎么解决呀
java socket -
weilJava:
在公司有些资源限制了,故下载不了,如果你的插件比较全,就都给我 ...
notepad++ 运行 Java 程序
系统环境:
MySQL 数据库环境:
eclipse 运行时参数:
使用 Spring 2.5、Hibernate3.3
Entity:
applicationContext.xml:
hibernate.cfg.xml:
log4j.properties:
HibernateDAO.java:
CommonServiceImpl.java:
Test.java:
结果:
SQL 生成语句如下:
不使用批量
1W: 耗费时间: 3.65 秒 内存占用见下图
10W: 耗费时间: 33.844 秒
50W : outOfMemory
30条为一个周期, 也就是将 if (i % 30 == 0) 这段注释解开
1W: 耗费时间: 3.797 秒. 查看内存, 这个时间就明显的感觉到运行时的压力已经有一些转换到数据库上面来了(运行时看得更清楚一些)
MySQL 的进程没能抓到图, 而且其是在运行时耗的资源. 也并不是很大, 比上图要小
10W: 耗费时间: 34.922 秒
50W: 耗费时间: 182.531 秒
100W outOfMemory
50条为一个周期, 即将上面的 30 改为 50
1W: 耗费时间: 3.625 秒
10W: 耗费时间: 32.031 秒
50W: 耗费时间: 161.391 秒
100W 同样 outOfMemory .
一路看下来, 我并不觉得 Hibernate 有多慢. 4秒以内处理 1W 条数据 . 至于内存溢出, 还是因为在 循环里面 new 了太多的对象, 尽管处理完我就将其引用指向 null 并显式调用 gc , 但 JVM 内部运行 gc 是异步的...
当然 性能上使用 50批量 的策略会好很多, 可以将压力让 服务器 和 数据库 同时去承担 .
保存下来再去测试 jdbc 批量看看...
使用 jdbc 测试:
在 applicationContext.xml 中添加:
JdbcDAO.java:
JdbcService.java:
TestJdbc.java: (这里很郁闷, 我用的 Junit 4.6 版本, 在上面的测试中正常. 在这里异常, 换成 4.4 就好了)
结果如下:
不使用批量:
1W: 耗费时间: 3.359 秒(这个效率确实比 Hibernate 要高)
10W: 耗费时间: 212.812 秒 (我不确定是不是我 jdbc的代码写得不够好, 反正这个效率让我很是郁闷)
50W 的时候我已经没有耐心再等下去了. 11 分钟过去了还没看到结果
使用30条一次批量
说实话, 这个时候的性能已经让我到了一种发狂的地步.
接近 3 秒 运行 100 条 . 1W 条数据花了 288.266 秒的时间
是的, 你没有看错, 就是 3 秒运行 100 条, 到后面的 50 我也就没有再继续测下去.
也可能是我 jdbc 代码写得不对吧. 毕竟 hibernate 底层也是用的 jdbc, 其再快也是不可能快过 Native SQL, 我这个贴的目的也只是想了解下差距的多少, 只是这个效率...
如果哪位有过 jdbc 方面的操作, 给个提醒...
谢谢.
1. 我在测试 Hibernate 的时候写过
以上代码也只是想让 gc 整理 循环体内部因为申明太多指向跟 new 太多对象造成的内存溢出
2. 的确, 直接执行 pstm.execute(); 是直接执行, 不是批量了! 如果要批量的话, 应该像下面这样:
哪天我再测一下, 这还是去年在公司测的. 一直没动过
MySQL 数据库环境:
mysql> select version(); -------------- select version() -------------- +----------------------+ | version() | +----------------------+ | 5.1.41-community-log | +----------------------+ 1 row in set (0.00 sec)
eclipse 运行时参数:
--launcher.XXMaxPermSize 256M -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m -vm C:/Program Files/Java/jdk1.6.0_18/bin/javaw -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m
使用 Spring 2.5、Hibernate3.3
Entity:
package com.model; import java.io.Serializable; import java.sql.Timestamp; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; /** * @author <a href="liu.anxin13@gmail.com">Tony</a> */ @Entity @Table(name = "T_USERINFO") @org.hibernate.annotations.Entity(selectBeforeUpdate = true, dynamicInsert = true, dynamicUpdate = true) public class UserInfo implements Serializable { private static final long serialVersionUID = -4855456169220894250L; @Id @Column(name = "ID", length = 32) private String id = java.util.UUID.randomUUID().toString().replaceAll("-", ""); @Column(name = "CREATE_TIME", updatable = false) private Timestamp createTime = new Timestamp(System.currentTimeMillis()); @Column(name = "UPDATE_TIME", insertable = false) private Timestamp updateTime = new Timestamp(System.currentTimeMillis()); // setter/getter... }
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:component-scan base-package="com.dao,com.service" /> <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxPoolSize" value="50" /> <property name="minPoolSize" value="2" /> <property name="initialPoolSize" value="5" /> <property name="acquireIncrement" value="5" /> <property name="maxIdleTime" value="1800" /> <property name="idleConnectionTestPeriod" value="1800" /> <property name="maxStatements" value="1000"/> <property name="breakAfterAcquireFailure" value="true" /> <property name="testConnectionOnCheckin" value="true" /> <property name="testConnectionOnCheckout" value="false" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" isolation="READ_COMMITTED" rollback-for="Throwable" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="services" expression="execution(* com.service.*.*.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="services" /> </aop:config> </beans>
hibernate.cfg.xml:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- 默认 15, 这是我个人不能完全理解的参数, 不明白这个参数的实际意义 --> <!-- <property name="hibernate.jdbc.batch_size">50</property> --> <!-- 排序插入和更新, 避免出现 锁si --> <property name="hibernate.order_inserts">true</property> <property name="hibernate.order_updates">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">false</property> <property name="hibernate.format_sql">false</property> <property name="hibernate.current_session_context_class"> org.hibernate.context.JTASessionContext </property> <mapping class="com.model.UserInfo" /> </session-factory> </hibernate-configuration>
log4j.properties:
log4j.rootLogger=INFO, CONS log4j.appender.CONS=org.apache.log4j.ConsoleAppender log4j.appender.CONS.layout=org.apache.log4j.PatternLayout log4j.appender.CONS.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss sss} [%p] %r %l [%t] %x - %m%n # log4j.logger.org.springframework=WARN # log4j.logger.org.hibernate=WARN # log4j.logger.com.mchange=WARN
HibernateDAO.java:
package com.dao; import java.io.Serializable; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; @Repository public class HibernateDAO { private static final Logger log = Logger.getLogger(HibernateDAO.class); @Autowired private HibernateTemplate template; public Serializable save(Object entity) { try { return template.save(entity); } catch (Exception e) { log.info("save exception : " + e.getMessage()); // 异常的目的只是为了记录日志 throw new RuntimeException(e); } } }
CommonServiceImpl.java:
package com.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.dao.HibernateDAO; import com.model.UserInfo; @Service("commonService") public class CommonService { private static final Logger log = Logger.getLogger(CommonService.class); @Autowired private HibernateDAO dao; public void testOcean(long num) { for (int i = 0; i < num; i++) { // 在循环中 new 大量对象. 此为 outOfMemory 的根源 // 将 user 申明在 循环外面, 循环体内部才将其指向具体的对象, 这样可以提高一点效率 UserInfo user = new UserInfo(); dao.save(user); user = null; // 实际意义不大, 就算手动运行, gc 也是异步的, 没有办法控制 if (i % 100000 == 0) System.gc(); /* if (i % 30 == 0) { dao.flush(); dao.clear(); } */ } } }
Test.java:
package com; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.service.CommonService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/applicationContext.xml" }) public class TestHibernate { @Autowired @Qualifier("commonService") private CommonService service; private static final Logger log = Logger.getLogger(TestHibernate.class); @Test public void testHibernate() { // 海量数据的条数. 分别以 1W, 10W, 50W, 100W 为数值 // 虽然都算不上海量, 但做为测试也应该算够了吧 long num = 10000; log.info("开始"); long begin = System.currentTimeMillis(); service.testOcean(num); long end = System.currentTimeMillis(); log.info("耗费时间: " + num + " 条. " + (end - begin) / 1000.00000000 + " 秒"); System.out.println("赶紧查看内存"); try { Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } } }
结果:
SQL 生成语句如下:
Hibernate: insert into T_USERINFO (CREATE_TIME, ID) values (?, ?)
不使用批量
1W: 耗费时间: 3.65 秒 内存占用见下图
10W: 耗费时间: 33.844 秒
50W : outOfMemory
30条为一个周期, 也就是将 if (i % 30 == 0) 这段注释解开
1W: 耗费时间: 3.797 秒. 查看内存, 这个时间就明显的感觉到运行时的压力已经有一些转换到数据库上面来了(运行时看得更清楚一些)
MySQL 的进程没能抓到图, 而且其是在运行时耗的资源. 也并不是很大, 比上图要小
10W: 耗费时间: 34.922 秒
50W: 耗费时间: 182.531 秒
100W outOfMemory
50条为一个周期, 即将上面的 30 改为 50
1W: 耗费时间: 3.625 秒
10W: 耗费时间: 32.031 秒
50W: 耗费时间: 161.391 秒
100W 同样 outOfMemory .
一路看下来, 我并不觉得 Hibernate 有多慢. 4秒以内处理 1W 条数据 . 至于内存溢出, 还是因为在 循环里面 new 了太多的对象, 尽管处理完我就将其引用指向 null 并显式调用 gc , 但 JVM 内部运行 gc 是异步的...
当然 性能上使用 50批量 的策略会好很多, 可以将压力让 服务器 和 数据库 同时去承担 .
保存下来再去测试 jdbc 批量看看...
使用 jdbc 测试:
在 applicationContext.xml 中添加:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>
JdbcDAO.java:
package com.dao; import java.sql.Connection; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class JdbcDAO { private static final Logger log = Logger.getLogger(JdbcDAO.class); @Autowired private JdbcTemplate template; public Connection getConn() { try { return template.getDataSource().getConnection(); } catch (Exception e) { log.info("获取连接时异常: " + e.getMessage()); throw new RuntimeException(e); } } }
JdbcService.java:
package com.service; import java.sql.Connection; import java.sql.PreparedStatement; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.dao.JdbcDAO; import com.model.UserInfo; @Service("jdbcService") public class JdbcService { private static final Logger log = Logger.getLogger(JdbcService.class); @Autowired private JdbcDAO dao; public void testOcean(long num) { Connection conn = dao.getConn(); try { conn.setAutoCommit(false); String sql = "insert into T_USERINFO(CREATE_TIME, ID) values(?, ?)"; PreparedStatement pstm = conn.prepareStatement(sql); for (int i = 0; i < num; i++) { // 要保证公平, 也在循环中 new 对象 UserInfo user = new UserInfo(); pstm.setTimestamp(1, user.getCreateTime()); pstm.setString(2, user.getId()); pstm.execute(); user = null; if (i % 10000 == 0) System.gc(); // 批处理 /* if (i % 30 == 0) { pstm.executeBatch(); conn.commit(); pstm.clearBatch(); } */ } // 将循环里面的批处理解开后, 就要将此处的commit注释, 并将下面注释的语句解开 conn.commit(); // pstm.executeBatch(); } catch (Exception e) { log.info("异常: " + e.getMessage()); } finally { try { conn.close(); } catch (Exception e) { conn = null; } } } }
TestJdbc.java: (这里很郁闷, 我用的 Junit 4.6 版本, 在上面的测试中正常. 在这里异常, 换成 4.4 就好了)
package com; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.service.JdbcService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/applicationContext.xml" }) public class TestJdbc { private static final Logger log = Logger.getLogger(TestJdbc.class); @Autowired @Qualifier("jdbcService") private JdbcService service; @Test public void testJdbc() { long num = 500000; log.info("开始"); long begin = System.currentTimeMillis(); service.testOcean(num); long end = System.currentTimeMillis(); log.info("耗费时间: " + num + " 条. " + (end - begin) / 1000.00000000 + " 秒"); System.out.println("赶紧查看内存"); try { Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } } }
结果如下:
不使用批量:
1W: 耗费时间: 3.359 秒(这个效率确实比 Hibernate 要高)
10W: 耗费时间: 212.812 秒 (我不确定是不是我 jdbc的代码写得不够好, 反正这个效率让我很是郁闷)
50W 的时候我已经没有耐心再等下去了. 11 分钟过去了还没看到结果
使用30条一次批量
说实话, 这个时候的性能已经让我到了一种发狂的地步.
接近 3 秒 运行 100 条 . 1W 条数据花了 288.266 秒的时间
是的, 你没有看错, 就是 3 秒运行 100 条, 到后面的 50 我也就没有再继续测下去.
也可能是我 jdbc 代码写得不对吧. 毕竟 hibernate 底层也是用的 jdbc, 其再快也是不可能快过 Native SQL, 我这个贴的目的也只是想了解下差距的多少, 只是这个效率...
如果哪位有过 jdbc 方面的操作, 给个提醒...
谢谢.
评论
4 楼
bushkarl
2010-08-23
3 楼
yhailj
2010-08-22
peterwei 写道
我的机器配置是1.8G的老机子,差不多800M内存。你想想都比你的快那么多,肯定是你哪写得不对了。
1.if (i % 10000 == 0)
System.gc(); 这个没什么用吧
2.没看见有ps.addBatch();我的有的,而用ps不用批处理时用的是executeUpdate();
3.就算我在里面new东西,50w也只是多了10秒不到。
你可以仔细看一下我的代码。
1.if (i % 10000 == 0)
System.gc(); 这个没什么用吧
2.没看见有ps.addBatch();我的有的,而用ps不用批处理时用的是executeUpdate();
3.就算我在里面new东西,50w也只是多了10秒不到。
你可以仔细看一下我的代码。
1. 我在测试 Hibernate 的时候写过
// 实际意义不大, 就算手动运行, gc 也是异步的, 没有办法控制 if (i % 10000 == 0) System.gc();
以上代码也只是想让 gc 整理 循环体内部因为申明太多指向跟 new 太多对象造成的内存溢出
2. 的确, 直接执行 pstm.execute(); 是直接执行, 不是批量了! 如果要批量的话, 应该像下面这样:
for (int i = 0; i < num; i++) { // 要保证公平, 也在循环中 new 对象 UserInfo user = new UserInfo(); pstm.setTimestamp(1, user.getCreateTime()); pstm.setString(2, user.getId()); pstm.addBatch(); user = null; if (i % 10000 == 0) System.gc(); // 批处理 if (i % 30 == 0) { pstm.executeBatch(); conn.commit(); pstm.clearBatch(); } } pstm.executeBatch(); conn.commit();
哪天我再测一下, 这还是去年在公司测的. 一直没动过
2 楼
peterwei
2010-08-22
我的机器配置是1.8G的老机子,差不多800M内存。你想想都比你的快那么多,肯定是你哪写得不对了。
1.if (i % 10000 == 0)
System.gc(); 这个没什么用吧
2.没看见有ps.addBatch();我的有的,而用ps不用批处理时用的是executeUpdate();
3.就算我在里面new东西,50w也只是多了10秒不到。
你可以仔细看一下我的代码。
1.if (i % 10000 == 0)
System.gc(); 这个没什么用吧
2.没看见有ps.addBatch();我的有的,而用ps不用批处理时用的是executeUpdate();
3.就算我在里面new东西,50w也只是多了10秒不到。
你可以仔细看一下我的代码。
1 楼
peterwei
2010-08-22
你的用法有问题吧,这个要靠你多试试多种情况。我的机子比你差多了。还没你说的情况。我的测试如下:
================================
清空表
通过PrepareStatement插入数据:
插入数据量:500000
<运行时间: 96.266 秒>
运行时间:96266 毫秒
96.266
================================
清空表
用批处理插入数据:
批量更新成功 500000 条记录!
<运行时间: 96.515 秒>
运行时间:96515 毫秒
96.515
================================
你可以看看我的blog,我也写了个测试jdbc性能的。
================================
清空表
通过PrepareStatement插入数据:
插入数据量:500000
<运行时间: 96.266 秒>
运行时间:96266 毫秒
96.266
================================
清空表
用批处理插入数据:
批量更新成功 500000 条记录!
<运行时间: 96.515 秒>
运行时间:96515 毫秒
96.515
================================
你可以看看我的blog,我也写了个测试jdbc性能的。
相关推荐
### JDBC与Hibernate的比较 在软件开发领域,尤其是在基于Java的应用程序中,数据库访问技术的选择对项目的成功至关重要。本文将详细探讨两种常见的Java数据库访问方式:JDBC(Java Database Connectivity)与...
此外,Hibernate支持缓存机制,可以通过二级缓存提高性能,尤其是在查询小部分数据时,Iterator方式的效率较高。 对于数据状态,JDBC操作的数据通常是瞬时的,需要开发者手动同步数据库和内存中的数据。而Hibernate...
标题"hibernate入门数据简单插入"指的是使用Hibernate框架进行数据库的基本操作,特别是数据的插入。Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者在应用程序中处理数据库对象,而无需直接编写...
本篇将详细探讨“Hibernate插入数据”的相关知识点,结合学习心得,深入理解并掌握其核心原理与实践技巧。 首先,Hibernate通过对象关系映射(ORM)技术,将数据库表与Java类关联起来,使得数据库操作可以通过对象...
在使用Hibernate时,需要配置正确的JDBC驱动,以便Hibernate能与KingbaseV8数据库建立连接。KingbaseV8的JDBC驱动通常包括对应的jar文件,例如:kingbase-jdbc.jar,这个文件应被添加到项目的类路径中。 在提供的...
当涉及到与Microsoft Access数据库的交互时,Hibernate同样能够提供支持,但需要相应的JDBC驱动。在这个场景中,"hibernate 链接access数据的jdbc驱动包"就是用来建立Hibernate与Access数据库连接的关键组件。 首先...
3. **数据状态**:JDBC操作的数据是瞬时的,数据库与内存中的数据可能不一致,而Hibernate提供了一种对象-关系映射机制,使得数据具有持久性,能够保持数据库与对象的一致性。 **性能比较:** 1. **创建操作**:...
总之,“hibernate+junit+mysql-jdbc开发核心jar包三合一”是Java Web开发中的关键组件,它们共同构成了数据持久化、单元测试和数据库连接的基础。掌握这些工具的使用,对于提升开发效率和保证软件质量具有重要意义...
标题中的“本人理解hibernate 与 JDBC 的最本质区别”揭示了我们即将探讨的核心主题:Hibernate 和 JDBC 在处理数据库操作时的不同之处。 Hibernate 是一个对象关系映射(ORM)框架,而 JDBC(Java Database ...
在这些场景中,如果使用传统的 INSERT 语句逐条插入数据,会导致性能下降和内存溢出问题。因此,使用批量更新机制可以大大提高性能和降低内存占用。 Hibernate 的批量更新机制 Hibernate 提供了两种批量更新机制:...
Hibernate通过JDBC与数据库进行通信,执行SQL语句。在Hibernate中,JDBC驱动程序是必要的,以便应用程序能够连接到特定的数据库。例如,"mysql-connector-java-3.1.13-bin.jar"就是MySQL的JDBC驱动,用于连接到MySQL...
### JDBC与Oracle BLOB的交互 #### 1. 理解Oracle BLOB特性 在Oracle中,BLOB用于存储大量的二进制数据,如图像文件。与传统的文本或数字字段不同,BLOB字段有自己的游标(Cursor),这使得直接写入数据变得复杂。...
Hibernate与JDBC对于数据库的性能操作对比事例,配置,更多信息资源
- **性能问题**:对于某些复杂查询,Hibernate可能无法达到最佳性能,尤其是在处理大量数据时。 - **学习曲线**:虽然Hibernate简化了许多操作,但对于新手来说,理解其核心概念和配置仍需一定时间。 - **灵活性限制...
当处理大量的数据时,使用`Iterator`而不是`List`来遍历结果集可以节省大量的内存资源。这是因为`Iterator`在每次调用`next()`方法时只会加载当前的记录,而不会一次性加载所有的结果到内存中。这种方式特别适用于...
4. **Hibernate与JDBC比较**: - Hibernate抽象了数据库层,使代码更简洁,降低了维护成本。 - Hibernate提高了开发效率,减少了SQL编写工作。 - Hibernate的查询优化可能不如直接手写的SQL,但在大部分场景下...
最近自学java中的框架-struts写了一些小例子,这都是很经典的程序,如果大家瞧得起要下载去看看,顺便给俺找找不足的地方。我的qq 821865130 email qingtian_hechen@163.com 希望大家能多多给我帮助...在此谢谢各位!!
虽然Hibernate可以简化数据操作,但在某些复杂查询或性能优化时,开发者可能直接使用JDBC编写SQL语句以获取更高的灵活性和效率。在双表查询中,JDBC可以用于编写自定义的JOIN查询,以满足特定的需求。 在实际项目中...
在上述例子中,当尝试向数据库插入100,000条数据时,由于默认情况下Hibernate会将所有持久化对象保留在一级缓存中,随着数据量的增加,内存消耗也会迅速增长,最终导致内存溢出。因此,我们需要对一级缓存进行管理。...