- 浏览: 284187 次
- 性别:
- 来自: 福建
文章分类
- 全部博客 (183)
- 软件架构 (6)
- JEE (21)
- Struts (2)
- Spring (8)
- 权限控制 (10)
- iBATIS (3)
- Hibernate (15)
- Freemarker (1)
- SpringSide (2)
- JBoss (1)
- Seam (2)
- jBPM (2)
- 开源 (2)
- 开发工具 (5)
- 打包构建 (14)
- JSF (1)
- 日志 (3)
- 搜索 (3)
- 定时器 (1)
- 单元测试 (3)
- IoC (3)
- JGroups (3)
- JavaFX (1)
- Web (9)
- Javascript (14)
- Ajax (0)
- qooxdoo (0)
- Dojo (2)
- ExtJS (2)
- JQuery (5)
- ZK (1)
- 数据库 (6)
- 正则表达式 (1)
- ruby (3)
- php (1)
- 数据结构与算法 (1)
- ubuntu (3)
- OSGi (1)
- 高性能网站架构 (12)
最新评论
-
FX夜归人:
...
Lucene为数据库建索引 -
yu46612143:
...
m2eclipse 安装及使用 -
lenomon:
可以看看这个demo, M2eclipse 设置 Mave ...
m2eclipse 安装及使用 -
Smile__xtj:
aa
Java对象验证框架 OVal -
tuoxiaohu:
这个插件不支持3.X了,只有4.X的,请问你有3.1.X的pl ...
在Eclipse WTP中加入Resin server adapter
背景:
Hibernate(目前使用的版本是3.2)中提供了多种生成主键的方式.在下面的文章中有列出来
[hibernate]Hibernate主键生成方式 Key Generator
然而当前的这么多种生成方式未必能满足我们的要求.
比如increment,可以在一个hibernate实例的应用上很方便的时候,但是在集群的时候就不行了.
再如 identity ,sequence ,native 是数据局提供的主键生成方式,往往也不是我们需要,而且在程序跨数据库方面也体现出不足.
还有基于算法的生成方式生成出来的主键基本都是字符串的.
我们现在需要一种生成方式:使用Long作为主键类型,自动增,支持集群.
那么我们需要自定义一个我们的主键生成器才能实现了.
实现代码:
package hibernate; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; 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; public class IncrementGenerator implements IdentifierGenerator, Configurable { private static final Log log = LogFactory.getLog(IncrementGenerator.class); private Long next; private String sql; public Serializable generate(SessionImplementor session, Object object) throws HibernateException { if (sql!=null) { getNext( session.connection() ); } return next; } public void configure(Type type, Properties params, Dialect d) throws MappingException { 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 ); log.info(sql); } private void getNext(Connection conn) throws HibernateException { try { PreparedStatement st = conn.prepareStatement(sql); ResultSet rs = st.executeQuery(); if ( rs.next() ) { next = rs.getLong(1) + 1; } else { next = 1l; } }catch(SQLException e) { throw new HibernateException(e); } finally { try{ conn.close(); }catch(SQLException e) { throw new HibernateException(e); } } } }
配置:
在对应的hbm文件里面将id的配置如下:
<id name="id" type="long" column="id" > <generator class="hibernate.IncrementGenerator" /> </id>
另一个主键生成方式的例子
package com.mc.framework.hibernate.id; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.MessageFormat; import java.util.Properties; 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.IdentifierGeneratorFactory; import org.hibernate.id.MultipleHiLoPerTableGenerator; import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.mapping.Table; import org.hibernate.type.Type; import org.hibernate.util.PropertiesHelper; import org.hibernate.util.StringHelper; import com.htf.framework.util.ClassUtil; public class AutoadjustMultipleHiLoGenerator extends MultipleHiLoPerTableGenerator implements PersistentIdentifierGenerator,Configurable { private static final Log _log = LogFactory.getLog(AutoadjustMultipleHiLoGenerator.class); public static final int DEFAULT_START_VALUE = 0; private static final String START_VALUE = "start_value"; public static final int DEFAULT_MAX_LO = 10000; protected int startValue; protected String _query = null; protected String _insert = null; protected String _update = null; protected String _tableName = null; protected int _maxLo; protected long _hi = 0; protected int _lo; protected Class<?> _returnClass; private String selectMaxSQL = null; public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { // 这个结果是高位,保存在数据库中的值. int result = 0; int updateRows = 0; int nextInTable; // 表中ID的最大值 do { // SQL.debug(_query); PreparedStatement qps = conn.prepareStatement(_query); PreparedStatement ips = null; try { ResultSet rs = qps.executeQuery(); boolean isInitialized = rs.next(); // 没有初始化,则代表ID表中,没有该表主键的记录 if (!isInitialized) { nextInTable = this.getNext(conn); _log.debug("表中记录最大值为的下一个值 : " + nextInTable); int curVal = nextInTable - 1;// 当前值 if (curVal == 0) { return 0; } int tmp = curVal / (_maxLo + 1); result = tmp + 1; ips = conn.prepareStatement(_insert); ips.setInt(1, result); ips.execute(); } else { result = rs.getInt(1); } rs.close(); } catch (SQLException sqle) { _log.error("could not read or init a hi value", sqle); throw sqle; } finally { if (ips != null) { ips.close(); } qps.close(); } // sql = update; PreparedStatement ups = conn.prepareStatement(_update); try { ups.setInt(1, result + 1);// 新值 ups.setInt(2, result);// 旧值 updateRows = ups.executeUpdate(); } catch (SQLException sqle) { _log.error("could not update hi value in: " + _tableName, sqle); throw sqle; } finally { ups.close(); } } while (updateRows == 0); return new Integer(result); } public synchronized Serializable generate(SessionImplementor session, Object obj) throws HibernateException { // 低位会不断在内存中加一,如果当低位大于 "最大的低位" 时, //则从数据库中将高位加一,低位归零,再一次循环 if (_lo > _maxLo) { // 高位 int hival = ((Integer) doWorkInNewTransaction(session)).intValue(); _lo = (hival == 0) ? 1 : 0; _hi = hival * (_maxLo + 1); String msg = "高低位生成的ID的信息 : new hiValue=[{0}],maxLo=[{1}],lo=[{2}],hi=[{3}]"; _log.debug(MessageFormat.format(msg, hival, _maxLo, _lo, _hi)); } Number genedId = IdentifierGeneratorFactory.createNumber(_hi + _lo, _returnClass); _lo++; _log.debug("根据高低位生成的ID为: " + genedId); return genedId; } @Override public void configure(Type type, Properties params, Dialect dialect) throws MappingException { startValue = PropertiesHelper.getInt(START_VALUE, params, DEFAULT_START_VALUE); super.configure(type, params, dialect); _query = ClassUtil.getFieldValue(this, "query", String.class); _insert = ClassUtil.getFieldValue(this, "insert", String.class); _update = ClassUtil.getFieldValue(this, "update", String.class); _tableName = ClassUtil.getFieldValue(this, "tableName", String.class); // _maxLo = ClassUtil.getFieldValue(this, "maxLo", Integer.class); _maxLo = PropertiesHelper.getInt(MAX_LO, params, DEFAULT_MAX_LO); _lo = ClassUtil.getFieldValue(this, "lo", Integer.class); _returnClass = ClassUtil .getFieldValue(this, "returnClass", Class.class); configureForIncrement(type, params, dialect); } private void configureForIncrement(Type type, Properties params, Dialect dialect) { String tableList = params.getProperty("tables"); if (tableList == null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES); String[] tables = StringHelper.split(", ", tableList); String column = params.getProperty("column"); if (column == null) column = params.getProperty(PersistentIdentifierGenerator.PK); String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA); String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG); StringBuffer buf = new StringBuffer(); for (int i = 0; i < tables.length; i++) { if (tables.length > 1) { buf.append("select ").append(column).append(" from "); } buf.append(Table.qualify(catalog, schema, tables[i])); if (i < tables.length - 1) buf.append(" union "); } if (tables.length > 1) { buf.insert(0, "( ").append(" ) ids_"); column = "ids_." + column; } selectMaxSQL = "select max(" + column + ") from " + buf.toString(); } private int getNext(Connection conn) { long next; PreparedStatement st = null; ResultSet rs = null; try { st = conn.prepareStatement(selectMaxSQL); rs = st.executeQuery(); try { if (rs.next()) { next = rs.getLong(1) + 1; if (rs.wasNull()) next = 1; } else { next = 1; } selectMaxSQL = null; } finally { if (rs != null) { rs.close(); } if (st != null) { st.close(); } } } catch (SQLException sqle) { throw new RuntimeException(sqle); } return new Long(next).intValue(); } }
发表评论
-
Hibernate 主键生成方式
2009-04-07 22:22 22131 assigned: 主键由外部程 ... -
Hibernate开发总结
2009-04-03 11:55 852终于有时间改middlegen。以前没真正使用Hibernat ... -
Hibernate相关项目介绍
2009-03-26 14:14 813http://www.oschina.net/p/hibern ... -
eclipse3.4关于hibernate tools BUG的解决
2009-03-06 10:44 1323发表人及其连接:sys53 http://sys53.itey ... -
生成映射文件和持久化对象
2009-03-06 10:02 875http://book.csdn.net/bookfiles/ ... -
给hibernateTools写个插件
2009-03-06 09:47 1213CowNew开源团队网站 http://www.cownew. ... -
Hibernate Tools for Eclipse插件的安装和使用
2009-03-06 09:46 3686一直想抛弃Myeclipse,今天终于找到了不用它的理由, E ... -
Middlegen-Hibernate-r5使用之 oracle10g
2009-03-05 21:52 1591Middlegen-Hibernate-r5配置 1得到 ... -
Hibernate3.2 核心包
2009-03-05 21:16 933hibernate 核心包与核 ... -
Hibernate3中的hbm2java和hbm2ddl的ant脚本实现
2009-03-05 20:54 23241.Hibernate-tools.jar这个包已经不像以前那 ... -
Hibernate EntityManager - Hibernate的EJB3.0的JPA标准实现
2009-03-05 20:52 2228Hibernate EntityManager实现了EJB3. ... -
框架Hibernate Validator 简介
2009-03-05 20:43 1411用Annotations 给类或 ... -
Hibernate Search
2009-03-05 20:39 1882不久前Hibernate推出了Hibernate Search ... -
Hibernate 工具
2009-03-05 20:29 745Hibernate Tool 使用说明 http://www ...
相关推荐
【标签】:“源码”和“工具”表明这篇内容可能涉及到具体的代码实现和辅助开发的工具,可能是通过某种代码生成器或者IDE插件来实现映射文件的自动化创建。 【压缩包子文件的文件名称列表】:“hibernate映射文件...
2. **TABLE(自定义表生成器)** - **概述**:`TABLE`策略通过在数据库中创建一个单独的表来管理主键值。这种方式相对独立于数据库类型,适合需要跨库生成唯一ID的场景。该策略通过`@TableGenerator`注解来配置...
3. **注解**:如`@Entity`表示这是一个Hibernate实体,`@Table`指定对应数据库中的表名,`@Id`标识主键,`@GeneratedValue`处理主键生成策略。 除了实体类,生成器还会自动生成对应的Hibernate映射文件(.hbm.xml)...
总的来说,选择合适的主键生成策略和正确配置是Hibernate成功集成到项目的关键步骤。理解这些策略的差异以及它们如何与不同数据库交互,将有助于优化性能并避免潜在的问题。在实际开发中,应根据项目需求和所使用的...
7. **@GenericGenerator**: Hibernate特有的主键生成策略注解,可以指定生成器的名称、策略和参数,支持更灵活的主键生成方式,例如使用UUID、自定义算法等。 在实际开发中,这些注解使得开发者可以不写XML配置文件...
自动生成的Entity类通常包含属性(对应表的字段)和getter/setter方法,有时还会包含一些特定的Hibernate注解,如@Id(主键)和@GeneratedValue(主键生成策略)。 2. **映射文件(Mapping Files)**:在传统的...
6. **第三方库**:在编程语言层面,有许多库和框架提供了主键生成的功能,如Java的Hibernate或Spring框架,它们可以与数据库交互,自动处理主键生成。 使用"SQL主键产生器"工具的优点在于,它可以帮助开发者避免...
- 自定义主键生成策略,如SequenceGenerator、TableGenerator等。 12. **事件监听与拦截器** - 实现Hibernate事件监听器,监听对象的生命周期事件。 - 使用Interceptor,自定义逻辑,如对象的预加载、预更新等。...
在这种方式下,开发者可以自定义序列生成器的名称和数据库中序列的名称,并将其用作主键值。 在跨不同数据库平台执行代码时,Hibernate会根据不同的数据库管理系统,选择合适的主键生成策略。例如,在SQL Server和...
实体类生成器是一种用于自动化创建Java或其他编程语言中的数据模型类的工具。这些类通常代表数据库表中的记录,包含属性(字段)和方法,用于在应用程序中操作数据。使用实体类生成器可以显著提高开发效率,减少手动...
Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者用面向对象的方式来处理数据库操作,而实体生成工具则是这个过程中不可或缺的一部分。 ### Hibernate概述 Hibernate是一种开源的Java ORM框架,它为...
博文链接提到的是对源码的分析,这可能包括了JPA或其实现(如Hibernate)中主键生成相关类的源代码研究,理解它们如何根据指定的策略生成主键。 6. **工具应用**: 标签中的"工具"可能指的是开发者使用的一些辅助...
2.4. Hibernate独有的注解扩展:除了标准的EJB3注解,Hibernate还提供了一些自定义注解,如`@GeneratedValue`用于设置主键生成策略,`@Formula`用于在属性中使用SQL表达式,`@Cache`用于配置缓存,`@Filter`用于动态...
要使用这个工具,开发者首先需要解压文件,然后按照说明配置相关的参数,运行代码生成器,最后将生成的代码整合到自己的SSH2项目中。通过这种方式,开发者可以更专注于业务逻辑的实现,而不用在基础架构上花费太多...
5. **主键生成策略**:Hibernate提供了多种主键生成策略,如`GenerationType.IDENTITY`, `GenerationType.SEQUENCE`, 和 `GenerationType.TABLE`,可以根据不同的数据库系统选择合适的策略。 6. **会话和事务**:...
- `@GeneratedValue`: 用于主键字段,定义主键生成策略,如.AUTO(自增)或.SEQUENCE(序列)。 - `@OneToOne`, `@OneToMany`, `@ManyToOne`, `@ManyToMany`: 用于处理各种关联关系,如一对一、一对多、多对一、多...
5. **Hibernate主键生成器(数值型主键操作方法)** - Hibernate提供了多种主键生成策略,如`Identity`, `Sequence`, `Table`, `Auto`等。对于数值型主键,应根据目标数据库的特性选择合适的生成策略。例如,Oracle...
默认情况下,Hibernate可能会选择自动增长策略,但根据实际需求,可能需要使用`assigned`策略,即主键由应用逻辑生成,例如使用序列或自定义ID生成器。修改后的配置如下: ```xml ``` 这段配置表示主键...
1. 数据库模式理解:生成SQL代码前,代码生成器需要解析数据库模式,包括表结构、字段类型、主键、外键和索引等信息。这涉及对SQL标准和各种数据库系统(如MySQL、PostgreSQL、Oracle、SQL Server等)语法的理解。 ...