Spring 3 / Hibernate - ดำเนินการถ่ายโอนข้อมูล DB ระหว่างรันไทม์

ฉันกำลังพัฒนาแอปพลิเคชันด้วย spring roo ซึ่งใช้สปริง 3 และไฮเบอร์เนต
เนื่องจากแบ็กเอนด์ถูกสร้างขึ้นมาให้ไม่มีประสิทธิภาพ ฉันจึงมีตัวเลือกในการตั้งค่าข้อมูลกลับไปเป็นดัมพ์

ดัมพ์นี้ควร "ดำเนินการ" หากผู้ใช้ส่งแบบฟอร์ม jsp ฉันสามารถโหลดไฟล์ Dump.sql ได้และทุกอย่างก็เรียบร้อยดี ยกเว้นว่าฉันไม่รู้วิธีดำเนินการ ฉันลองหลายวิธีแล้ว:
1. Native Query พร้อมตัวจัดการเอนทิตี:

Query q = entityManager.createNativeQuery(dump);  
q.executeUpdate();

แต่มันใช้งานไม่ได้ (ข้อยกเว้นไฮเบอร์เนต) ฉันคิดว่าเป็นเพราะไฮเบอร์เนตไม่สามารถ "อ่าน" ไฟล์ Dump.sql ที่ส่งออก mysql ได้"
2. วิธีคือใช้แค่ไฮเบอร์เนต:

Configuration cfg = new Configuration();  
File configFile = new     File(getClass().getClassLoader().getResource("/METAINF/persistence.xml").toURI());  
cfg.configure(configFile);  
SessionFactory sf=cfg.buildSessionFactory();  
Session sess=sf.openSession();  
Statement st;  
st = sess.connection().createStatement();  

แต่มันก็ไม่ได้ผลเช่นกัน:

org.hibernate.MappingException: การกำหนดค่าไม่ถูกต้องเกิดจาก: org.xml.sax.SAXParseException: เอกสารไม่ถูกต้อง: ไม่พบไวยากรณ์

มีข้อเสนอแนะอะไรบ้าง?


person Alexander    schedule 16.02.2012    source แหล่งที่มา
comment
คุณไม่สามารถเริ่มเครื่องมือการกู้คืน mysql ได้หรือไม่?   -  person Firo    schedule 16.02.2012


คำตอบ (1)


ครั้งหนึ่งฉันเคยเขียนคลาส Java ซึ่งดัมพ์ข้อมูลจากฐานข้อมูล จากนั้นอิมพอร์ตมันไปยังฐานข้อมูลอื่น (แต่ไม่ได้ใช้ดัมพ์ที่สร้างโดย MySQL) บางทีคุณอาจจะลองดูที่มัน

คลาสนี้ขึ้นอยู่กับ DdlUtils และ DbUnit :

import java.io.IOException;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ddlutils.Platform;
import org.apache.ddlutils.PlatformFactory;
import org.apache.ddlutils.model.Database;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Dumper between databases.
 * 
 * @author ndeverge
 */
public final class DatabaseDumper {

    /**
     * Le logger.
     */
    private static final Log LOGGER = LogFactory.getLog(DatabaseDumper.class);

    /**
     * Environment (dev, continuous integration etc...).
     */
    @Value("#{envProperties['env']}")
    private String env;

    /**
     * The db to dump data from.
     */
    @Autowired
    @Qualifier("referenceDataSource")
    private DataSource sourceDataSource;

    /**
     * the db where to write data to.
     */
    @Autowired
    @Qualifier("dataSource")
    private DataSource destDataSource;

    /**
     * Do we need to run the dump ?
     */
    private boolean doRun;

    /**
     * @return the doRun
     */
    public boolean isDoRun() {
        if (doRun) {
            return true;
        }
        // run the dump only on continuous-integration environment
        if ("continuous-integration".equalsIgnoreCase(env)) {
            return true;
        }
        return false;
    }

    /**
     * @param aDoRun
     *            the doRun to set
     */
    public void setDoRun(final boolean aDoRun) {
        doRun = aDoRun;
    }

    /**
     * Set datasources if not initialized by Spring.<br>
     * This method is used when this utility is started from command line.
     * 
     * @throws SQLException
     *             on errors
     */
    private void initDataSources() throws SQLException {

        if (sourceDataSource == null || destDataSource == null) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring/dbDumperContext.xml");

            sourceDataSource = (DataSource) context.getBean("referenceDataSource");

            destDataSource = (DataSource) context.getBean("dataSource");
        }

    }

    /**
     * Dumper execution.
     * 
     * @throws Exception
     *             on errors
     */
    public void execute() throws Exception {

        if (!isDoRun()) {
            LOGGER.debug("Do not run the dump for environment \"" + env + "\"");
        } else {

            LOGGER.warn("WARNING !!! Running the database dump, it may take some time...");

            long start = System.currentTimeMillis();

            // extract schema
            Database schema = dumpSchema(sourceDataSource);

            // create schema
            createSchema(destDataSource, schema);

            // extract data
            IDataSet dataSet = dumpData(sourceDataSource);

            // import data
            importData(destDataSource, dataSet);

            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Database dump duration = " + (System.currentTimeMillis() - start) + " ms");
            }
        }
    }

    /**
     * Extract schema using ddlutils.
     * 
     * @param aSourceDataSource
     *            source db
     * @return an outputstream containing the schema
     * @throws DatabaseUnitException
     *             on errors
     * @throws SQLException
     *             on errors
     * @throws IOException
     *             on errors
     */
    private IDataSet dumpData(final DataSource aSourceDataSource) throws DatabaseUnitException, SQLException,
            IOException {
        IDatabaseConnection sourceConnection = new DatabaseConnection(aSourceDataSource.getConnection());

        return sourceConnection.createDataSet();
    }

    /**
     * Extract data using dbUnit.
     * 
     * @param aSourceDataSource
     *            source db
     * @return an outputstream containing the data
     */
    private Database dumpSchema(final DataSource aSourceDataSource) {
        return PlatformFactory.createNewPlatformInstance(aSourceDataSource).readModelFromDatabase("sourceModel");

    }

    /**
     * Create schema in destination db.
     * 
     * @param aDestDataSource
     *            the destination db
     * @param schema
     *            the schema
     */
    private void createSchema(final DataSource aDestDataSource, final Database schema) {
        Platform destPlatform = PlatformFactory.createNewPlatformInstance(aDestDataSource);

        // create schema by droping tables firts (2nd parameter = true)
        destPlatform.createTables(schema, true, true);
    }

    /**
     * Data import.
     * 
     * @param aDestDataSource
     *            the destination db
     * @param dataSet
     *            the data
     * @throws SQLException
     *             on errors
     * @throws DatabaseUnitException
     *             on errors
     */
    private void importData(final DataSource aDestDataSource, final IDataSet dataSet) throws DatabaseUnitException,
            SQLException {
        IDatabaseConnection destConnection = new DatabaseConnection(aDestDataSource.getConnection());

        DatabaseOperation.CLEAN_INSERT.execute(destConnection, dataSet);
    }

    /**
     * Launch the dumper from commande line.
     * 
     * @param args
     *            paramètres
     */
    public static void main(final String[] args) {
        try {
            DatabaseDumper dumper = new DatabaseDumper();
            dumper.setDoRun(true);
            dumper.initDataSources();
            dumper.execute();
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }

}
person ndeverge    schedule 16.02.2012
comment
ขอบคุณสำหรับสิ่งนี้ แต่ฉันต้องการวิธีแก้ปัญหาที่ไม่ต้องพึ่งพาเฟรมเวิร์กเพิ่มเติม - person Alexander; 16.02.2012
comment
หวังว่า... :-) ช่วยบอกหน่อยว่าโอเค (หรือเปล่า) - person ndeverge; 27.03.2012