现在做的项目有一个需求:在不多维护一张表的情况下,自动生成主键,同sequence一样,而且要有一定的规范.比如,现在我们的规范是yymmddhhmmss+四位流水号.没有办法,只好对hibernate的主键生成做自定义.下面是我的代码,请多多指教.
声明,我的hibernate的版本是:hibernate3.2
自定义的时候,只对两个地方做了修改,一个是自己写了一个java类,实现了hibernate的IdentifierGenerator和Configurable ,另外一个地方就是对*.hbm.xml文件做修改.
一.
先说对*.hbm.xml做的修改吧,东西比较少.
原始的配置文件中,主键生成时,采用的是自动增加1,如下:
<
class
name
="com.ce.fxmgn.entity.Hold"
table
="HOLD"
>
<
id
name
="oid"
type
="java.lang.String"
>
<
column
name
="OID"
length
="32"
/>
<
generator
class
="sequence"
>
<
param
name
="sequence"
>
seq_id
</
param
>
</
generator
>
</
id
>
在修改后,去掉了sequence,如下:
<
class
name
="com.ce.fxmgn.entity.Hold"
table
="HOLD"
>
<
id
name
="oid"
type
="java.lang.String"
>
<
column
name
="OID"
length
="32"
/>
<
generator
class
="com.hello.test.po.InMemoryIncrement"
>
</
generator
>
</
id
>
其中,com.hello.test.po.InMemoryIncrement便是自己写的java类.
二.扩展的java类.实现了hibernate的IdentifierGenerator和Configurable
package
com.hello.test.po;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
import
org.hibernate.HibernateException;
import
org.hibernate.MappingException;
import
org.hibernate.dialect.Dialect;
import
org.hibernate.engine.SessionImplementor;
import
org.hibernate.id.Configurable;
import
org.hibernate.id.IdentifierGenerator;
import
org.hibernate.id.PersistentIdentifierGenerator;
import
org.hibernate.type.Type;
import
java.io.Serializable;
import
java.sql.Connection;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.Map;
import
java.util.Properties;
import
java.util.Properties;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
InMemoryIncrement
implements
IdentifierGenerator, Configurable
...
{
private static final Log log = LogFactory.getLog(InMemoryIncrement.class);
//存储最大值的数组的容量
private static final int MAX_CAPACITY = 2000;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**同步锁*/
private static final Object lock = new Object();
//存储表存储在数组中的索引值
private static Map map = new HashMap();
//最大值数组
private static long[] seqs = new long[MAX_CAPACITY];
//最大值数组已经使用的容量
private static int lastIndex;
//递增步长,默认加1
private int step = 1;
private String key;
private String sql;
private Connection connection;
private Class returnClass;
public Serializable generate(SessionImplementor session, Object object)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
throws HibernateException ...{
// TODO Auto-generated method stub
connection = session.connection();
long seq = -1;
//找到索引值
int index = findIndex();
//把最大值加1
seqs[index] = seqs[index] + step;
seq = seqs[index];
//得到流水号,是自己写的工具类生成的.形式为000x
String seqStr = JspFormate.currentFormateORM(seq);
//得到yymmdd,是自己写的方法工具类生成的yymmdd
String preDate = JspFormate.dateFormateYYYYMMDD(new Date()).substring(2);
//得到hhmmss,是自己写的工具类获取的hhmmss
String preHour = JspFormate.dateFormateOnlyHHMMSSORM(new Date());
return preDate + preHour + seqStr;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* 找到表中自动增长字段存储在数组中的索引值
* @return 索引值
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private int findIndex() ...{
int index = 0;
//首先中缓存中取出索引值
Integer integer = (Integer) map.get(key);
//如果没有找到就从数据库中读出最大值并进行cache
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (null == integer) ...{
//double check lock
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
synchronized (lock) ...{
integer = (Integer) map.get(key);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (null == integer) ...{
long maxvalue = 1;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//* try {
maxvalue = getMaxvalue();
} catch (SQLException e) {
log.error(e);
}*/
maxvalue = new Long(0).longValue();
integer = new Integer(lastIndex++);
seqs[integer.intValue()] = maxvalue;
map.put(key, integer);
}
}
}
index = integer.intValue();
return index;
}
public void configure(Type type, Properties params, Dialect d)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
throws MappingException ...{
// 取出table参数
String table = params.getProperty("table");
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (table == null) ...{
table = params.getProperty(PersistentIdentifierGenerator.TABLE);
}
//取出column参数
String column = params.getProperty("column");
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (column == null) ...{
column = params.getProperty(PersistentIdentifierGenerator.PK);
}
//表的sehcma参数
String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
returnClass = type.getReturnedClass();
//取出step参数
String stepvalue = params.getProperty("step");
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if ((null != stepvalue) && !"".equals(stepvalue.trim())) ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
step = Integer.parseInt(stepvalue);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (Exception e) ...{
log.error(e);
}
}
//构造存储在Map中的索引值的key name
key = table + "_$_" + column;
//根据参数构造取最大值的SQL
sql = "select max(" + column + ") from ";
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (null != schema) ...{
sql += (schema + ".");
}
sql += table;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* 取指定表中id字段的最大值,不存在记录返回0
* @return 最大值
* @throws SQLException if sql error occurs.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private long getMaxvalue() throws SQLException ...{
long maxvalue = 0;
PreparedStatement st = connection.prepareStatement(sql);
System.out.println("============================================" + sql);
ResultSet rs = null;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
rs = st.executeQuery();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (rs.next()) ...{
maxvalue = rs.getLong(1);
}
sql = null;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} finally ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (rs != null) ...{
rs.close();
}
st.close();
}
return maxvalue;
}
}