package com.yourcompany;
import java.io.Serializable;
import java.util.Properties;
import java.sql.*;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.PropertiesHelper;
import net.sf.hibernate.util.StringHelper;
import net.sf.hibernate.id.PersistentIdentifierGenerator;
import net.sf.hibernate.id.Configurable;
/**
* <p>产生数据表的主键值</p>
*
* <p>
* 该类弥补了Hibernate内置生成器hilo的所有表的主键均共享一个数据行的缺陷,
* 即在保存主键的表上添加一个字段,该字段保存的是要得到主键值的表名称,每个表的
* 主键值均单独保存到一个数据行上。
* </p>
*
* <br>保存主键的表名称(默认为COMMON_PRIMARY_KEY),
* <br>该表有两个字段,其中一个字段(默认名称为TARGET_TABLE)是要得到主键值的数据表名,
* <br>另一个字段(默认名称为PRIMARY_KEY_COLUMN)是要得到的主键值。
*
* <br>部署描述样例:
* <id ...>
<generator class="com.yourcompany.PrimaryKeyGenerator">
<param name="target_value">Courses</param>
<!-- 后边的三个参数可以不写,用默认的,不过前提是在你的数据库中有表COMMON_PRIMARY_KEY -->
<!-- 并且有PRIMARY_KEY_COLUMN和TARGET_TABLE这两个字段 -->
<!-- 别忘了在这个表中加如你要得到主键的表名称(这个例子是Courses),并且初始化主键值,SQL如下: -->
<!-- INSERT INTO COMMON_PRIMARY_KEY VALUES('COURSES',1); -->
<param name="table">你自己创建的表名称</param>
<param name="column">存放主键的列名称</param>
<param name="target_column">要得到主键值的表名称</param>
</generator>
</id>
*
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class PrimaryKeyGenerator implements PersistentIdentifierGenerator, Configurable{
/*---------------静态成员-------------*/
/**
* 列名称参数
*/
private static final String COLUMN = "column";
/**
* 表名称参数
*/
private static final String TABLE = "table";
/**
* 目标名称参数
*/
private static final String TARGET_NAME = "target_name";
/**
* 目标值参数
*/
private static final String TARGET_VALUE = "target_value";
/*-------------结束静态成员--------------*/
/*--------------私有成员---------------*/
/**
* 保存主键的表名称
*/
private String _strTableName;
/**
* 保存主键值的列名称
*/
private String _strColumnName;
/**
* 保存表名称的列名称
*/
private String _strTargetColumn;
/**
* 查询Sql
*/
private String _strQuerySql;
/**
* 更新Sql
*/
private String _strUpdateSql;
/*-------------结束私有成员-------------*/
/**
* 得到各个参数的值
* @param type
* @param params
* @param dialect
*/
public void configure (Type type, Properties params, Dialect dialect){
//得到存放主键值的表名称(默认为COMMON_PRIMARY_KEY)
_strTableName = PropertiesHelper.getString(TABLE,params,"COMMON_PRIMARY_KEY");
//得到存放主键值的列名称(默认为PRIMARY_KEY_COLUMN)
_strColumnName = PropertiesHelper.getString(COLUMN,params,"PRIMARY_KEY_COLUMN");
//得到要取得主键值的目标数据表的列名称(默认为TARGET_TABLE)
_strTargetColumn = PropertiesHelper.getString(TARGET_NAME,params,"TARGET_TABLE");
//得到要取得主键值的目标数据表的值
String strTargetValue = params.getProperty(TARGET_VALUE);
//得到查询与更新的SQL语句
_strQuerySql = "SELECT " + _strColumnName + " FROM " + _strTableName + " WHERE " +
_strTargetColumn + " = '" + strTargetValue + "'";
_strUpdateSql = "UPDATE " + _strTableName + " SET " + _strColumnName + " = ? WHERE " +
_strTargetColumn + " = '" + strTargetValue + "'";
}
/**
* 产生主键值
* @param sessionImplementor
* @param obj
* @return 主键值
* @throws SQLException
* @throws HibernateException
*/
public synchronized Serializable generate(SessionImplementor sessionImplementor, Object obj)
throws SQLException, HibernateException{
Connection conn = null;
Statement stmt = null;
PreparedStatement preStmt = null;
try{
//得到数据库连接
conn = sessionImplementor.getFactory().openConnection();
stmt = conn.createStatement();
//得到主键值
ResultSet rs = stmt.executeQuery(_strQuerySql);
int iPrimaryKey;
if(rs.next()){
iPrimaryKey = rs.getInt(1);
rs.close();
}
else
throw new HibernateException("没有检索到符合条件的主键值");
//更新主键列
preStmt = conn.prepareStatement(_strUpdateSql);
preStmt.setInt(1,iPrimaryKey + 1);
preStmt.execute();
return String.valueOf(iPrimaryKey);
}
finally{
if(stmt != null)
stmt.close();
if(preStmt != null)
preStmt.close();
if(conn != null)
conn.close();
}
}
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
return new String[] {
"CREATE TABLE " + _strTableName + " ( " + _strColumnName + " " + dialect.getTypeName(Types.INTEGER) +
"," + _strTargetColumn + " " + dialect.getTypeName(Types.VARCHAR) + " )",
};
}
public String sqlDropString(Dialect dialect) {
return "DROP TABLE " + _strTableName + dialect.getCascadeConstraintsString();
}
public Object generatorKey() {
return _strTableName;
}
}
import java.io.Serializable;
import java.util.Properties;
import java.sql.*;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.PropertiesHelper;
import net.sf.hibernate.util.StringHelper;
import net.sf.hibernate.id.PersistentIdentifierGenerator;
import net.sf.hibernate.id.Configurable;
/**
* <p>产生数据表的主键值</p>
*
* <p>
* 该类弥补了Hibernate内置生成器hilo的所有表的主键均共享一个数据行的缺陷,
* 即在保存主键的表上添加一个字段,该字段保存的是要得到主键值的表名称,每个表的
* 主键值均单独保存到一个数据行上。
* </p>
*
* <br>保存主键的表名称(默认为COMMON_PRIMARY_KEY),
* <br>该表有两个字段,其中一个字段(默认名称为TARGET_TABLE)是要得到主键值的数据表名,
* <br>另一个字段(默认名称为PRIMARY_KEY_COLUMN)是要得到的主键值。
*
* <br>部署描述样例:
* <id ...>
<generator class="com.yourcompany.PrimaryKeyGenerator">
<param name="target_value">Courses</param>
<!-- 后边的三个参数可以不写,用默认的,不过前提是在你的数据库中有表COMMON_PRIMARY_KEY -->
<!-- 并且有PRIMARY_KEY_COLUMN和TARGET_TABLE这两个字段 -->
<!-- 别忘了在这个表中加如你要得到主键的表名称(这个例子是Courses),并且初始化主键值,SQL如下: -->
<!-- INSERT INTO COMMON_PRIMARY_KEY VALUES('COURSES',1); -->
<param name="table">你自己创建的表名称</param>
<param name="column">存放主键的列名称</param>
<param name="target_column">要得到主键值的表名称</param>
</generator>
</id>
*
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class PrimaryKeyGenerator implements PersistentIdentifierGenerator, Configurable{
/*---------------静态成员-------------*/
/**
* 列名称参数
*/
private static final String COLUMN = "column";
/**
* 表名称参数
*/
private static final String TABLE = "table";
/**
* 目标名称参数
*/
private static final String TARGET_NAME = "target_name";
/**
* 目标值参数
*/
private static final String TARGET_VALUE = "target_value";
/*-------------结束静态成员--------------*/
/*--------------私有成员---------------*/
/**
* 保存主键的表名称
*/
private String _strTableName;
/**
* 保存主键值的列名称
*/
private String _strColumnName;
/**
* 保存表名称的列名称
*/
private String _strTargetColumn;
/**
* 查询Sql
*/
private String _strQuerySql;
/**
* 更新Sql
*/
private String _strUpdateSql;
/*-------------结束私有成员-------------*/
/**
* 得到各个参数的值
* @param type
* @param params
* @param dialect
*/
public void configure (Type type, Properties params, Dialect dialect){
//得到存放主键值的表名称(默认为COMMON_PRIMARY_KEY)
_strTableName = PropertiesHelper.getString(TABLE,params,"COMMON_PRIMARY_KEY");
//得到存放主键值的列名称(默认为PRIMARY_KEY_COLUMN)
_strColumnName = PropertiesHelper.getString(COLUMN,params,"PRIMARY_KEY_COLUMN");
//得到要取得主键值的目标数据表的列名称(默认为TARGET_TABLE)
_strTargetColumn = PropertiesHelper.getString(TARGET_NAME,params,"TARGET_TABLE");
//得到要取得主键值的目标数据表的值
String strTargetValue = params.getProperty(TARGET_VALUE);
//得到查询与更新的SQL语句
_strQuerySql = "SELECT " + _strColumnName + " FROM " + _strTableName + " WHERE " +
_strTargetColumn + " = '" + strTargetValue + "'";
_strUpdateSql = "UPDATE " + _strTableName + " SET " + _strColumnName + " = ? WHERE " +
_strTargetColumn + " = '" + strTargetValue + "'";
}
/**
* 产生主键值
* @param sessionImplementor
* @param obj
* @return 主键值
* @throws SQLException
* @throws HibernateException
*/
public synchronized Serializable generate(SessionImplementor sessionImplementor, Object obj)
throws SQLException, HibernateException{
Connection conn = null;
Statement stmt = null;
PreparedStatement preStmt = null;
try{
//得到数据库连接
conn = sessionImplementor.getFactory().openConnection();
stmt = conn.createStatement();
//得到主键值
ResultSet rs = stmt.executeQuery(_strQuerySql);
int iPrimaryKey;
if(rs.next()){
iPrimaryKey = rs.getInt(1);
rs.close();
}
else
throw new HibernateException("没有检索到符合条件的主键值");
//更新主键列
preStmt = conn.prepareStatement(_strUpdateSql);
preStmt.setInt(1,iPrimaryKey + 1);
preStmt.execute();
return String.valueOf(iPrimaryKey);
}
finally{
if(stmt != null)
stmt.close();
if(preStmt != null)
preStmt.close();
if(conn != null)
conn.close();
}
}
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
return new String[] {
"CREATE TABLE " + _strTableName + " ( " + _strColumnName + " " + dialect.getTypeName(Types.INTEGER) +
"," + _strTargetColumn + " " + dialect.getTypeName(Types.VARCHAR) + " )",
};
}
public String sqlDropString(Dialect dialect) {
return "DROP TABLE " + _strTableName + dialect.getCascadeConstraintsString();
}
public Object generatorKey() {
return _strTableName;
}
}
本文介绍了一种自定义的Hibernate主键生成器实现,该生成器能够为不同表生成独立的主键值,避免了多个表共用同一主键序列的问题。通过配置参数指定表名、列名等信息,实现按需生成并更新主键。
920

被折叠的 条评论
为什么被折叠?



