Can Hibernate work with MySQL's “ON DUPLICATE KEY UPDATE” syntax?

后端 未结 3 536
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 05:20

MySQL supports an \"INSERT ... ON DUPLICATE KEY UPDATE ...\" syntax that allows you to \"blindly\" insert into the database, and fall back to updating the exist

3条回答
  •  鱼传尺愫
    2020-11-27 05:46

    If you are using Grails, I found this solution which did not require moving your Domain class into the JAVA world and using @SQLInsert annotations:

    1. Create a custom Hibernate Configuration
    2. Override the PersistentClass Map
    3. Add your custom INSERT sql to the Persistent Classes you want using the ON DUPLICATE KEY.

    For example, if you have a Domain object called Person and you want to INSERTS to be INSERT ON DUPLICATE KEY UPDATE you would create a configuration like so:

    public class MyCustomConfiguration extends GrailsAnnotationConfiguration {
    
        public MyCustomConfiguration() {
            super();
    
            classes = new HashMap() {
                @Override
                public PersistentClass put(String key, PersistentClass value) {
                    if (Person.class.getName().equalsIgnoreCase(key)) {
                        value.setCustomSQLInsert("insert into person (version, created_by_id, date_created, last_updated, name) values (?, ?, ?, ?, ?) on duplicate key update id=LAST_INSERT_ID(id)", true, ExecuteUpdateResultCheckStyle.COUNT);
                    }
                    return super.put(key, value);
                }
            };
        }
    

    and add this as your Hibernate Configuration in DataSource.groovy:

    dataSource {
        pooled = true
        driverClassName = "com.mysql.jdbc.Driver"
        configClass = 'MyCustomConfiguration'
    }
    

    Just a note to be careful using LAST_INSERT_ID, as this will NOT be set correctly if the UPDATE is executed instead of the INSERT unless you set it explicitly in the statement, e.g. id=LAST_INSERT_ID(id). I haven't checked where GORM gets the ID from, but I'm assuming somewhere it is using LAST_INSERT_ID.

    Hope this helps.

提交回复
热议问题