现在的位置: 首页 > 综合 > 正文

Hibernate自定义主键生成策略

2014年04月05日 ⁄ 综合 ⁄ 共 2981字 ⁄ 字号 评论关闭

在复习Hibernate的时候,又遇到了MySQL自增时,批量添加出问题的情况;

暂时写了一个可以实现MySQL自增主键生成器的代码,运行效率很差劲(*^__^*) 嘻嘻……但是功能都有

 

package pkg;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.type.Type;

public class IncrementGenerator implements IdentifierGenerator, Configurable {
    private String sql;
    private Type type;

//这里应该是static的,多有线程看到的都是同一份缓存记录
    private static Map<Class, Long> cacheEntityPKMax = new HashMap<Class, Long>();
    
    public IncrementGenerator() {
    }

    /**
     * 如果一个事务只添加一条记录,那么只需添加时查询主键列最大值
     */
    public void configure(Type type, Properties params, Dialect dialect)
            throws MappingException {
        this.type = type;
        String table = params.getProperty("table");
        if (table == null)
            table = params.getProperty(PersistentIdentifierGenerator.TABLE);
        String column = params.getProperty("column");
        if (column == null)
            column = params.getProperty(PersistentIdentifierGenerator.PK);
        String schema = params
                .getProperty(PersistentIdentifierGenerator.SCHEMA);
        sql = "select max(" + column + ") from "
                + (schema == null ? table : schema + '.' + table);
    }

    /**
     * 但是大多数情况下,一个事务可能会批量添加很多数据,如自动保存指定实体相关的多个实体数据
     */
    public Serializable generate(SessionImplementor session, Object obj)
            throws HibernateException {
        PreparedStatement ptsmt = null;
        ResultSet rs = null;
        Long id = new Long(1);
        try {
            
            Connection conn = session.connection();
            ptsmt = conn.prepareStatement(sql);
            rs = ptsmt.executeQuery();
            if(rs.next()){
                id = rs.getLong(1)+1;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                ptsmt.close();

                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        Long oldId = cacheEntityPKMax.get(obj.getClass());
        if((oldId !=null)&&(id<=oldId)){
            id = oldId + 1;
        }
        
        /**
         * 下面的代码是为了记录批量添加实体数据时,记录上次生成的ID,
         * 以为了和查询出的ID相比较
         */
        cacheEntityPKMax.put(obj.getClass(), id);
        if(type instanceof org.hibernate.type.IntegerType){
            return Integer.valueOf(id.toString());
        }
        if(type instanceof org.hibernate.type.LongType){
            return Long.valueOf(id.toString());
        }
        return null;
    }
}

 

 

//使用:

 

Main方法测试:

抱歉!评论已关闭.