添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一)EntityManager方法简介

1、 entityManager. find (Class<T> entityClass, Object primaryKey);

根据主键查找数据;如果主键格式不正确,会抛出illegalArgumentException异常;如果主键在数据库未找到数据返回null;

2、 entityManager. persist (Object entity);

新增数据;如果entity的主键不为空,而数据库没有该主键,会抛出异常;如果entity的主键不为空,而数据库有该主键,且entity的其他字段与数据库不同,persist后不会更新数据库;

3、 entityManager. merge (T entity);

将 Detached状态的Entity实例转至Managed状态;

4、 entityManager. remove (Object entity);

删除数据;只能将Managed状态的Entity实例删除,由此Entity实例状态变为Removed;

5、 entityManager. clear ();

将所有的Entity实例状态转至Detached状态;

6、 entityManager. flush ();

将所有Managed状态的Entity实例同步到数据库;

7、 entityManager. refresh (Object entity);

加载Entity实例后,数据库该条数据被修改,refresh该实例,能得到数据库最新的修改,覆盖原来的Entity实例;

二)EntityManager批量新增or修改

测试方式:用一个循环往一个表批量插入数据,需要先判断数据是否已经存在,然后再做新增or修改。

package com.oyj.jpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import com.oyj.jpa.entity.EmployeeEntity;
public class SessionBatchAddEmployee {
	public static void main(String[] args) {
        // JPA批量插入
        EntityManagerFactory entityManagerFactory = null;
        EntityManager entityManager = null;
        EntityTransaction txn = null;
        try {
            entityManagerFactory = Persistence.createEntityManagerFactory("myhibernate_jpa");
            entityManager = entityManagerFactory.createEntityManager();
            txn = entityManager.getTransaction();
            txn.begin();
            int batchSize = 1000; // 批次
            int size = 100000; // 插入数据的数据量
            Long beginTime = System.currentTimeMillis(); // 开始时间
            EmployeeEntity entity = null;
            EmployeeEntity en = null;
            for (int i = 0; i < size; i++) {
                if (i > 0 && i % batchSize == 0) {
                    System.out.println("第" + (i/batchSize) + "次刷新entityManager!");
                    entityManager.flush();
                    entityManager.clear();
                int userid = (i+1);
                // 实体类
                entity = new EmployeeEntity();
                entity.setUserID(userid);
                entity.setUserName("userName" + userid);
                entity.setSex(1);
                // 当表里存在主键约束时, 需要判断数据是否已存在, 否则会报错
                en = entityManager.find(EmployeeEntity.class, userid);
                if (en != null) {
                    entityManager.merge(entity); // 修改
                } else {
                    entityManager.persist(entity); // 新增
            txn.commit();
            Long endTime = System.currentTimeMillis(); // 结束时间
            System.out.println("JPA批量插入or修改" + size + "数据, 执行总耗时: " + (endTime - beginTime) + "毫秒");
        } catch (RuntimeException e) {
            if ( txn != null && txn.isActive()) txn.rollback();
                throw e;
        } finally {
            if (entityManager != null) {
                entityManager.close();

控制台打印效果图:(用本地数据库执行,多启动几次,发现插入会变慢)

三)JDBC批量新增or修改

测试方式:用一个循环往一个表批量插入数据,需要先判断数据是否已经存在,然后再做新增or修改。

package com.oyj.jpa;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcBatchAddEmployee {
    public static void main(String[] args) {
        batchInsert();
     * JDBC批量插入
    public static void batchInsert() {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = getConnection();
            StringBuilder builder = new StringBuilder();
            builder.append("INSERT INTO employee (userid, username, sex) values(?, ?, ?)");
            ps = conn.prepareStatement(builder.toString());
            // 先设置不自动提交
            conn.setAutoCommit(false);
            int batchSize = 1000;
            int size = 100000; 
            Long beginTime = System.currentTimeMillis(); // 开始时间
            for (int i = 0; i < size; i++) {
                ps.setInt(1, (i+1));
                ps.setString(2, "username" + (i+1));
                ps.setInt(3, 1);
                ps.addBatch();
                // 每多少次提交一遍
                if (i > 0 && i % batchSize == 0) {
                    System.out.println("第" + (i/batchSize) + "次executeBatch!");
                    ps.executeBatch();
                    conn.commit();
            // 最后一次执行批量操作, 当i%500不为0时, 即最后一批数据的提交
            ps.executeBatch();
            conn.commit();
            Long endTime = System.currentTimeMillis(); // 结束时间
            System.out.println("JDBC批量插入" + size  + "条数据执行总耗时: " + (endTime - beginTime) + "毫秒");
        } catch (SQLException e) {
            System.out.println("batchInsert==>SQLException Fail!" + e);
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                if (conn != null) {
                    conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
    public static Connection getConnection() { // 获取数据库连接
        Connection conn = null;
        try {
            if (conn == null) {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "oysept", "oysept");
        } catch (Exception e) {
            System.out.println("getConnection==>SQLException Fail!" + e);
        return conn;

控制台效果图打印:

EntityManager在执行批量操作时,数据量越大,执行效率越慢,执行耗时成倍数递增;影响因素较多,网络,数据库性能,数据量等问题。

JDBC批量执行快速,数据量越大,执行效率只会缓慢递增,运行速度快。

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

一)JPA方法简介1、entityManager.find(Class&lt;T&gt; entityClass, Object primaryKey);根据主键查找数据;如果主键格式不正确,会抛出illegalArgumentException异常;如果主键在数据库未找到数据返回null;2、entityManager.persist(Object entity);新增数据;如果...
有时候我们需要向数据库插入大量数据,如果一条一条插入会非常慢所以我们可以考虑批量插入其实很简单 只需要使用默认的save()方法就可以了假设现在有一个student实体类  我们需要一次插入整个学区5000名学生的信息package com.chunying.boke.bean; * @author chunying public class Student { pr...
已经拥有持久化主键并和持久化建立了上下文环境 当处在托管状态的实体Bean被管理器flush了,那么就在极短暂的时间进入了持久化状态,事务提交之后,立刻变为了游离状态。 您可以把持久化状态当做实实在在的数据库记录。 ③ 游离状态 拥有持久化主键,但是没有与持久化建立上下文环境 游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体
在 JPA 中,可以使用 `EntityManager` 对象的 `persist()` 方法来新增实体。如果要批量新增多个实体,可以使用以下方法: 1. 使用 `EntityManager` 对象的 `createQuery()` 方法创建一个批量插入语句,然后使用 `executeUpdate()` 方法执行该语句。例如: ```java List<Entity> entities = ...; entityManager.createQuery("INSERT INTO Entity (field1, field2, ...) VALUES (:field1, :field2, ...)") .setParameter("field1", value1) .setParameter("field2", value2) .executeUpdate(); 这种方法需要手动拼接 SQL 语句,不太方便。 2. 使用 JPA 提供的批量操作 API,例如 `javax.persistence.EntityManager#persist` 和 `javax.persistence.EntityManager#flush` 方法。例如: ```java List<Entity> entities = ...; for (Entity entity : entities) { entityManager.persist(entity); if (i % batchSize == 0) { // 每 batchSize 条数据执行一次 flush() 方法 entityManager.flush(); entityManager.clear(); 这种方法比较简单,但是需要注意的是,如果新增的实体数量过大,可能会导致内存溢出。因此,一般需要限制批量操作的数量,例如每次执行 `flush()` 方法时只处理一定数量的实体。