在复习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方法测试: