服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
 热线电话: #
当前位置: 主页 > php教程 > php教程 >

关于MySQL提供的Last_insert_id()函数使用的理解

时间:2016-01-05 11:46来源:未知 作者:最模板 点击:
Last_insert_id()是MYSQL提供的返回 当前客户端 最后一个insert或update查询中 设置为AUTO_INCREMENT 列的值 Last_insert_id()不受其他客户端影响,所以是线程安全的,当前客户端只能拿到当前客户端

Last_insert_id()是MYSQL提供的返回当前客户端最后一个insert或update查询中设置为AUTO_INCREMENT列的值

Last_insert_id()不受其他客户端影响,所以是线程安全的,当前客户端只能拿到当前客户端的最新值,不需加锁处理

mybatis中的userGeneratedKeys="true" keyProperty="id"获取自增id的源码:

SimpleStatementHandler:

复制代码
 1 public int update(Statement statement)
 2       throws SQLException {
 3     String sql = boundSql.getSql();
 4     Object parameterObject = boundSql.getParameterObject();
 5     KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
 6     int rows;
 7     if (keyGenerator instanceof Jdbc3KeyGenerator) {  //使用Jdbc3KeyGenerator类型得到自增主键
 8       statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
 9       rows = statement.getUpdateCount();
10       keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
11     } else if (keyGenerator instanceof SelectKeyGenerator) { //使用selectKeyGenerator(<selectKey></selectKey>), 对于MYSQL则使用 select LAST_INSERT_ID() 来实现获取自增主键ID
12       statement.execute(sql);
13       rows = statement.getUpdateCount();
14       keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
15     } else {
16       statement.execute(sql);
17       rows = statement.getUpdateCount();
18     }
19     return rows;
20   }
复制代码

1. JDBC3KeyGenerator

复制代码
 1 public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
 2     List<Object> parameters = new ArrayList<Object>();
 3     parameters.add(parameter);
 4     processBatch(ms, stmt, parameters);
 5   }
 6 
 7   public void processBatch(MappedStatement ms, Statement stmt, List<Object> parameters) {
 8     ResultSet rs = null;
 9     try {
10       rs = stmt.getGeneratedKeys();
11       final Configuration configuration = ms.getConfiguration();
12       final TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
13       final String[] keyProperties = ms.getKeyProperties();
14       final ResultSetMetaData rsmd = rs.getMetaData();
15       TypeHandler<?>[] typeHandlers = null;
16       if (keyProperties != null && rsmd.getColumnCount() >= keyProperties.length) {
17         for (Object parameter : parameters) {
18           if (!rs.next()) break; // there should be one row for each statement (also one for each parameter)
19           final MetaObject metaParam = configuration.newMetaObject(parameter);
20           if (typeHandlers == null) typeHandlers = getTypeHandlers(typeHandlerRegistry, metaParam, keyProperties);
21           populateKeys(rs, metaParam, keyProperties, typeHandlers); //将生成的自增主键,可能是多个,设置到对象相对应的属性中
22         }
23       }
24     } catch (Exception e) {
25       throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e, e);
26     } finally {
27       if (rs != null) {
28         try {
29           rs.close();
30         } catch (Exception e) {
31           // ignore
32         }
33       }
34     }
35   }
复制代码

2.selectKeyGenerator

复制代码
 1 public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
 2     if (!executeBefore) {
 3       processGeneratedKeys(executor, ms, parameter);
 4     }
 5   }
 6 
 7   private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
 8     try {
 9       if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
10         String[] keyProperties = keyStatement.getKeyProperties();
11         final Configuration configuration = ms.getConfiguration();
12         final MetaObject metaParam = configuration.newMetaObject(parameter);
13         if (keyProperties != null) {
14           // Do not close keyExecutor.
15           // The transaction will be closed by parent executor.
16           Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
17           List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); //若是selectKey,则执行selectkey中的SQL语句查询,对于MySQL一般是select LAST_INSERT_ID()
18           if (values.size() == 0) {
19             throw new ExecutorException("SelectKey returned no data.");            
20           } else if (values.size() > 1) {
21             throw new ExecutorException("SelectKey returned more than one value.");
22           } else {
23             MetaObject metaResult = configuration.newMetaObject(values.get(0));
24             if (keyProperties.length == 1) {
25               if (metaResult.hasGetter(keyProperties[0])) {
26                 setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0]));
27               } else {
28                 // no getter for the property - maybe just a single value object
29                 // so try that
30                 setValue(metaParam, keyProperties[0], values.get(0));
31               }
32             } else {
33               handleMultipleProperties(keyProperties, metaParam, metaResult);
34             }
35           }
36         }
37       }
38     } catch (ExecutorException e) {
39       throw e;
40     } catch (Exception e) {
41       throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e);
42     }
43   }
复制代码

(责任编辑:最模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容