让mybatis-plus支持空间类型
钢翼
编程
一、背景
项目采用mybatis-plus,很大一部分原因是单表操作在mapper.xml不需要生成一堆繁琐的sql。
但是mybatis-plus并不支持空间类型的字段。还是需要对简单的增删改查写一堆sql。
网上常见的有mybatis拦截器,然后修改sql来实现。明显这个维护起来还是很麻烦的,而且效率也不高。
为了沿用注解,所以想到在源码上做改动。
二、步骤
1.fork源码
首先在https://github.com/baomidou/mybatis-plus fork一份源码。
2.修改源码
以下代码可在https://github.com/wmz46/mybatis-plus 上查看
/mybatis-plus-annotation/src/main/java/com/baomidou/mybatisplus/annotation/TableField.java添加自定义字段subSelect
@@ -70,6 +70,16 @@ public @interface TableField {
*/
String update() default "";
+ /**
+ * 字段 subSelect select 部分注入
+ * <p>
+ * 例1:@TableField(.. , subSelect="st_astext(%s)") 其中 %s 会填充为字段
+ * 输出 SQL 为:select st_astext(字段) as 字段 ...
+ * </p>
+ * @return
+ */
+ String subSelect() default "";
+ /**
+ * 字段 insert values 部分注入, 该注解优于 el 注解使用
+ */
+ String insert() default "";
+
/**
* 字段验证策略之 insert: 当insert操作时,该字段拼接insert语句时的策略
* <p>
/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java修改拼接查询sql
@@ -123,6 +123,11 @@ public class TableFieldInfo implements Constants {
* 字段 update set 部分注入
*/
private String update;
+
+ /**
+ * 字段 subSelect select 部分注入
+ */
+ private String subSelect;
+ /**
+ * 字段 insert values 部分注入
+ */
+ private String insert;
/**
* where 字段比较条件
*/
@@ -204,6 +209,7 @@ public class TableFieldInfo implements Constants {
this.withInsertFill = this.fieldFill == FieldFill.INSERT || this.fieldFill == FieldFill.INSERT_UPDATE;
this.withUpdateFill = this.fieldFill == FieldFill.UPDATE || this.fieldFill == FieldFill.INSERT_UPDATE;
this.update = tableField.update();
+ this.insert = tableField.insert();
+ this.subSelect = tableField.subSelect();
JdbcType jdbcType = tableField.jdbcType();
final Class<? extends TypeHandler> typeHandler = tableField.typeHandler();
final String numericScale = tableField.numericScale();
@@ -262,8 +268,13 @@ public class TableFieldInfo implements Constants {
column = String.format(columnFormat, column);
}
+
this.column = column;
- this.sqlSelect = column;
+ if (StringUtils.isNotBlank(subSelect)) {
+ this.sqlSelect = String.format(subSelect, column);
+ }else {
+ this.sqlSelect = column;
+ }
if (needAs) {
// 存在指定转换属性
String propertyFormat = dbConfig.getPropertyFormat();
@@ -435,7 +440,11 @@ public class TableFieldInfo implements Constants {
*/
public String getInsertSqlProperty(final String prefix) {
final String newPrefix = prefix == null ? EMPTY : prefix;
- return SqlScriptUtils.safeParam(newPrefix + el) + COMMA;
+ if(StringUtils.isNotBlank(insert)){
+ return String.format(insert, column);
+ }else {
+ return SqlScriptUtils.safeParam(newPrefix + el) + COMMA;
+ }
}
3.编译
gradle build -x test
以上代码执行无报错即可。注:我在一台电脑可以正常编译,另一台电脑上会报licenseTest错,由于本人对gradle不熟,不清楚怎么解决。
4.发布到github packages
修改根目录下的build.gradle
@@ -184,15 +184,11 @@ subprojects {
publishing {
repositories {
maven {
- def userName = System.getProperty("un")
- def passWord = System.getProperty("ps")
- def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
- def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
- url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
-
+ name = "GitHubPackages"
+ url = "https://maven.pkg.github.com/wmz46/mybatis-plus"
credentials {
- username userName
- password passWord
+ username = project.findProperty("gpr.user")//你的github用户名
+ password = project.findProperty("gpr.key")//你的github的package的token
}
}
}
执行以下指令发布到github
gradle publish
三、引用
在pom.xml中添加github仓库
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
.......
</dependencies>
<repositories>
<repository>
<id>github</id>
<name>GitHub OWNER Apache Maven Packages</name>
<url>https://maven.pkg.github.com/wmz46/mybatis-plus</url>
</repository>
.......
</repositories>
实体字段注解
//property必须有值,否则生成的select不会有AS 别名
//insert中的参数必须使用#{xxx}包裹,否则无法入参
//update中的参数必须使用#{et.xxx}包裹,否则无法入参
//condition中必须有两个%s,第一个为字段名,第二个为参数名
@TableField(value="lonlat",property="lonlat",subSelect = "st_astext(%s)",update = "ST_GeomFromText(#{et.lonlat})",insert = "ST_GeomFromText(#{lonlat})",condition = "%s=ST_GeomFromText(#{%s})")
private String lonlat;
修改后即可正常查询、插入和修改,注解condition不支持以lambda方式查询,只支持构造函数方式的实体查询,如下:
XXX xxx = new XXX();
xxx.setLonlat("POINT(12991959 2675174)");
QueryWrapper<XXX> qw = new QueryWrapper<>(xxx);
XXX result = xxxMapper.selectOne(qw);