标签:
JFinal保存对象后可以取出主键,即使这个主键是数据库自增长的。
今天无意中发现,JFinal保存对象后可以把主键取出来,我的数据库表主键都是自增的。比如
Blog blog = getModel(Blog.class);//这里没有存放id
blog.save();
System.out.println(blog.getInt("id"));//这里居然可以取出来。
今天研究的半天,最后在大家的帮助下终于明白是怎么实现的了。Model类的源码如下:
public boolean save() {
Config config = getConfig();
Table table = getTable();
StringBuilder sql = new StringBuilder();
List<Object> paras = new ArrayList<Object>();
config.dialect.forModelSave(table, attrs, sql, paras);
// if (paras.size() == 0) return false; // The sql "insert into tableName() values()" works fine, so delete this line
// --------
Connection conn = null;
PreparedStatement pst = null;
int result = 0;
try {
conn = config.getConnection();
if (config.dialect.isOracle())
pst = conn.prepareStatement(sql.toString(), new String[]{table.getPrimaryKey()});
else
pst = conn.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);
config.dialect.fillStatement(pst, paras);
result = pst.executeUpdate();
getGeneratedKey(pst, table);
getModifyFlag().clear();
return result >= 1;
} catch (Exception e) {
throw new ActiveRecordException(e);
} finally {
config.close(pst, conn);
}
}
根据波总的指导,红色加粗的代码才是保存后取出主键的关键,而绿色加粗部分是具体实现过程。经过查看API,这个方法是为了创建一个默认 PreparedStatement
对象,该对象能获取自动生成的键。给定常量告知驱动程序是否可以获取自动生成的键。如果 SQL 语句不是一条 INSERT
语句,或者 SQL 语句能够返回自动生成的键(这类语句的列表是特定于供应商的),则忽略此参数【JDK中文文档的原话】。
绿色加粗部分的源代码:
/**
* Get id after save method.
*/
private void getGeneratedKey(PreparedStatement pst, Table table) throws SQLException {
String pKey = table.getPrimaryKey();
if (get(pKey) == null || getConfig().dialect.isOracle()) {
ResultSet rs = pst.getGeneratedKeys();
if (rs.next()) {
Class colType = table.getColumnType(pKey);
if (colType == Integer.class || colType == int.class)
set(pKey, rs.getInt(1));
else if (colType == Long.class || colType == long.class)
set(pKey, rs.getLong(1));
else
set(pKey, rs.getObject(1)); // It returns Long object for int colType
rs.close();
}
}
}
标签:
原文地址:http://my.oschina.net/u/1444945/blog/395400