使用hibernate插入很多行非常慢

时间:2015-10-20 10:25:51

标签: java mysql hibernate insert

我有大约5000行使用hibernate插入我的数据库,但它持续约2分钟,我不知道为什么。这是我的代码:

hibernate.cfg.xml中

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
   <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
   <property name="hibernate.connection.url">jdbc:mysql://sql.user.nazwa.pl:3307/user</property>
       <property name="hibernate.jdbc.batch_size">20</property>
   <property name="hibernate.connection.username">user</property>
   <property name="hibernate.connection.password">pasword</property>
       <property name="show_sql">false</property>
       <mapping resource="model/models.hbm.xml"/>
</session-factory>
</hibernate-configuration>

models.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="model.User" table="User">
        <id name="userId" type="int" column="userId">
            <generator class="native"/>
        </id>

        <property name="userName" column="userName" type="string"/>
        <property name="height" column="height" type="double"/>
        <property name="weight" column="weight" type="double"/>
        <property name="hrMax" column="hrMax" type="double"/>
        <property name="hrMin" column="hrMin" type="double"/>

        <set name="trainings" cascade="all-delete-orphan,save-update" lazy="false">
            <key column="userId"/>
            <one-to-many class="model.Training"/>
        </set>
    </class>

    <class name="model.Training" table="Training">
        <id name="trainingId" type="int" column="trainingId">
            <generator class="native"/>
        </id>

        <property name="type" column="type" type="string"/>
        <property name="date" column="date" type="string"/>
        <property name="duration" column="duration" type="org.hibernate.type.LocalTimeType"/>
        <property name="totalDistance" column="totalDistance" type="double"/>
        <property name="averageHeartRate" column="averageHeartRate" type="int"/>
        <property name="averageSpeed" column="averageSpeed" type="double"/>
        <property name="maxSpeed" column="maxSpeed" type="double"/>
        <property name="calories" column="calories" type="int"/>
        <property name="fatPercentageOfCalories" column="fatPercentageOfCalories" type="int"/>

        <set name="trainingDetails" cascade="all-delete-orphan,save-update" lazy="false">
            <key column="trainingId"/>
            <one-to-many class="model.TrainingDetails"/>
        </set>
    </class>

    <class name="model.TrainingDetails" table="TrainingDetails">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>

        <property name="time" column="time" type="org.hibernate.type.LocalTimeType"/>
        <property name="heartRate" column="heartRate" type="int"/>
        <property name="speed" column="speed" type="double"/>
        <property name="altitude" column="altitude" type="int"/>
        <property name="distance" column="distance" type="double"/>
    </class>


</hibernate-mapping>

HibernateUtil.java

package model;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Created by Piotr on 2015-10-11.
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();

        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        // Close caches and connection pools
        getSessionFactory().close();
    }
}

执行时间过长的方法:

public void addTrainingsDetailsToTraining(Map<String, String> mapOne, Map<String, ArrayList<String>> mapTwo
            , int trainingId, int rowCount) {
        Session session = hibernateUtil.getSessionFactory().openSession();
        session.setCacheMode(CacheMode.IGNORE);
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Training training = (Training) session.get(Training.class, trainingId);
            for (int i = 0; i < rowCount; i++) {
                training.getTrainingDetails().add(new TrainingDetails(LocalTime.parse(mapTwo.get(time).get(i))
                        , Integer.parseInt(mapTwo.get(heartRate).get(i)), Double.parseDouble(mapTwo.get(speed).get(i))
                        , Integer.parseInt(mapTwo.get(altitude).get(i)), Double.parseDouble(mapTwo.get(distance).get(i))));
                if (i % 20 == 0) {
                    session.flush();
                    session.clear();
                }
            }
            session.update(training);
            tx.commit();
        } catch (Exception e) {
            if (tx != null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

1 个答案:

答案 0 :(得分:0)

如果你的设计允许你可以给普通SQL做一个改变(或者也许还有HQL等价物)。

我想INSERT ... ON DUPLICATE KEY UPDATE使用VALUES上传多个数据时,语法应该更快:

http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html