Skip to content

Commit 46608ea

Browse files
committed
feat: support generate sql from xml and execute the sql
1 parent 1ec0b83 commit 46608ea

27 files changed

+1314
-63
lines changed

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ dependencies {
1515
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
1616
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
1717
implementation 'org.mybatis:mybatis:3.5.6'
18+
implementation 'com.alibaba:fastjson:1.2.78'
19+
implementation 'mysql:mysql-connector-java:5.1.13'
20+
implementation 'com.github.vertical-blank:sql-formatter:2.0.3'
1821
}
1922

2023
// See https://github.com/JetBrains/gradle-intellij-plugin/

gradlew

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ case "`uname`" in
8080
;;
8181
esac
8282

83+
8384
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
8485

8586

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package io.github.linyimin.plugin.compile;
2+
3+
import com.intellij.compiler.impl.ModuleCompileScope;
4+
import com.intellij.openapi.compiler.CompilerManager;
5+
import com.intellij.openapi.module.Module;
6+
import com.intellij.openapi.module.ModuleUtilCore;
7+
import com.intellij.openapi.project.Project;
8+
import com.intellij.openapi.roots.OrderEnumerator;
9+
import com.intellij.openapi.ui.Messages;
10+
import com.intellij.openapi.util.io.FileUtil;
11+
import com.intellij.openapi.vfs.VirtualFile;
12+
import com.intellij.psi.PsiClass;
13+
import com.intellij.psi.PsiMethod;
14+
import com.intellij.psi.util.ClassUtil;
15+
import com.intellij.util.lang.UrlClassLoader;
16+
import io.github.linyimin.plugin.service.MybatisSqlStateComponent;
17+
import io.github.linyimin.plugin.service.model.MybatisSqlConfiguration;
18+
import io.github.linyimin.plugin.utils.JavaUtils;
19+
import org.apache.commons.lang3.StringUtils;
20+
21+
import java.io.File;
22+
import java.net.MalformedURLException;
23+
import java.net.URL;
24+
import java.util.ArrayList;
25+
import java.util.List;
26+
27+
28+
/**
29+
* @author yiminlin
30+
* @date 2022/02/07 1:49 上午
31+
**/
32+
public class MybatisPojoCompile {
33+
34+
// TODO: 需要优化成只编译Mybatis需要的类
35+
36+
public static ClassLoader classLoader;
37+
38+
public static void compile(Project project) {
39+
40+
MybatisSqlConfiguration sqlConfig = project.getService(MybatisSqlStateComponent.class).getState();
41+
assert sqlConfig != null;
42+
43+
String methodName = sqlConfig.getMethod();
44+
String clazzName = StringUtils.substring(methodName,0, StringUtils.lastIndexOf(methodName, "."));
45+
46+
PsiClass psiClass = JavaUtils.findClazz(project, clazzName);
47+
final Module module = ModuleUtilCore.findModuleForPsiElement(psiClass);
48+
final VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile();
49+
ModuleCompileScope scope = new ModuleCompileScope(project, new Module[]{module}, false);
50+
// new FileSetCompileScope(Collections.singletonList(virtualFile), new Module[]{module})
51+
52+
CompilerManager.getInstance(project).make(scope, null);
53+
54+
setClassLoader(module);
55+
}
56+
57+
public static void setClassLoader(Module module) {
58+
final List<URL> urls = new ArrayList<>();
59+
final List<String> list = OrderEnumerator.orderEntries(module).recursively().runtimeOnly().getPathsList().getPathList();
60+
for (String path : list) {
61+
try {
62+
urls.add(new File(FileUtil.toSystemIndependentName(path)).toURI().toURL());
63+
}
64+
catch (MalformedURLException e) {
65+
Messages.showErrorDialog(e.getMessage(), "MalformedURLException");
66+
}
67+
}
68+
classLoader = UrlClassLoader.build().urls(urls).parent(ClassLoader.getSystemClassLoader()).get();
69+
}
70+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.github.linyimin.plugin.description;
2+
3+
import com.intellij.openapi.module.Module;
4+
import com.intellij.psi.xml.XmlFile;
5+
import com.intellij.util.xml.DomFileDescription;
6+
import io.github.linyimin.plugin.dom.model.MybatisConfiguration;
7+
import io.github.linyimin.plugin.utils.MapperDomUtils;
8+
import org.jetbrains.annotations.NotNull;
9+
import org.jetbrains.annotations.Nullable;
10+
11+
/**
12+
* @author yiminlin
13+
* @date 2022/02/05 2:45 上午
14+
**/
15+
public class MapperConfigurationDescription extends DomFileDescription<MybatisConfiguration> {
16+
17+
public MapperConfigurationDescription() {
18+
super(MybatisConfiguration.class, "configuration");
19+
}
20+
21+
@Override
22+
public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) {
23+
return MapperDomUtils.isMybatisConfigurationFile(file);
24+
}
25+
}

src/main/java/io/github/linyimin/plugin/dom/Constant.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package io.github.linyimin.plugin.dom;
22

3+
import com.alibaba.fastjson.JSON;
34
import com.google.common.collect.Lists;
5+
import com.intellij.util.containers.ContainerUtil;
46

7+
import java.math.BigDecimal;
8+
import java.text.DateFormat;
9+
import java.text.SimpleDateFormat;
10+
import java.time.*;
11+
import java.util.Date;
512
import java.util.List;
13+
import java.util.Map;
614

715
/**
816
* @author yiminlin
@@ -14,4 +22,41 @@ public class Constant {
1422
public static final List<String> MYBATIS_OPS = Lists.newArrayList(
1523
"insert", "update", "delete", "select"
1624
);
25+
26+
public static final String PARAM_ANNOTATION = "org.apache.ibatis.annotations.Param";
27+
28+
public static final String APPLICATION_NAME = "mybatis-sql-viewer";
29+
30+
public static final String DATABASE_URL_TEMPLATE = "jdbc:mysql://%s:%s/%s";
31+
32+
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
33+
private static final DateFormat DF = new SimpleDateFormat(PATTERN);
34+
public static Map<String, Object> normalTypes = new ContainerUtil.ImmutableMapBuilder<String, Object>()
35+
.put("byte", 0)
36+
.put("java.lang.Byte", 0)
37+
.put("short", 0)
38+
.put("java.lang.Short", 0)
39+
.put("int", 0)
40+
.put("java.lang.Integer", 0)
41+
.put("long", 0)
42+
.put("java.lang.Long", 0)
43+
.put("float", 0.0)
44+
.put("java.lang.Float", 0.0)
45+
.put("double", 0.0)
46+
.put("java.lang.Double", 0.0)
47+
.put("boolean", true)
48+
.put("java.lang.Boolean", Boolean.TRUE)
49+
.put("java.math.BigDecimal", new BigDecimal(0))
50+
.put("char", "a")
51+
.put("java.lang.Character", "a")
52+
.put("java.lang.String", "")
53+
.put("java.util.Date", DF.format(new Date()))
54+
.put("java.sql.Date", DF.format(new Date()))
55+
.put("java.sql.Timestamp", System.currentTimeMillis())
56+
.put("java.time.LocalDate", LocalDate.now(ZoneId.of(JSON.defaultTimeZone.getID())).toString())
57+
.put("java.time.LocalTime", LocalTime.now(ZoneId.of(JSON.defaultTimeZone.getID())).toString())
58+
.put("java.time.LocalDateTime", LocalDateTime.now(ZoneId.of(JSON.defaultTimeZone.getID())).toString())
59+
.put("java.time.YearMonth", YearMonth.now(ZoneId.of(JSON.defaultTimeZone.getID())).toString())
60+
.build();
61+
1762
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.github.linyimin.plugin.dom.model;
2+
3+
import com.intellij.util.xml.DomElement;
4+
import com.intellij.util.xml.SubTagsList;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
import java.util.List;
8+
9+
/**
10+
* @author yiminlin
11+
* @date 2022/02/05 2:44 上午
12+
**/
13+
public interface MybatisConfiguration extends DomElement {
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.linyimin.plugin.message;
2+
3+
import com.intellij.openapi.project.Project;
4+
import com.intellij.util.messages.Topic;
5+
6+
/**
7+
* @author yiminlin
8+
* @date 2022/02/02 2:47 上午
9+
**/
10+
public interface ConfigChangeNotifier {
11+
12+
Topic<ConfigChangeNotifier> PARAM_CHANGE_TOPIC = Topic.create("param change", ConfigChangeNotifier.class);
13+
14+
/**
15+
* @param project {@link Project}
16+
*/
17+
default void configChanged(Project project) {
18+
19+
}
20+
}

src/main/java/io/github/linyimin/plugin/provider/MapperXmlProcessor.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import java.util.Collections;
1717
import java.util.List;
1818
import java.util.Objects;
19-
import java.util.stream.Collectors;
2019

2120
/**
2221
* @author yiminlin

src/main/java/io/github/linyimin/plugin/provider/generate/FunctionTooltip.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.github.linyimin.plugin.provider.generate;
22

3-
import com.intellij.openapi.wm.ToolWindowManager;
43
import com.intellij.psi.PsiElement;
54
import com.intellij.psi.PsiIdentifier;
65
import com.intellij.psi.PsiMethod;

src/main/java/io/github/linyimin/plugin/provider/generate/MapperXmlGenerateSqlLineMakerProvider.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.intellij.openapi.editor.markup.GutterIconRenderer;
66
import com.intellij.psi.PsiElement;
77
import com.intellij.psi.xml.XmlTag;
8+
import com.intellij.psi.xml.XmlToken;
9+
import com.intellij.psi.xml.XmlTokenType;
810
import io.github.linyimin.plugin.dom.Constant;
911
import io.github.linyimin.plugin.utils.IconUtils;
1012
import io.github.linyimin.plugin.utils.MapperDomUtils;
@@ -18,22 +20,29 @@ public class MapperXmlGenerateSqlLineMakerProvider implements LineMarkerProvider
1820
@Override
1921
public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
2022

23+
// 避免LineMarker is supposed to be registered for leaf elements only, but got: XmlTag:select Warning
24+
if (!(element instanceof XmlToken) || ((XmlToken)element).getTokenType() != XmlTokenType.XML_START_TAG_START) {
25+
return null;
26+
}
27+
28+
PsiElement tag = element.getParent();
29+
2130
// 只处理Mapper接口中的内容
22-
if (!MapperDomUtils.isElementWithinMapperXml(element)) {
31+
if (!MapperDomUtils.isElementWithinMapperXml(tag)) {
2332
return null;
2433
}
2534

26-
XmlTag xmlTag = (XmlTag) element;
35+
XmlTag xmlTag = (XmlTag) tag;
2736

2837
if (!Constant.MYBATIS_OPS.contains(xmlTag.getName())) {
2938
return null;
3039
}
3140

32-
FunctionTooltip tooltip = new FunctionTooltip(element);
41+
FunctionTooltip tooltip = new FunctionTooltip(tag);
3342

3443
return new LineMarkerInfo<>(
35-
xmlTag.getNavigationElement(),
36-
xmlTag.getNavigationElement().getTextRange(),
44+
element,
45+
element.getTextRange(),
3746
IconUtils.GENERATE_ICON,
3847
tooltip,
3948
new SqlGenerateNavigationHandler(),

0 commit comments

Comments
 (0)