mybatis generator 的使用可参考 MyBatis:自动生成Mapper代码和映射XML 。
自动生成 select for update 语句的方案:
方案1
使用为 mybatis generator 编写的一个 GUI 工具: https://github.com/zouzg/mybatis-generator-gui,有生成 select for update 的选项。
方案2
编写插件。可以参考已有的插件,比如 org.mybatis.generator.plugins.RowBoundsPlugin
。
示例:
package tool.plugin;
import org.mybatis.generator.api.FullyQualifiedTable;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import java.util.*;
public class SelectForUpdatePlugin extends PluginAdapter {
private Map<FullyQualifiedTable, List<XmlElement>> elementsToAdd =
new HashMap<FullyQualifiedTable, List<XmlElement>>();
@Override
public boolean validate(List<String> warnings) {
return true;
}
/**
* 扩展接口中的 selectByExampleWithBLOBs 方法
*/
@Override
public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method,
Interface interfaze, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndAddMethod(method, interfaze);
}
return true;
}
/**
* 扩展接口中的 selectByExample 方法
*/
@Override
public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(
Method method, Interface interfaze, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndAddMethod(method, interfaze);
}
return true;
}
/**
* 扩展接口中的 selectByPrimaryKey 方法
*/
@Override
public boolean clientSelectByPrimaryKeyMethodGenerated(
Method method, Interface interfaze, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndAddMethod(method, interfaze);
}
return true;
}
/**
* 扩展 xml 中的 selectByExampleWithBLOBs 方法
*/
@Override
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
XmlElement element, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndSaveElement(element, introspectedTable.getFullyQualifiedTable());
}
return true;
}
/**
* 扩展 xml 中的 selectByExample 方法
*/
@Override
public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(
XmlElement element, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndSaveElement(element, introspectedTable.getFullyQualifiedTable());
}
return true;
}
/**
* 扩展 xml 中的 selectByExample 方法
*/
@Override
public boolean sqlMapSelectByPrimaryKeyElementGenerated(
XmlElement element, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
copyAndSaveElement(element, introspectedTable.getFullyQualifiedTable());
}
return true;
}
/**
* 将 XML 追加的内容放入 XML 根节点中
* 本方法会在 sqlMapSelectByPrimaryKeyElementGenerated 等方法之后运行
*/
@Override
public boolean sqlMapDocumentGenerated(Document document,
IntrospectedTable introspectedTable) {
List<XmlElement> elements = elementsToAdd.get(introspectedTable.getFullyQualifiedTable());
if (elements != null) {
for (XmlElement element : elements) {
document.getRootElement().addElement(element);
}
}
return true;
}
private void copyAndAddMethod(Method method, Interface interfaze) {
Method newMethod = new Method(method);
newMethod.setName(method.getName() + "ForUpdate");
interfaze.addMethod(newMethod);
}
private void copyAndSaveElement(XmlElement element, FullyQualifiedTable fqt) {
XmlElement newElement = new XmlElement(element);
// 修改 id
for (Iterator<Attribute> iterator = newElement.getAttributes().iterator(); iterator.hasNext();) {
Attribute attribute = iterator.next();
if ("id".equals(attribute.getName())) {
iterator.remove();
Attribute newAttribute = new Attribute("id", attribute.getValue() + "ForUpdate");
newElement.addAttribute(newAttribute);
break;
}
}
// 追加 for update
TextElement textElement = new TextElement("for update");
newElement.addElement(textElement);
List<XmlElement> elements = elementsToAdd.get(fqt);
if (elements == null) {
elements = new ArrayList<XmlElement>();
elementsToAdd.put(fqt, elements);
}
elements.add(newElement);
}
}