Skip to content

Commit ebe0434

Browse files
committed
使用自定义的 SelectKeyGenerator,防止有默认值时被替换掉 fix abel533#213
1 parent f835029 commit ebe0434

File tree

2 files changed

+129
-1
lines changed

2 files changed

+129
-1
lines changed

src/main/java/tk/mybatis/mapper/mapperhelper/MapperTemplate.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
2929
import org.apache.ibatis.executor.keygen.KeyGenerator;
3030
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
31-
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
3231
import org.apache.ibatis.mapping.*;
3332
import org.apache.ibatis.reflection.MetaObject;
3433
import org.apache.ibatis.reflection.SystemMetaObject;
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* Copyright 2009-2016 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package tk.mybatis.mapper.mapperhelper;
17+
18+
import org.apache.ibatis.executor.Executor;
19+
import org.apache.ibatis.executor.ExecutorException;
20+
import org.apache.ibatis.executor.keygen.KeyGenerator;
21+
import org.apache.ibatis.mapping.MappedStatement;
22+
import org.apache.ibatis.reflection.MetaObject;
23+
import org.apache.ibatis.session.Configuration;
24+
import org.apache.ibatis.session.ExecutorType;
25+
import org.apache.ibatis.session.RowBounds;
26+
27+
import java.sql.Statement;
28+
import java.util.List;
29+
30+
/**
31+
* @author Clinton Begin
32+
* @author Jeff Butler
33+
*/
34+
public class SelectKeyGenerator implements KeyGenerator {
35+
36+
public static final String SELECT_KEY_SUFFIX = "!selectKey";
37+
private boolean executeBefore;
38+
private MappedStatement keyStatement;
39+
40+
public SelectKeyGenerator(MappedStatement keyStatement, boolean executeBefore) {
41+
this.executeBefore = executeBefore;
42+
this.keyStatement = keyStatement;
43+
}
44+
45+
@Override
46+
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
47+
if (executeBefore) {
48+
processGeneratedKeys(executor, ms, parameter);
49+
}
50+
}
51+
52+
@Override
53+
public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
54+
if (!executeBefore) {
55+
processGeneratedKeys(executor, ms, parameter);
56+
}
57+
}
58+
59+
private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
60+
try {
61+
if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
62+
String[] keyProperties = keyStatement.getKeyProperties();
63+
final Configuration configuration = ms.getConfiguration();
64+
final MetaObject metaParam = configuration.newMetaObject(parameter);
65+
if (keyProperties != null) {
66+
// Do not close keyExecutor.
67+
// The transaction will be closed by parent executor.
68+
Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
69+
List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
70+
if (values.size() == 0) {
71+
throw new ExecutorException("SelectKey returned no data.");
72+
} else if (values.size() > 1) {
73+
throw new ExecutorException("SelectKey returned more than one value.");
74+
} else {
75+
MetaObject metaResult = configuration.newMetaObject(values.get(0));
76+
if (keyProperties.length == 1) {
77+
if (metaResult.hasGetter(keyProperties[0])) {
78+
setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0]));
79+
} else {
80+
// no getter for the property - maybe just a single value object
81+
// so try that
82+
setValue(metaParam, keyProperties[0], values.get(0));
83+
}
84+
} else {
85+
handleMultipleProperties(keyProperties, metaParam, metaResult);
86+
}
87+
}
88+
}
89+
}
90+
} catch (ExecutorException e) {
91+
throw e;
92+
} catch (Exception e) {
93+
throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e);
94+
}
95+
}
96+
97+
private void handleMultipleProperties(String[] keyProperties,
98+
MetaObject metaParam, MetaObject metaResult) {
99+
String[] keyColumns = keyStatement.getKeyColumns();
100+
101+
if (keyColumns == null || keyColumns.length == 0) {
102+
// no key columns specified, just use the property names
103+
for (String keyProperty : keyProperties) {
104+
setValue(metaParam, keyProperty, metaResult.getValue(keyProperty));
105+
}
106+
} else {
107+
if (keyColumns.length != keyProperties.length) {
108+
throw new ExecutorException("If SelectKey has key columns, the number must match the number of key properties.");
109+
}
110+
for (int i = 0; i < keyProperties.length; i++) {
111+
setValue(metaParam, keyProperties[i], metaResult.getValue(keyColumns[i]));
112+
}
113+
}
114+
}
115+
116+
private void setValue(MetaObject metaParam, String property, Object value) {
117+
if (metaParam.hasSetter(property)) {
118+
if(metaParam.hasGetter(property)){
119+
Object defaultValue = metaParam.getValue(property);
120+
if(defaultValue != null){
121+
return;
122+
}
123+
}
124+
metaParam.setValue(property, value);
125+
} else {
126+
throw new ExecutorException("No setter found for the keyProperty '" + property + "' in " + metaParam.getOriginalObject().getClass().getName() + ".");
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)