在数据库操作中,插入数据库信息的时候往往需要使其数据库的中的表字段的主键id能够自增,虽然有的数据库的表字段可也直接在设计的时候就写成自增,比如mysql,但是有的数据库却在实现表字段的自增上却不是很好使,而且各种数据库的实现方式可能不同,所以问了简单统一的管理,方便数据库的移植,而不需要改变SQL创建语句,所以可以单独的创建一个表,专门用于管理数据库表字段主键id的自增,该表(t_table_id)可以按下面这样设计:有一个表名字段table_name(存放需要自增id的表名称),一个是当前对应表的主键id的值value。
创建上面的表之后,然后想该表中插入对应的要进行自增表字段主键id的表的信息。比如:insert into t_table_id table_name,value values('t_client',1);这个语句为表t_client设置主键id冲1开始自增。
其实简单的这样设计了还并不能实现自增,还需要编写代码来进行实现,下面就通过编写java代码来进行实现:
package org.ml.drp.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* id生成器
* @author MuLing
*
*/
public class IdGenerator {
/**
* 根据表名生成该表的序列
* @param tableName
* @return 返回生成的序列
*/
public static int generate(String tableName) {
//使用数据库的悲观锁for update
String sql = "select value from t_table_id where table_name=? for update";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int value = 0;
try {
conn = DbUtil.getConnection();
//开始事务
DbUtil.beginTransaction(conn);
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, tableName);
rs = pstmt.executeQuery();
if (!rs.next()) {
throw new RuntimeException();
}
value = rs.getInt("value");
value++; //自加
modifyValueField(conn, tableName, value);//修改对应序列字段的值
//提交事务
DbUtil.commitTransaction(conn);
}catch(Exception e) {
e.printStackTrace();
//回滚事务
DbUtil.rollbackTransaction(conn);
throw new RuntimeException();
}finally {
DbUtil.close(rs);
DbUtil.close(pstmt);
DbUtil.resetConnection(conn); //重置Connection的状态
DbUtil.close(conn);
}
return value;
}
/**
* 根据表名更新序列字段的值
* @param conn
* @param tableName
* @param value
*/
private static void modifyValueField(Connection conn, String tableName, int value)
throws SQLException {
String sql = "update t_table_id set value=? where table_name=?";
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, value);
pstmt.setString(2, tableName);
pstmt.executeUpdate();
}finally {
DbUtil.close(pstmt);
}
}
public static void main(String[] args) {
int retValue = IdGenerator.generate("t_client");
System.out.println(retValue);
}
}
另外附加下面的数据库工具类(DbUtil.java)中的几个方法实现:
public static void resetConnection(Connection conn) {
try {
if (conn != null) {
if (conn.getAutoCommit()) {
conn.setAutoCommit(false);
}else {
conn.setAutoCommit(true);
}
}
}catch(SQLException e) {}
}
public static void beginTransaction(Connection conn) {
try {
if (conn != null) {
if (conn.getAutoCommit()) {
conn.setAutoCommit(false); //手动提交
}
}
}catch(SQLException e) {}
}
public static void commitTransaction(Connection conn) {
try {
if (conn != null) {
if (!conn.getAutoCommit()) {
conn.commit();
}
}
}catch(SQLException e) {}
}
public static void rollbackTransaction(Connection conn) {
try {
if (conn != null) {
if (!conn.getAutoCommit()) {
conn.rollback();
}
}
}catch(SQLException e) {}
}