1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.executor.keygen;
17
18 import java.sql.ResultSet;
19 import java.sql.ResultSetMetaData;
20 import java.sql.SQLException;
21 import java.sql.Statement;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.apache.ibatis.executor.Executor;
26 import org.apache.ibatis.executor.ExecutorException;
27 import org.apache.ibatis.mapping.MappedStatement;
28 import org.apache.ibatis.reflection.MetaObject;
29 import org.apache.ibatis.session.Configuration;
30 import org.apache.ibatis.type.TypeHandler;
31 import org.apache.ibatis.type.TypeHandlerRegistry;
32
33
34
35
36 public class Jdbc3KeyGenerator implements KeyGenerator {
37
38 @Override
39 public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
40
41 }
42
43 @Override
44 public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
45 List<Object> parameters = new ArrayList<Object>();
46 parameters.add(parameter);
47 processBatch(ms, stmt, parameters);
48 }
49
50 public void processBatch(MappedStatement ms, Statement stmt, List<Object> parameters) {
51 ResultSet rs = null;
52 try {
53 rs = stmt.getGeneratedKeys();
54 final Configuration configuration = ms.getConfiguration();
55 final TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
56 final String[] keyProperties = ms.getKeyProperties();
57 final ResultSetMetaData rsmd = rs.getMetaData();
58 TypeHandler<?>[] typeHandlers = null;
59 if (keyProperties != null && rsmd.getColumnCount() >= keyProperties.length) {
60 for (Object parameter : parameters) {
61
62 if (!rs.next()) {
63 break;
64 }
65 final MetaObject metaParam = configuration.newMetaObject(parameter);
66 if (typeHandlers == null) {
67 typeHandlers = getTypeHandlers(typeHandlerRegistry, metaParam, keyProperties);
68 }
69 populateKeys(rs, metaParam, keyProperties, typeHandlers);
70 }
71 }
72 } catch (Exception e) {
73 throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e, e);
74 } finally {
75 if (rs != null) {
76 try {
77 rs.close();
78 } catch (Exception e) {
79
80 }
81 }
82 }
83 }
84
85 private TypeHandler<?>[] getTypeHandlers(TypeHandlerRegistry typeHandlerRegistry, MetaObject metaParam, String[] keyProperties) {
86 TypeHandler<?>[] typeHandlers = new TypeHandler<?>[keyProperties.length];
87 for (int i = 0; i < keyProperties.length; i++) {
88 if (metaParam.hasSetter(keyProperties[i])) {
89 Class<?> keyPropertyType = metaParam.getSetterType(keyProperties[i]);
90 TypeHandler<?> th = typeHandlerRegistry.getTypeHandler(keyPropertyType);
91 typeHandlers[i] = th;
92 }
93 }
94 return typeHandlers;
95 }
96
97 private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
98 for (int i = 0; i < keyProperties.length; i++) {
99 TypeHandler<?> th = typeHandlers[i];
100 if (th != null) {
101 Object value = th.getResult(rs, i + 1);
102 metaParam.setValue(keyProperties[i], value);
103 }
104 }
105 }
106
107 }