让mybatis-plus支持空间类型

返回
Author Avatar
钢翼
2021-11-29
编程
81

一、背景

项目采用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);