`
woming66
  • 浏览: 57559 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

我的各种主键生成策略类

    博客分类:
  • Java
阅读更多
package com.generate;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

/**
 * 主键生成策略
 * @author zzq
 *
 */
public class Generator {

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
	private static Random random = new Random();
	private static NumberFormat nf = new DecimalFormat("000");
	
	private static Map<String, IDTable> idTables = new HashMap<String, IDTable>();
	
	/**
	 * UUID主键生成策略
	 * @return 32位UUID
	 */
	public static String UUIDGenerator() {
		return UUID.randomUUID().toString();
	}
	
	/**
	 * COMB主键生成策略
	 * @return yyyyMMddHHmmssSS 17位时间 + 3位随机数
	 */
	public static String COMBGenerator() {
		String datetime = sdf.format(new Date());
		int end = random.nextInt(1000);
		nf.format(end);
		return datetime + end;
	}
	
	/**
	 * 第三方数据表主键生成策略
	 * @param table 第三方主键表名
	 * @param keyColumnName 主键表识别主键字段名
	 * @param keyValue 主键表识别主键值
	 * @param valueColumnName 主键值字段名
	 * @return 主键值
	 */
	public static synchronized long TableGenerator(String table, String keyColumnName, String keyValue, String valueColumnName) {
		
		String key = table + "/" + keyColumnName + "/" + keyValue + "/" + valueColumnName;
		IDTable idTable = idTables.get(key);
		
		if(null == idTable) {
			idTable = (new Generator()).new IDTable();
			idTables.put(key, idTable);
		}
		
		return idTable.getValue(table, keyColumnName, keyValue, valueColumnName);
	}
	
	/**
	 * 释放资源,将缓存的标识字段同步到数据库中
	 */
	public static synchronized void TableGeneratorClose() {
		
		for(Iterator<String> iter = idTables.keySet().iterator(); iter.hasNext(); ) {
			String key = iter.next();
			Generator.IDTable idTable = idTables.get(key);
			String[] str = key.split("/");
			idTable.destory(str[0], str[1], str[2], str[3]);
		}
	}
	
	/**
	 * 主键表(主要负责向数据库查询对应识别值的主键值) 加入缓存策略
	 * @author 朱志强
	 *
	 */
	public class IDTable {
		
		private long maxValue;
		private long nextValue;
		private static final long POOLSIZE = 10;
		private boolean isInit = false;
		
		public long getValue(String table, String keyName, String keyValue, String valueName) {
			
			if(false == isInit) {
				init(table, keyName, keyValue, valueName);
				isInit = true;
			}
			
			if(nextValue == maxValue) {
				query(table, keyName, keyValue, valueName);
			}
			nextValue++;
			return nextValue;
		}
		
		/**
		 * 初始化资源,将属于与数据表中的标识字段同步
		 * @param table
		 * @param keyName
		 * @param keyValue
		 * @param valueName
		 */
		public void init(String table, String keyName, String keyValue, String valueName) {
			
			StringBuffer sb = new StringBuffer("select ").append(valueName).append(" from ").append(table).append(" where ").append(keyName).append(" = '").append(keyValue).append("'");
			
			Long id = DBUtil.executeQuery(sb.toString());
			
			if(null != id) {
				nextValue = id;
				maxValue = id;
			}
		}
		
		public void query(String table, String keyName, String keyValue, String valueName) {
			
			StringBuffer sb = new StringBuffer("select ").append(valueName).append(" from ").append(table).append(" where ").append(keyName).append(" = '").append(keyValue).append("'");
			
			Long id = DBUtil.executeQuery(sb.toString());
			if(null == id) {
				sb = new StringBuffer("insert into ").append(table).append(" values('").append(keyValue).append("', ").append(POOLSIZE).append(")");
				DBUtil.executeUpdate(sb.toString());
				maxValue = POOLSIZE;
				nextValue = 0;
			} else {
				sb = new StringBuffer("update ").append(table).append(" set ").append(valueName).append("=").append(maxValue + POOLSIZE).append(" where ").append(keyName).append("='").append(keyValue).append("'");
				DBUtil.executeUpdate(sb.toString());
				maxValue += POOLSIZE;
			}
		}
		
		/**
		 * 释放资源,将缓存中的数据同步到数据库中
		 * @param table 
		 * @param keyName
		 * @param keyValue
		 * @param valueName
		 */
		public void destory(String table, String keyName, String keyValue, String valueName) {
		
			StringBuffer sb = new StringBuffer("select ").append(valueName).append(" from ").append(table).append(" where ").append(keyName).append(" = '").append(keyValue).append("'");
			
			Long id = DBUtil.executeQuery(sb.toString());
			if(null != id) {
				sb = new StringBuffer("update ").append(table).append(" set ").append(valueName).append("=").append(nextValue).append(" where ").append(keyName).append("='").append(keyValue).append("'");
				DBUtil.executeUpdate(sb.toString());
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		long id = Generator.TableGenerator("idtable", "keyname", "t_user", "id");
		System.out.println(id);
		
		id = Generator.TableGenerator("idtable", "keyname", "t_user", "id");
		System.out.println(id);
		
		id = Generator.TableGenerator("idtable", "keyname", "t_person", "id");
		System.out.println(id);
		
		id = Generator.TableGenerator("idtable", "keyname", "t_org", "id");
		System.out.println(id);
		
		Generator.TableGeneratorClose();
	}
}


package com.generate;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 数据库连接工厂
 * @author zzq
 *
 */
public class ConnectionFactory {

	private static String USERNAME;
	
	private static String PASSWORD;
	
	private static String URL;
	
	private static String DRIVERNAME;
	
	static {
		try {
			Properties prop = new Properties();
			InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");
			prop.load(is);
			USERNAME = prop.getProperty("username");
			PASSWORD = prop.getProperty("password");
			URL = prop.getProperty("url");
			DRIVERNAME = prop.getProperty("drivername");
			
			is.close();
			
			Class.forName(DRIVERNAME);
		} catch (Exception e) {
			throw new RuntimeException("加载数据源配置文件失败", e);
		}
	}
	
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
		} catch (Exception e) {
			throw new RuntimeException("获取数据库连接失败", e);
		}
		return conn;
	}
	
	public static void close(Connection conn) {
		if(null != conn) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void close(Statement stmt) {
		if(null != stmt) {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void close(ResultSet rs) {
		if(null != rs) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}


public class DBUtil {

	public static int executeUpdate(String sql) {
		Connection conn = null;
		Statement stmt = null;
		try {
			conn = ConnectionFactory.getConnection();
			stmt = conn.createStatement();
			return stmt.executeUpdate(sql);
		} catch(SQLException e) {
			throw new RuntimeException("更新失败", e);
		} finally {
			ConnectionFactory.close(stmt);
			ConnectionFactory.close(conn);
		}
	}
	
	public static Long executeQuery(String sql) {
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null; 
		try {
			conn = ConnectionFactory.getConnection();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			
			boolean isReturn = rs.next();
			if(isReturn == false) {
				return null;
			}
			
			return rs.getLong(1);
		} catch(SQLException e) {
			throw new RuntimeException("查询数据失败", e);
		} finally {
			ConnectionFactory.close(rs);
			ConnectionFactory.close(stmt);
			ConnectionFactory.close(conn);
		}
	}
}
1
1
分享到:
评论

相关推荐

    常用Hibernate主键生成策略

    ### 常用Hibernate主键生成策略详解 #### 一、引言 在数据库设计与操作过程中,主键是确保数据唯一性的关键要素之一。在实际应用中,开发者经常需要处理不同类型的数据库,并且需要应对各种不同的主键生成需求。...

    Hibernate主键生成策略

    本文将详细介绍并比较Hibernate中的各种主键生成策略。 #### 二、主键生成策略 ##### 1. Native (原生) - **定义**:`native`策略根据底层数据库的不同选择最合适的主键生成策略。例如,在Oracle中,它会使用`...

    MybatisPlus主键生成策略方法详解.docx

    综上所述,MybatisPlus的主键生成策略非常灵活,可以根据项目需求选择合适的策略,包括默认的雪花算法、数据库自增、用户输入以及特定数据库序列等方式,同时支持自定义扩展,确保在各种环境下都能高效、稳定地生成...

    Hibernate主键生成方式

    不同的主键生成策略适用于不同的场景,本文将详细介绍 Hibernate 提供的各种主键生成策略,并分析它们的特点及适用场景。 #### 二、主键生成策略 ##### 1. assigned - **定义**:该策略下,主键由外部程序负责...

    mybatis自定义生成代码策略示例

    这个例子可能包括了如何生成 Entity 类、DAO 接口及其实现,以及 Mapper XML 文件,并且可能展示了如何处理复杂的表关联、主键生成策略等。 总之,自定义 MyBatis 代码生成策略是一项实用的技术,它可以帮助我们...

    Hibernate主键策略-sequence

    Hibernate还提供了其他主键生成策略,如`increment`(适用于单线程环境),`identity`(数据库自增,如MySQL),`table`(通过独立的主键生成表)等,开发者应根据具体需求选择合适的策略。 6. **跨数据库兼容性**...

    Hibernate映射文件主键的生成

    在Java的持久化框架Hibernate中,主键的生成策略是一个重要的...在实际开发中,应根据数据库类型和需求选择合适的主键生成策略,确保数据的一致性和完整性。理解并正确配置这些策略,将有助于提高程序的稳定性和性能。

    08_传智播客ibatis教程_sql主键生成方式

    通过学习“08_传智播客ibatis教程_sql主键生成方式”,开发者能够熟练掌握如何在Ibatis中配置和使用各种主键生成策略,从而提高代码的灵活性和数据库操作的效率。在实际开发中,还需要注意不同数据库对主键生成策略...

    解决spring自增型主键问题

    本文将深入探讨如何在SQL Server 2008环境下解决自增型主键的问题,以及如何在Spring框架下进行有效的主键生成策略配置。 ### SQL Server 2008自增型主键问题 SQL Server 2008中的自增型主键,通常通过设置列属性...

    根据数据库生成实体类的一个工具

    这些注解包括但不限于`@Entity`(标记一个类作为数据库表的映射)、`@Table`(指定表名)、`@Column`(指定字段与列的对应关系)、`@Id`(标识主键)、`@GeneratedValue`(定义主键生成策略)等。通过使用这些注解,...

    Oracle 生成实体类.rar

    例如,Entity Framework是一个常用的ORM框架,它可以自动生成实体类和上下文类,但默认并不支持Oracle数据库,需要安装额外的提供者如Oracle Developer Tools for Visual Studio。 这个压缩包可能包含了一个自定义...

    mysql自动生成实体类工具类

    总结来说,"mysql自动生成实体类工具类",如MyBatis Generator,是提高开发效率的有效工具,它能帮助开发者快速生成与数据库表结构对应的Java实体类,同时支持注释自定义和多种代码生成策略。在实际开发中,利用这样...

    hibernate各种主健详解

    ### Hibernate 主键生成策略详解 在使用Hibernate框架进行持久化操作时,主键生成策略的选择对数据一致性、系统性能及可扩展性具有重要的影响。本文将深入探讨Hibernate中几种常用的主键生成策略,并分析各自的优...

    myeclipse自动生成hibernate映射文件

    在这个过程中,可以选择主键生成策略(如序列`sequence`),并设置实体类的名称。 4. **主键生成策略**: 主键生成策略决定了如何在数据库中生成唯一的主键值。在本例中,选择了序列`sequence`,这适用于Oracle...

    hibernate应用[包括示例,映射,主键自增,各种查询操作方式以及配置文档以及 Annotation示例]

    3. **主键自增**:Hibernate提供了多种主键生成策略,包括自动增长(Identity)、序列(Sequence)等,这些策略确保了每个新创建的对象都有一个唯一的标识。 4. **查询操作**:这包括了HQL(Hibernate Query ...

    mybatisPlusGenerator.zip

    10. **主键生成策略**:MybatisPlus支持多种主键生成策略,如ID_WORKER(雪花算法)、IDENTITY(数据库自增)、INPUT(手动输入)等,开发者可以根据实际需求选择。 使用MybatisPlus进行项目搭建时,通常步骤包括:...

    mybaties自动生成实体类及映射文件

    同时,你可以设置需要生成实体类和映射文件的表名,以及自定义生成规则,比如字段命名策略、是否生成注释等。 实体类(Entity Class)是Java对象,代表数据库中的表记录。MBG会为每个表生成对应的实体类,其中包含...

    15_传智播客JPA详解_JPA中的联合主键

    - 当使用联合主键时,JPA默认不会生成主键值,通常需要自定义生成策略或手动设置主键值。 - 在保存或更新实体时,确保联合主键的所有字段都有值,否则会抛出异常。 理解并正确使用JPA中的联合主键对于开发复杂的...

    mybatis generator生成器

    1. 自动生成主键策略:MBG可以根据数据库的主键生成策略(如Identity、Sequence、AutoIncrement等)自动处理主键生成。 2. 自定义插件:MBG支持插件机制,用户可以编写自己的插件来扩展其功能,比如添加自定义的生成...

    java根据数据库表或视图创建实体

    7. **自定义配置**:用户可能需要对生成的实体类进行特定的定制,如忽略某些字段、指定主键策略等。工具可能提供了配置选项来满足这些需求。 8. **性能优化**:考虑到大量表的处理,程序可能还实现了批量生成和并行...

Global site tag (gtag.js) - Google Analytics