Java 使用弹簧复位连接+;冬眠
我在JavaEE项目中使用Spring+Hibernate 在这个项目中,用户可以上传一个XLS文件,我应该将其导入我的数据库。在导入之前,我必须验证此文件,并检查其与数据库中其他实体的完整性。因此,我大致有以下几点:Java 使用弹簧复位连接+;冬眠,java,hibernate,spring-mvc,jpa,entitymanager,Java,Hibernate,Spring Mvc,Jpa,Entitymanager,我在JavaEE项目中使用Spring+Hibernate 在这个项目中,用户可以上传一个XLS文件,我应该将其导入我的数据库。在导入之前,我必须验证此文件,并检查其与数据库中其他实体的完整性。因此,我大致有以下几点: // The importer @Component("importer") public class Importer { @Autowired FirstDAO firstDao; @Autowired SecondDAO secondDa
// The importer
@Component("importer")
public class Importer {
@Autowired
FirstDAO firstDao;
@Autowired
SecondDAO secondDao;
// Read the file and open it (65.000 lines for example)
public void validate() {
foreach line in the file {
firstDAO.has(line[col1]);
secondDao.has(line[col2]);
}
// It stores the valid objects in a List and persist them at the end
}
}
// The DAO
@Repository
public class FirstDao {
@PersistenceContext
protected EntityManager entityManager;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public boolean has(String name) {
List<Object> result = entityManager.createQuery( from FIRST_TABLE where name = :name)
.setParameter("name", name)
.getResultList();
if (result.size > 0) return true;
else return false;
}
}
// The PersistenceContext/Hibernate configuration
<!-- Data Source -->
<jee:jndi-lookup id="myDS" jndi-name="jdbc/my-DS" cache="true" proxy-interface="javax.sql.DataSource" />
<!-- Entity Manager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property value="classpath:META-INF/my_persistence.xml" name="persistenceXmlLocation"/>
<property name="dataSource" ref="myDS"/>
<property name="persistenceUnitName" value="myPersistenceUnit" />
<!--
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
</property>
</bean>
//导入程序
@组件(“进口商”)
公营进口商{
@自动连线
第一道第一道;
@自动连线
二道二道;
//读取文件并打开它(例如65.000行)
public void validate(){
文件中的每一行{
has(行[col1]);
has(行[col2]);
}
//它将有效对象存储在一个列表中,并在最后持久化它们
}
}
//刀
@存储库
公共类第一道{
@持久上下文
受保护的实体管理器实体管理器;
@事务性(传播=传播。不受支持)
公共布尔has(字符串名){
List result=entityManager.createQuery(来自第一个_表,其中name=:name)
.setParameter(“名称”,名称)
.getResultList();
如果(result.size>0)返回true;
否则返回false;
}
}
//PersistenceContext/Hibernate配置
记录应用程序后,我注意到:
- 对于每个查询(在我的DAO上有方法),都会打开和关闭与我的数据库的连接
- 服务器上的内存被淹没(可能是内存泄漏)
- 在大量打开和关闭连接之后,我从数据库中重置了连接。不知道为什么。如果我继续请求连接,数据源将被挂起
entityManager
的文章,但我仍然不知道我是否做对了,因此:
- 以这种方式在for循环中执行验证是否正确?(每个项目一个连接,意味着在65000行文件中打开和关闭130.000个连接)
- 我已经阅读了entityManager的
。我怀疑可能是内存泄漏。也许Hibernate正在PersistenceContext中创建很多对象。我如何告诉Entity Manager在验证时不要缓存这些家伙无状态持久性上下文
提前谢谢。首先,除非你有很好的理由,否则你真的不应该逐行这样做。即使数据大小大于内存,您也应该一次执行1000行或类似操作,但绝对不能逐个执行。 因为最重要的数据库使用优化之一是减少数据库命中次数 其次,您不应该仅仅为了检查数据是否存在而检索数据。 您应该使用基本的“选择计数”查询。通过这种方式,您将不再需要使用IO来读取数据、通过网络将数据检索到服务器以及花费内存来获取列表中对象的数量等所有东西 如果您使用我的第一个建议,检查现有记录,不是一次检查一条记录,而是一次检查1000条记录,那么您可以只选择名称而不是所有行
顺便说一句,据我所知,如果数据源配置正确(如最大连接数等),那么您使用的是数据源。您不应该担心数据库连接数 你的问题听起来像是一系列问题。但是,对于文件的每一行连接到DB,这将使系统的性能下降很多。您不能遍历整个文件,将其加载到内存中,然后运行一个select语句来检索需要与加载的文件进行比较的db数据吗?将所有数据加载到内存中,然后立即验证所有数据。您可能需要首先修复内存泄漏问题。