继承AbstractXmlElementGenerator类,覆盖addElements方法:public class SaveOrUpdate extends AbstractXmlElementGenerator {
public SaveOrUpdate() {
super();
}
@Override
public void addElements(XmlElement parentElement) {
XmlElement answer = new XmlElement("insert"); //$NON-NLS-1$
answer.addAttribute(new Attribute("id", "saveOrUpdate")); //$NON-NLS-1$
FullyQualifiedJavaType parameterType = introspectedTable.getRules().calculateAllFieldsClass();
answer.addAttribute(new Attribute("parameterType", //$NON-NLS-1$
parameterType.getFullyQualifiedName()));
context.getCommentGenerator().addComment(answer);
GeneratedKey gk = introspectedTable.getGeneratedKey();
if (gk != null) {
IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn());
// if the column is null, then it's a configuration error. The
// warning has already been reported
if (introspectedColumn != null) {
if (gk.isJdbcStandard()) {
answer.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$
answer.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$
answer.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$
} else {
answer.addElement(getSelectKey(introspectedColumn, gk));
}
}
}
StringBuilder sb = new StringBuilder();
sb.append("insert into "); //$NON-NLS-1$
sb.append(introspectedTable.getFullyQualifiedTableNameAtRuntime());
answer.addElement(new TextElement(sb.toString()));
XmlElement insertTrimElement = new XmlElement("trim"); //$NON-NLS-1$
insertTrimElement.addAttribute(new Attribute("prefix", "(")); //$NON-NLS-1$ //$NON-NLS-2$
insertTrimElement.addAttribute(new Attribute("suffix", ")")); //$NON-NLS-1$ //$NON-NLS-2$
insertTrimElement.addAttribute(new Attribute("suffixOverrides", ",")); //$NON-NLS-1$ //$NON-NLS-2$
answer.addElement(insertTrimElement);
XmlElement valuesTrimElement = new XmlElement("trim"); //$NON-NLS-1$
valuesTrimElement.addAttribute(new Attribute("prefix", "values (")); //$NON-NLS-1$ //$NON-NLS-2$
valuesTrimElement.addAttribute(new Attribute("suffix", ")")); //$NON-NLS-1$ //$NON-NLS-2$
valuesTrimElement.addAttribute(new Attribute("suffixOverrides", ",")); //$NON-NLS-1$ //$NON-NLS-2$
answer.addElement(valuesTrimElement);
TextElement updateElement = new TextElement("ON DUPLICATE KEY UPDATE");
answer.addElement(updateElement);
for (IntrospectedColumn introspectedColumn : ListUtilities
.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns())) {
if (introspectedColumn.isSequenceColumn() || introspectedColumn.getFullyQualifiedJavaType().isPrimitive()) {
// if it is a sequence column, it is not optional
// This is required for MyBatis3 because MyBatis3 parses
// and calculates the SQL before executing the selectKey
// if it is primitive, we cannot do a null check
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(',');
insertTrimElement.addElement(new TextElement(sb.toString()));
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
sb.append(',');
valuesTrimElement.addElement(new TextElement(sb.toString()));
continue;
}
sb.setLength(0);
sb.append(introspectedColumn.getJavaProperty());
sb.append(" != null"); //$NON-NLS-1$
XmlElement insertNotNullElement = new XmlElement("if"); //$NON-NLS-1$
insertNotNullElement.addAttribute(new Attribute("test", sb.toString())); //$NON-NLS-1$
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(',');
insertNotNullElement.addElement(new TextElement(sb.toString()));
insertTrimElement.addElement(insertNotNullElement);
sb.setLength(0);
sb.append(introspectedColumn.getJavaProperty());
sb.append(" != null"); //$NON-NLS-1$
XmlElement valuesNotNullElement = new XmlElement("if"); //$NON-NLS-1$
valuesNotNullElement.addAttribute(new Attribute("test", sb.toString())); //$NON-NLS-1$
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
sb.append(',');
valuesNotNullElement.addElement(new TextElement(sb.toString()));
valuesTrimElement.addElement(valuesNotNullElement);
}
XmlElement dynamicElement = new XmlElement("set"); //$NON-NLS-1$
answer.addElement(dynamicElement);
for (IntrospectedColumn introspectedColumn : ListUtilities
.removeGeneratedAlwaysColumns(introspectedTable.getAllColumns())) {
sb.setLength(0);
sb.append(introspectedColumn.getJavaProperty("record.")); //$NON-NLS-1$
sb.append(" != null"); //$NON-NLS-1$
XmlElement isNotNullElement = new XmlElement("if"); //$NON-NLS-1$
isNotNullElement.addAttribute(new Attribute("test", sb.toString())); //$NON-NLS-1$
dynamicElement.addElement(isNotNullElement);
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn));
sb.append(" = "); //$NON-NLS-1$
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "record.")); //$NON-NLS-1$
sb.append(',');
isNotNullElement.addElement(new TextElement(sb.toString()));
}
// answer.addElement(getUpdateByExampleIncludeElement());
if (context.getPlugins().sqlMapInsertSelectiveElementGenerated(answer, introspectedTable)) {
parentElement.addElement(answer);
}
}
}
对应的SQL示例:INSERT INTO `demo`
(`id`,`name`,`age`,`val`)
VALUES(1,"name",25,"abc")
ON DUPLICATE KEY UPDATE
`id`=1,`name` ="tom",`age` = 26,`val`="abc";