hibernate自定义生成主健

现在做的项目有一个需求:在不多维护一张表的情况下,自动生成主键,sequence一样,而且要有一定的规范.比如,现在我们的规范是yymmddhhmmss+四位流水号.没有办法,只好对hibernate的主键生成做自定义.下面是我的代码,请多多指教.

声明,我的hibernate的版本是:hibernate3.2

自定义的时候,只对两个地方做了修改,一个是自己写了一个java,实现了hibernateIdentifierGeneratorConfigurable ,另外一个地方就是对*.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.实现了hibernateIdentifierGeneratorConfigurable

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;

public   class  InMemoryIncrement  implements  IdentifierGenerator, Configurable  {
    
private static final Log log = LogFactory.getLog(InMemoryIncrement.class);
    
//存储最大值的数组的容量 
    private static final int MAX_CAPACITY = 2000;
    
/**同步锁*/
    
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)
        
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;
    }

    
/**
     * 找到表中自动增长字段存储在数组中的索引值
     * 
@return 索引值
     
*/

    
private int findIndex() {
        
int index = 0;
        
//首先中缓存中取出索引值 
        Integer integer = (Integer) map.get(key);
        
//如果没有找到就从数据库中读出最大值并进行cache 
        if (null == integer) {
            
//double check lock 
            synchronized (lock) {
                integer 
= (Integer) map.get(key);
                
if (null == integer) {
                    
long maxvalue = 1;
                   
/* 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)
        
throws MappingException {
        
//     取出table参数 
        String table = params.getProperty("table");
        
if (table == null{
            table 
= params.getProperty(PersistentIdentifierGenerator.TABLE);
        }

        
//取出column参数 
        String column = params.getProperty("column");
        
if (column == null{
            column 
= params.getProperty(PersistentIdentifierGenerator.PK);
        }

        
//表的sehcma参数 
        String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
        returnClass 
= type.getReturnedClass();
        
//取出step参数 
        String stepvalue = params.getProperty("step");
        
if ((null != stepvalue) && !"".equals(stepvalue.trim())) {
            
try {
                step 
= Integer.parseInt(stepvalue);
            }
 catch (Exception e) {
                log.error(e);
            }

        }

        
//构造存储在Map中的索引值的key name 
        key = table + "_$_" + column;
        
//根据参数构造取最大值的SQL 
        sql = "select max(" + column + ") from ";
        
if (null != schema) {
            sql 
+= (schema + ".");
        }

        sql 
+= table;
    }

    
/**
     * 取指定表中id字段的最大值,不存在记录返回0
     * 
@return 最大值
     * 
@throws SQLException if sql error occurs.
     
*/

    
private long getMaxvalue() throws SQLException {
        
long maxvalue = 0;
        PreparedStatement st 
= connection.prepareStatement(sql);
        System.out.println(
"============================================" + sql);
        ResultSet rs 
= null;
        
try {
            rs 
= st.executeQuery();
            
if (rs.next()) {
                maxvalue 
= rs.getLong(1);
            }

            sql 
= null;
        }
 finally {
            
if (rs != null{
                rs.close();
            }

            st.close();
        }

        
return maxvalue;
    }

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值