方向控制:我们使用一个表来存放所有所要管理表的主键和主键值.
表: keytable
create table keytable(
keyname varchar2(20) primary key,
keyvalue number(10) not null);
我们使用一个类来管理类的生成策略: Class KeyInfo
此类一次取出某一个主键的某一个缓冲值范围,每调用一次getNextKey()返回一个此主键的值,并且设定下一个主键值,取值策略如下: 值在范围内,取出值,如果值达到了缓冲范围的最大值,那么和数据库交互一下,生成下一个缓冲范围.在取出缓冲范围之前先更新一下数据库的主键值,避免取缓冲范围失败,下次再获得主键值已被使用.具体类如下:
package singleton.keySequence;
public class KeyInfo {
private long minKey;
private long maxKey;
private int poolSize;
private long nextKey;
private String keyName;
/**
* @param poolSize 键的缓冲长度
* @param keyName 键的名字
*/
public KeyInfo(int poolSize,String keyName){
this.poolSize=poolSize;
this.keyName=keyName;
queryDB();
}
/**
* @return the value of nextKey 用于获得下一个键的方法
* 如果返回的键值大于键的上限,查询数据库重新进行对键的最大值,最小值和下一个返回键值的设定
*/
public long getNextKey(){
if(nextKey>maxKey){
queryDB();
}
return nextKey++;
}
/**
* 查询数据库重新进行对键的最大值,最小值和下一个返回键值的设定
*/
private void queryDB(){
String updateSql="UPDATE KEYTABLE SET KEYVALUE=KEYVALUE+"
+poolSize+" WHERE KEYNAME='"+keyName+"'";
String querySql="select KEYVALUE FROM KEYTABLE WHERE KEYNAME='"+keyName+"'";
JDBCTemplate.update(updateSql);
// System.out.println(updateSql);
// System.out.println(querySql);
long valueFromDB=(Integer)JDBCTemplate.query(querySql); maxKey=valueFromDB;
minKey=maxKey-poolSize+1;
nextKey=minKey;
}
}
我们使用单例类来管理这些主键生成方式:
package singleton.keySequence;
import java.util.HashMap;
import java.util.Map;
public class KeyGenerator {
private Map<String,KeyInfo> keyMap=new HashMap<String,KeyInfo>(10);
private static final int POOL_SIZE=30;
private static KeyGenerator keygen=new KeyGenerator();
private KeyGenerator() {
}
public static KeyGenerator getInstance(){
return keygen;
}
public long getNextKey(String keyName){
if(keyMap.containsKey(keyName)){
return keyMap.get(keyName).getNextKey();
}else{
KeyInfo keyInfo=new KeyInfo(POOL_SIZE,keyName);
keyMap.put(keyName, keyInfo);
return keyInfo.getNextKey();
}
}
}
JDBC访问数据库类 :
数据库工具类:JDBCConnectionFactory
管理Connection对象和资源关闭
/*
* (1)功能一:为用户提供连接对象
* (2)功能三:提供通用的关闭
*/
package common.db;
import java.sql.*;
import java.util.*;
import java.io.*;
public class JDBCConnectionFactory
{
static String url;
static String user;
static String password;
//从文件中加载数据库的连接信息
//目的:降低耦合度,即更换数据库时无需更改源代码。
static
{
try
{
FileInputStream fis=new FileInputStream("common/db/dbtext");
Properties pro=new Properties();
pro.load(fis);
url=pro.getProperty("url");
user=pro.getProperty("username");
password=pro.getProperty("password");
fis.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
//功能一:
public static Connection getConnection()
{
Connection conn=null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn=DriverManager.getConnection(url, user, password);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
//功能三:
public static void close(Connection conn,ResultSet rs,Statement stmt)
{
try
{
if(conn!=null)
conn.close();
if(stmt!=null)
stmt.close();
if(rs!=null)
rs.close();
}catch(SQLException e){
System.out.println(e.getMessage());
}
}
}
具体的数据库访问类
package common.db;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTemplate {
private static Connection conn=null;
private static Statement stmt=null;
private static ResultSet rs=null;
public static void update(String updateSql) throws Exception{
conn=JDBCConnectionFactory.getConnection();
stmt=conn.createStatement();
stmt.executeUpdate(updateSql);
JDBCConnectionFactory.close(conn, null, stmt);
conn=null;
stmt=null;
}
public static Object query(String querySql)throws Exception{
conn=JDBCConnectionFactory.getConnection();
stmt=conn.createStatement();
rs=stmt.executeQuery(querySql);
int i=-1;
while(rs.next()){
i=rs.getInt(1);
if(i!=-1)
break;
}
JDBCConnectionFactory.close(conn, rs, stmt);
conn=null;
stmt=null;
return i;
}
}
以下是测试类
package singleton.keySequence;
public class ClientTest {
public static void main(String[] args) throws Exception{
KeyGenerator key=KeyGenerator.getInstance();
for(int i=0;i<15;i++){
System.out.println(key.getNextKey("person_id"));
System.out.println(key.getNextKey("person_id"));
}
}
}
以上内容在MyEclipse 和Oracle9i上测试通过,
欢迎朋友相互交流,luoyuzj911@163.com
分享到:
相关推荐
在Java的持久化框架中,如JPA(Java Persistence API)和Hibernate,主键生成策略是数据模型设计的重要部分。主键通常是表中唯一标识记录的一列或一组列,用于确保数据的完整性和唯一性。本篇文章将深入探讨JPA的4种...
在Java的持久化框架Hibernate中,主键生成策略是一个至关重要的概念,它决定了数据库表中主键值如何自动生成。主键通常是表中唯一标识记录的一列,对于数据的完整性和一致性至关重要。以下是对Hibernate中主键生成...
### Hibernate 主键生成策略详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 框架,它允许开发人员将 Java 对象映射到数据库表中的记录,从而极大地简化了数据访问层的开发工作。在 Hibernate 中,...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者...选择合适的主键生成策略取决于项目需求,包括数据库类型、性能需求、并发性和可移植性等。在设计时,应充分考虑这些因素以确保主键的正确性和一致性。
【hibernate主键生成策略】是Hibernate框架中用于生成持久化对象主键的重要机制,它决定了如何在数据库中创建唯一的标识符。在SSH(Spring、Struts、Hibernate)架构中,Hibernate作为持久层框架,主键生成策略的...
4. **设置主键生成策略**: JPA提供了多种主键生成策略,例如`GenerationType.IDENTITY`(依赖于数据库生成)、`GenerationType.AUTO`(由JPA实现决定)等。 5. **编写DAO层**: 使用EntityManager进行CRUD操作,如`...
### Hibernate 主键生成策略与配置详解 #### 一、概述 在使用Hibernate进行持久化操作时,合理选择和配置主键生成策略对于确保数据的一致性和优化性能至关重要。本文将详细介绍几种常见的主键生成策略,并结合示例...
在实际应用中,选择哪种主键生成策略应考虑如下因素: - 数据库类型和版本 - 应用程序的需求,如是否需要分布式或并行插入 - 性能要求,包括查询速度和存储空间 - 数据一致性与安全性 - 系统扩展性和可维护性 设计...
通过本文的介绍,我们可以了解到Hibernate提供的几种主键生成策略各有特点,开发者可以根据项目的实际需求和所使用的数据库类型来选择最适合的策略。无论是自然主键还是代理主键,Hibernate都能够提供灵活而强大的...
这里的`@Id`注解标记`id`字段为实体的主键,而`@GeneratedValue`注解表示主键生成策略。`GenerationType.IDENTITY`意味着主键值由数据库自动生成,比如在MySQL中,这通常对应于`AUTO_INCREMENT`。 **JPA主键生成...
数据库主键生成GUID 在数据库设计中,选择合适的主键类型是非常重要的。GUID(Global Unique Identifier,全局唯一标识符)是一种常用的主键类型,它可以提供唯一的标识符,用于标识数据库中的每一条记录。 GUID的...
- **概述**:`AUTO`是最常用的主键生成策略之一,也是JPA默认采用的方式。当使用该策略时,JPA会根据后端数据库的不同特性自动选择合适的主键生成方式。例如,在MySQL中,如果表的主键是自增字段,则使用数据库自身...
数据库主键设计的五种方法 数据库主键设计是数据库设计中一个非常重要的环节,好的主键设计可以提高数据库的性能和可扩展性。本文将介绍五种常见的主键设计方法,每种方法都有其优点和缺陷。 第一种:编号作主键 ...
Hibernate各种主键生成策略详解,包括 assigned increment hilo seqhilo sequence identity native uuid foreign uuid.hex sequence-identity 等