3 Star 13 Fork 5

10km/sql2java

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 52.27 KB
一键复制 编辑 原始数据 按行查看 历史

sql2java

sql2java是一个轻量级数据库(SQL)访问代码(java)生成器,是在国外一款同名开源项目(https://sourceforge.net/projects/sql2java)的基础上重写的ORM工具,以maven 插件方式运行,目前在mysql下测试通过已经应用于实际项目开发中

  • 生成的表记录的java bean类支持thrift/swift,swagger 注释,生成的java bean对象可以直接用于thrift/swfit服务的数据类型
  • 支持表记录内存缓存(cache)机制
  • 支持侦听器(listener)机制用于通知表记录增册改事件
  • 支持事务(transaction)操作
  • 支持自增长键(AUTO_INCREMENT)
  • 支持自定义扩展模板(velocity),用户可以使用自定义的模板生成扩展代码
  • 支持乐观锁(optimisticlock)

生成的java代码结构

bean

生成的数据记录类示例

bean

编译项目

编译要求 JDK 1.7,Maven 3.5 以上版本

# 下载源码
git clone https://gitee.com/l0km/sql2java.git
cd sql2java 
# 编译全部
mvn install 

sql2java的maven插件已经发布到maven中央仓库,如果只是要运行maven插件无需编译本项目

快速使用说明

创建配置文件

如下创建一个最简的参数配置文件(mysql2java.properties),用于告诉sql2java如何生成java代码, "#"起始的行为注释

# 指定 JDBC driver,告诉sql2java如何连接数据
jdbc.driver=com.mysql.jdbc.Driver
# 对于 mysql 数据库,如果 useInformationSchema=false 或没指定,则无法获取表中的注释信息
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useInformationSchema=true
jdbc.username=root
jdbc.password=
jdbc.schema=test

# 定义生成代码的包名
codewriter.package=sql2java.test

生成代码

执行如下maven插件,即开始从数据库中读取表结构信息并生成对应的java代码到当前文件夹下(src/main)

$ mvn com.gitee.l0km:sql2java-maven-plugin:generate \
	-Dsql2java.classpath=lib/mysql-connector-java-5.1.43-bin.jar \
	-Dsql2java.propfile=mysql2java.properties

[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building sql2java test 0.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- sql2java-maven-plugin:1.0.6-SNAPSHOT:generate (default-cli) @ sql2java-test ---
        database properties initialization
[INFO] classpath: [file:/D:/j/sql2java.test/lib/mysql-connector-java-5.1.43-bin.jar]
Connecting to root on jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useInformationSchema=true ...
    Connected.
    Database server :MySQL.
Loading table list according to pattern t_% ...
    table t_book found
    table t_user found
samePrefix = [t_]
Loading columns ...
        t_book.id INT  default value: null
        t_book.name VARCHAR  default value: null
        t_book.borrower INT  default value: null
    t_book found 3 columns
        t_user.id INT AUTOINCREMENT default value: null
        t_user.name VARCHAR  default value: null
        t_user.birthdate DATE  default value: null
        t_user.phone VARCHAR  default value: null
        t_user.address VARCHAR  default value: null
    t_user found 5 columns
Database::loadPrimaryKeys
Found primary key (seq,name) (1,id) for table 't_book'
Found primary key (seq,name) (1,id) for table 't_user'
Loading imported keys ...
    t_book.id -> t_user.id found seq:1 foreign key name:fk_id
    UPDATE_RULE:NO_ACTION    DELETE_RULE:RESTRICT
Loading indexes ...
  Found interesting index phone_UNIQUE on phone for table t_user
Loading procedures ...
Generating template /templates/velocity/java5g/perschema/constant.java.vm
 .... writing to src/main\java\sql2java\test\Constant.java
    java\sql2java\test\Constant.java done.
Generating template /templates/velocity/java5g/perschema/database.properties.vm
 .... writing to src/main\resources/conf\database.properties
    resources/conf\database.properties done.
Generating template /templates/velocity/java5g/perschema/gu.sql2java.irowmetadata.vm
 .... writing to src/main\resources/META-INF/services\gu.sql2java.IRowMetaData
    resources/META-INF/services\gu.sql2java.IRowMetaData done.
Generating template /templates/velocity/java5g/pertable/bean.java.vm
 .... writing to src/main\java\sql2java\test\BookBean.java
    java\sql2java\test\BookBean.java done.
Generating template /templates/velocity/java5g/pertable/manager.interface.java.vm
 .... writing to src/main\java\sql2java\test\IBookManager.java
    java\sql2java\test\IBookManager.java done.
Generating template /templates/velocity/java5g/pertable/metadata.java.vm
 .... writing to src/main\java\sql2java\test\BookMetaData.java
    java\sql2java\test\BookMetaData.java done.
Generating template /templates/velocity/java5g/pertable/bean.java.vm
 .... writing to src/main\java\sql2java\test\UserBean.java
    java\sql2java\test\UserBean.java done.
Generating template /templates/velocity/java5g/pertable/manager.interface.java.vm
 .... writing to src/main\java\sql2java\test\IUserManager.java
    java\sql2java\test\IUserManager.java done.
Generating template /templates/velocity/java5g/pertable/metadata.java.vm
 .... writing to src/main\java\sql2java\test\UserMetaData.java
    java\sql2java\test\UserMetaData.java done.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.248 s
[INFO] Finished at: 2019-12-16T13:51:20+08:00
[INFO] Final Memory: 13M/308M
[INFO] ------------------------------------------------------------------------

com.gitee.l0km:sql2java-maven-plugin插件已经发布到maven中央仓库,无需编译本项目就可直接运行,上面的例子中没有指定插件的版本,则默认使用最新版本的插件

参数说明:

name description
sql2java.classpath 指定连接数据库的JDBC driver jar包
sql2java.propfile 指定sql2java生成代码必须的配置文件

完整示例

参见sql2java演示项目: sql2java-example: sql2java调用示例 (gitee.com)

用户可以在此演示项目的基础上修改完成自己的ORM代码项目结构

实际应用示例

参见开源项目 facelog: https://gitee.com/l0km/facelog/tree/master/db2

获取所有参数说明

为了控制java代码的生成方式,sql2java有几十个控制参数,默认情况下大部分可以不用修改,如果需要需要修改,就需要获取这些参数名字及说明,如下执行 maven 插件,显示所有配置说明以及插件本身的参数说明:

mvn com.gitee.l0km:sql2java-maven-plugin:help

如下执行 maven 插件,则在当前文件夹下生成一份名为my.properties的默认参数配置文件,你可以在此文件的基础上修改自己的代码生成配置:

$ mvn com.gitee.l0km:sql2java-maven-plugin:help -Dsql2java.output=my.properties
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building sql2java test 1.0.2
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- sql2java-maven-plugin:1.0.2:help (default-cli) @ sql2java-test ---
[INFO] OUTPUT PROPRETIES TO J:\sql2java.test\my.properties
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.495 s
[INFO] Finished at: 2019-11-20T15:25:27+08:00
[INFO] Final Memory: 10M/308M
[INFO] ------------------------------------------------------------------------

参数说明

SQL2JAVA的参数配置及说明如下

参数以参数名=参数值形式定义,所有#开始的行皆为注释行

#______________________________________________
#
# (1/8) 数据库访问配置(必填)
#______________________________________________
# JDBC驱动类名
#jdbc.driver=org.hsqldb.jdbcDriver
# 数据库访问的URL
#jdbc.url=jdbc:hsqldb:hsql://localhost
# 访问数据库的用户名
#jdbc.username=sa
# 访问数据库的密码
#jdbc.password=
# 访问的数据库名
#jdbc.schema=null
#______________________________________________
#
# (2/8) 配置自增长键的检索方式(可选)
#______________________________________________
# 此部分配置用于在插入记录时获取自增长键的值
# 对于JDBC 3.0以上支持PreparedStatement.getGeneratedKeys方法
# (DatabaseMetaData.supportsGetGeneratedKeys()返回true)的JDBC 驱动不需要配置此部分
#
# generatedkey.retrieve 可选值:
#
# auto - [默认值]getGeneratedKeys方法自动获取,当使用JDBC 3.0 driver时适用.
#
# before - 在插入(insert)记录之前获取自增长键值
#
# after - 在插入(insert)记录之后获取自增长键值
#
# generatedkey.statement用于定义获取自增长键值的SQL语句
# If you set it to before or after you also need to configure the
# autogeneratedkey.statement properties.
# <TABLE> 占位符用于取代当前表名
# <KEY> 占位符用于取代当前自增长键字段名
#
#generatedkey.retrieve=auto
#generatedkey.statement=

#______________________________________________
#
# (3/8) 生成代码配置(可选)
#______________________________________________

# 生成java代码的包名
codewriter.package=gu.sql2java.demo

# 生成java代码的文件夹
codewriter.destdir=src/main
# 生成扩展java代码的文件夹
#codewriter.destdir.extension=
# 生成扩展java代码的包名
#codewriter.package.extension=

# 定义被bean.converter.utils.java.vm 模板忽略的字段名
#general.beanconverter.tonative.ignore=create_time,update_time

# 生成的java bean是否支持facebook/swift 注释(annotation)
#swift.annotation.bean = true 
# 生成的java bean是否支持swagger 注释(annotation)
#swagger.annotation.bean = true 

# 对于有primitive 类型(Integer,Long,Double...)的字段是否生成primitive类型的setter方法 
codewriter.bean.primitiveSetter = true
# generate Long setter for Date type
# 对于 java.util.Date 类型的字段是否生成 Long类型的setter方法
codewriter.bean.dateLongSetter = true

# Date 类型的JSON 序列化类型 :
# Long 系统时间(毫秒)
# String ISO8601 时间日期格式的字符串
# 当指定了 swift或jackon注解时有效
codewriter.bean.dateSerializeType = Long

# 当 dateSerializeType 为 String 的日期格式,默认为IS8601 格式
codewriter.bean.dateStringFormat=yyyy-MM-dd'T'HH:mm:ss.SSSZ

# modified,initialized 字段的类型(不要修改)
bitstate.type = int

# 字节数对应的java类型:
#  byte[]
#  java.nio.ByteBuffer
# default byte[] if not specialized
#binary.type = byte[]

# add @JsonRawValue @JsonDeserialize annotation for JSON field 
#json.jackson.rawvalue = false
#set properties file name for database 
database.properties.env=config_folder
database.properties.isdebug=false
database.properties.dir=resources/conf
database.properties=database.properties
#flag for compatible with axis2
#bean.compatible_axis2=true
# Property file to use when initializing Velocity
#codewriter.velocityprops=somefile

# 默认加载模板的路径(不要修改)
velocity.templates.loadingpath=/templates/velocity/includes

# 为每张表(pertable)和每个方案(perschema)加载子模板的加载起始路径(不要修改)
velocity.templates=/templates/velocity/

############ 扩展模板 ###############
# 用户可以通过下面的扩展模板参数,指定自己定义的模板(.vm)文件的位置
# sql2java generator会根据指定的参数执行扩展模板生成代码 
# 扩展模板的加载路径
#velocity.templates.loadingpath.extension=
# 为每张表(pertable)和每个方案(perschema)加载扩展模板的加载起始路径	
#velocity.templates.extension =

# sets a prefix to prepend to all generated classes
# useful if you are worried about namespace collision with reserved words
# or java.lang classes
codewriter.classprefix=

# 是否为字段生成默认值
codewriter.generate.defaultvalue=true

#______________________________________________
#
# (4/8) 表和模板过滤配置(可选)
#______________________________________________
#
# 通过表类型过滤
# 用于指定需要生成代码的表类型(用逗号分隔的表类型列表)
# 表类型定义为:TABLE, VIEW, SYSTEM TABLE, SYNONYM
jdbc.tabletypes=TABLE, VIEW

# 通过表名过滤
# 使用通配%来过滤需要生成代码的表名
# 你可以指定一个逗号分割的通配符过滤列表
# 比如 %_name,ul_% 只对后缀为_name,或前缀为ul_的表名生成代码
# 默认对schema中所有的表生成代码
jdbc.tablenamepattern=%

# 表名白名单/名单过滤(此特性暂未启用)
# 白名单
# 空格分隔的表名列表,只在此名单中的表才会被生成代码
# 黑名单
# 空格分隔的表名列表,在此名单中的表不会被生成代码
# 白名单和黑名单只能定义一个,如果同时指定了白名单和黑名单则忽略黑名单  
# 白名单过滤
tables.include=
# 黑名单过滤
tables.exclude=

# 模板文件夹名白名单/名单过滤
# 白名单
# 空格分隔的表名列表,只在此名单中的模板文件夹中的模板才会被生成代码
# 黑名单
# 空格分隔的表名列表,在此名单中的模板文件夹中的模板不会被生成代码
# 白名单和黑名单只能定义一个,如果同时指定了白名单和黑名单则忽略黑名单  
template.folder.exclude=
template.folder.include=java5g   
# java5g : general bean & manager templates for java5

# (6/8) WHAT SHOULD BE DISPLAYED/NOT DISPLAYED ON THE FRONTEND ?
#        empty means all fields
#______________________________________________
# 逗号分割的字段名列表定义只能本地可见的字段
# A comma separated list of field names in a specified table that can only be accessed locally
# Equivalent to defining in the annotation of a field: ' SCOPE@LOCAL@EPOSC '
# Example:
#  table.user_info.scope.local=private_time,password
# 逗号分割的字段名列表定义THRIFT可见的字段
# A comma separated list of field names in a specified table that can be transmitted by RPC 
# in addition to being accessible locally
# Equivalent to defining in the annotation of a field: ' SCOPE@THRIFT@EPOSC '
# Example:
#  table.user_info.scope.thrift=password
# 逗号分割的字段名列表定义JSON可见的字段
# A comma separated list of field names in a specified table that can be serialized by JSON 
# in addition to being accessible locally
# Equivalent to defining in the annotation of a field: ' SCOPE@JSON@EPOSC '
# Example:
#  table.user_info.scope.json=private_time,password

​ #______________________________________________ # # (7/8) JDBC 类型映射(可选) #______________________________________________ # # jdbc DATE类型映射的java类型,可选值: # java.sql.Date # java.util.Date jdbc2java.date=java.util.Date

# jdbc TIME类型映射的java类型,可选值:
#  java.sql.Time
#  java.util.Date
jdbc2java.time=java.util.Date

# jdbc TIMESTAMP类型映射的java类型,可选值:
#  java.sql.Timestamp
#  java.util.Date
jdbc2java.timestamp=java.util.Date

#______________________________________________
#
# (8/8) 乐观锁配置(可选)
#______________________________________________
# optimisticlock.type 有两个可选项值:
# none - 乐观锁机制未启用(default).
# timestamp - 乐观锁字段包含 System.currentTimeMillis() 值.
#
# optimisticlock.column 定义乐观锁的字段名,如果字段名不存在则乐观锁机制不会启用
# 乐观锁的字段类型可以是java.lang.Long or java.lang.String.
optimisticlock.type=timestamp
optimisticlock.column=version_time

数据库字段编解码器

从 3.21.0 开始,sql2java增加了ColumnCodec接口用于应用层自定义对数据字段的序列化和反序列化,序列化方法(ColumnCodec.serialize)用于将自定义类型数据转换为数据库字段存储类型,反序列化方法(ColumnCodec.deserialize)则将字段存储类型转换为自定义数据类型。对于JSON类型的支持使用JsonColumnCodec实现,应用层可以参照JsonColumnCodec基于 BaseColumnCodec 实现自定义的数据库字段编解码器。

自定义类型字段支持

从 3.21.0 开始,增加数据库字段注释标记 ANN@@NNATYPE@@EPYT,应用层定义数据库字段的类型和编解码器,sql2java在生成代码时会自动根据此标记在生成指定类型的Java成员以及@ColumnCodecConfig注解。

TYPE@@EPYT

定义字段类型,如ATYPE@net.facelib.eam.interpreter.Rectangle@EPYT,将字段类型定义为net.facelib.eam.interpreter.Rectangle

ANN@@NNA

定义字段的注解,可定义多个,如ANN@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)@NNA,将在Java成员上生成注解@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)

示例

下面的表中rect字段定义了TYPE@@EPYTANN@@NNA

CREATE TABLE IF NOT EXISTS dc_device_channel (
    `device_id`     int         NOT NULL COMMENT 'X@NAME:设备ID@X',
    `sid`           int         NOT NULL DEFAULT 0 COMMENT 'X@NAME:物理屏幕ID@x',
    `area`          varchar(32) NOT NULL COMMENT 'X@NAME:显示区域ID@x',
    `rect`          varchar(256) DEFAULT NULL COMMENT 'ANN@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)@NNATYPE@net.facelib.eam.interpreter.Rectangle@EPYTX@NAME:显示区域坐标@x,对应EamPlayer的defineChannel语法',
    `channel`       varchar(32) NOT NULL COMMENT 'X@NAME:频道ID@x,显示区域对应的频道',
    `run_tasks`     text DEFAULT NULL COMMENT 'X@NAME:播放任务@X描述,设备实际播放的任务描述,由设备端写入,对应EamPlayer的definePlanTask和defineTrigger语法',
    PRIMARY KEY(`device_id`,`sid`,`area`),
    FOREIGN KEY (device_id)  REFERENCES dc_device(id) ON DELETE CASCADE,
    INDEX (channel)
)COMMENT 'X@NAME:设备显示区域频道记录@X' DEFAULT CHARSET=utf8;

生成的java类中对应rect的示例

    /** comments:X@NAME:显示区域坐标@x,对应EamPlayer的defineChannel语法 */
    @ApiModelProperty(value = "X@NAME:显示区域坐标@x,对应EamPlayer的defineChannel语法"  ,dataType="Rectangle")
    @CodegenLength(max=256)@CodegenInvalidValue
    @ExcelColumn(sort=4)
    @gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)
    private net.facelib.eam.interpreter.Rectangle rect;

getter/setter方法的对应类型为net.facelib.eam.interpreter.Rectangle

getter方法

    @ThriftField(value=7)
    @JsonProperty("rect")
    public net.facelib.eam.interpreter.Rectangle getRect(){
        return rect;
    }

setter方法

    @ThriftField(name="rect")
    @JsonProperty("rect")
    public void setRect(net.facelib.eam.interpreter.Rectangle newVal)
    {
        modified |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
        initialized |= DC_DEVICE_CHANNEL_ID_RECT_MASK;

        if (Objects.equals(newVal, rect)) {
            return;
        }
        rect = newVal;
    }

read/write方法对应的类型为rect字段的数据存储类型

read方法

    public String readRect(){
        return metaData.columnCodecs[DC_DEVICE_CHANNEL_ID_RECT].serialize(rect,String.class);
    }

write方法

    public void writeRect(String newVal){
        modified |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
        initialized |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
        rect = metaData.columnCodecs[DC_DEVICE_CHANNEL_ID_RECT].deserialize(newVal,metaData.fieldOf(DC_DEVICE_CHANNEL_ID_RECT).getGenericType());
    }

SCOPE@@EPOSC

字段注释标记 SCOPE@@EPOSC 用于定义字段可见度,具体格式为

SCOPE@(LOCAL|JSON|THRIFT)@EPOSC

可定义三种可见度

  • LOCAL 本地可见
  • JSON JSON序列化/反序列化可见
  • THRIFT Thrift RPC 序列化/反序列化可见

如下示例,下面的表定义中,private_time字段定义了SCOPE@@EPOSC注释标记,指定了该字段仅本地可见。也就是说只有服务端本身可以读写该字段。

CREATE TABLE IF NOT EXISTS dc_device (
  `id`             int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'X@NAME:设备id@X',
  `name`           varchar(32) DEFAULT NULL COMMENT 'X@NAME:设备名称@X,用户指定',
  `physical_address` varchar(32) NOT NULL UNIQUE COMMENT '设备X@NAME:物理地址@X,MAC地址,IMEI或其他设备识别码',
  `private_time`     bigint DEFAULT 0 COMMENT 'SCOPE@LOCAL@EPOSC设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段',
  `os_arch`        varchar(64) DEFAULT NULL COMMENT 'X@NAME:操作系统平台@X,操作系统名称及版本及硬件架构名称,例如:Windows-x86_64,Linux-x86_64,Android-arm...'
) COMMENT 'X@NAME:前端设备记录@X,前端设备基本信息' DEFAULT CHARSET=utf8;

sql2java-generator生成的DeviceBean对象中dc_device.private_time字段的对应成员privateTime定义代码如下:

    /** comments:设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段 */
    @ApiModelProperty(value = "设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段"  ,dataType="Long")
    @CodegenDefaultvalue("0")@CodegenInvalidValue("-1")
    @ExcelColumn(sort=9)
    @com.alibaba.fastjson.annotation.JSONField(serialize = false,deserialize = false)
    @com.fasterxml.jackson.annotation.JsonIgnore
    private Long privateTime;
    /**
     * Getter method for {@link #privateTime}.<br>
     * Meta Data Information (in progress):
     * <ul>
     * <li>full name: dc_device.private_time</li>
     * <li>comments: 设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段</li>
     * <li>default value: '0'</li>
     * <li>column size: 19</li>
     * <li>JDBC type returned by the driver: Types.BIGINT</li>
     * </ul>
     *
     * @return the value of privateTime
     */
    @JsonIgnore
    public Long getPrivateTime(){
        return privateTime;
    }

可以看到,privateTime成员定义的Jackson注解@JsonIgnore和fastjson注解@JSONField指定该字段在JSON序列化和反序列化时忽略应该字段。同时privateTime的getter方法上也没有thrift字段注解@ThriftField,代表应该字段也没有被定义为Thrift成员字段。

swift2thrift-maven-plugin插件生成的IDL中就不会有privateTime字段:

struct DeviceBean {
  1: required bool _new;
  2: required i32 modified;
  3: required i32 initialized;
  4: optional i32 id;
  5: optional string name;
  6: optional string physicalAddress;
  7: optional string osArch;
}

Boolean字段支持

3.19.0之前不论是TINYINT,SMALLINT,INT类型对应的Java类型都是Integer,3.19.0版本之后,细分了整数类型字段生成的Java数据类型,如下表

SQL 类型 Java字段类型 说明
TINYINT/BOOL/BOOLEAN Byte /Boolean 如果数据库字段注释(COMMENT)中定义了[NUM,Boolean],则生成的Java成员类型为Boolean,否则为Byte
SMALLINT Short
INT Integer

示例:

CREATE TABLE IF NOT EXISTS dc_device (
	`id`       int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '设备id',
    `online`   boolean DEFAULT false COMMENT '[NUM,Boolean],是否在线标记'	
);

如上定义boolean/boolTINYINT类型字段在生成的Java Bean中online字段将被定义为Boolean类型。

**注意:**在注释中[NUM,Boolean]标记必须在字符串起始位置。

JSON字段支持

从3.8版本之后,sql2java支持对保存JSON数据的String字段自动序列化和反序列。

开启json.jackson.rawvalue

要开启此特性,需要做如下两步简单的设置

开启此特性生成的代码需要fastjson,jackson库的支持

  • 修改 sql2java.properties

    json.jackson.rawvalue置为true,即增加如下设置

# 
# add @JsonRawValue @JsonDeserialize annotation for JSON field 
#json.jackson.rawvalue = true
  • 修改建表语句

    在需要定义为保存JSON数据的字段的注释中增加[JSON_STR,...]前缀,通过此前缀指定该字段要保存JSON数据(只对Java类型为String的字段有效)

    示例如下:

    CREATE TABLE IF NOT EXISTS dc_device_group (
      `id`          int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '设备组id',
      `name`        varchar(32) NOT NULL COMMENT '设备组名',
      `address`     varchar(128) DEFAULT NULL COMMENT '设备组详细地址:区/街道门牌',
      `props`       text DEFAULT NULL COMMENT '[JSON_STR,obj]JSON格式的扩展字段(最大64KB),用于定义扩展信息,online_time:开机时间,offline_time:关机时间,close_time:闭站时间,operator:操作人',
      `create_time` timestamp DEFAULT CURRENT_TIMESTAMP,
      `update_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) COMMENT '设备组信息' DEFAULT CHARSET=utf8;

    上面的示例中props字段的注释以[JSON_STR,obj]为前缀,即定义该字段为JSON字段,JSON字段的类型为Object

    只要做了上面两项目修改,重新执行Sql2java生成代码就可以了。

[JSON_STR]

生成代码时会根据[JSON_STR,...]来确定JSON字段的类型

[JSON_STR]格式 JSON字段类型
[JSON_STR,array] com.alibaba.fastjson.JSONArray
[JSON_STR,object] com.alibaba.fastjson.JSONObject
[JSON_STR,obj] com.alibaba.fastjson.JSONObject
[JSON_STR] com.alibaba.fastjson.JSON
[JSON_STR,com.mycompany.product.User] com.mycompany.product.User

生成代码示例

props 字段定义代码:

    /** comments:[JSON_STR]JSON格式的扩展字段(最大64KB),用于定义扩展信息,online_time:开机时间,offline_time:关机时间,close_time:闭站时间,operator:操作人 */
    @ApiModelProperty(value = "[JSON_STR]JSON格式的扩展字段(最大64KB),用于定义扩展信息,online_time:开机时间,offline_time:关机时间,close_time:闭站时间,operator:操作人"  ,dataType="String")
    @CodegenLength(max=65535)@CodegenInvalidValue
    @com.fasterxml.jackson.annotation.JsonRawValue
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.json.RawJsonDeserializer.class)
    private com.alibaba.fastjson.JSONObject props;

getter/setter方法代码,以String类型对字段进行读写:

    @ThriftField(value=16)
    @JsonProperty("props")
    public String getProps(){
        return null == props ? null : props.toJSONString();
    }
    @ThriftField(name="props")
    @JsonProperty("props")
    public void setProps(String newVal)
    {
        modified |= DC_DEVICE_GROUP_ID_PROPS_MASK;
        initialized |= DC_DEVICE_GROUP_ID_PROPS_MASK;

        props =  com.alibaba.fastjson.JSONObject.parseObject(newVal,com.alibaba.fastjson.JSONObject.class);
    }

额外生成的read/write方法代码,提供对JSON对象直接读写:

    /** 
     * read method for {@link #props}<br>
     * @return the JSON value of props
     */
    public com.alibaba.fastjson.JSONObject readProps(){
        return props;
    }
    /** 
     * write method for {@link #props} with JSON object.<br>
     */
    public void writeProps(com.alibaba.fastjson.JSONObject newVal){
        modified |= DC_DEVICE_GROUP_ID_PROPS_MASK;
        initialized |= DC_DEVICE_GROUP_ID_PROPS_MASK;
        if (Objects.equals(newVal, props)) {
            return;
        }
        props = newVal;
    }

序列化效果

{
    "modified": 0,
    "initialized": 65535,
    "new": false,
    "id": 5,
    "name": "连平客运总站",
    "address": null,
    "props": {
    	"offline_time": "22:00",
    	"online_time": "8:00",
    	"operator": "unknow"
    },
    "createTime": "2022-07-06T12:41:56.000+0800",
    "updateTime": "2022-07-06T12:41:56.000+0800"
}

Excel 注解支持

自从3.10开始,sql2java提供基于apache/poi实现的数据记录导出为Excel格式数据流或文件的功能.参见sql2java-excel/README.md.

sql2java-excel支持注解方式配置每张表每个字段的Excel导出配置。sql2java-generator在生成Java Bean代码时支持从SQL 表和字段注释COMMENT中根据读取预定义的标记,在Java Bean类代码中生成@ExcelSheet,@ExcelColumn注解。

开启excel.annotation.bean

要开启Excel注解生成特性,需要做如下两步设置

开启此特性生成的代码需要sql2java-excel库的支持

  • 修改 sql2java.properties

    excel.annotation.bean置为true,即增加如下设置

# generate @ExcelSheet,@ExcelColumn annotation if true
excel.annotation.bean = true  
  • 修改建表语句

在数据库建表语句的表和字段注释(COMMENT)上根据需要定义特殊的EXCEL 标记,示例如下:

下面的CREATE TABLE SQL语句示例中用到了很多X@....@X标记,这些标记内容就是为sql2java-generator在生成JavaBean代码时用于识别生成@ExcelSheet,@ExcelColumn注解的特殊标记(tag):

CREATE TABLE IF NOT EXISTS dc_device (
  `id`          int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'X@NAME:设备id@X',
  `group_id`    int(11) DEFAULT 1 COMMENT 'X@NAME:所属设备组id@X',
  `features`    int(11) DEFAULT 0 COMMENT 'X@NAME:设备组特性标志@X,应用层定义',
  `name`        varchar(32) DEFAULT NULL COMMENT 'X@NAME:设备名称@X,用户指定',
  `physical_address` varchar(32) NOT NULL UNIQUE COMMENT '设备X@NAME:物理地址@X,MAC地址,IMEI或其他设备识别码',
  `address_type`varchar(16) NOT NULL DEFAULT 'MAC' COMMENT '设备物理X@NAME:地址类型@X(MAC,IMEI...),默认6字节MAC地址(HEX)',
  `iot_card`    varchar(32) DEFAULT NULL UNIQUE COMMENT '设备X@NAME:物联网卡编号@X,例如联通叫iccid',
  `status`      varchar(32) NOT NULL DEFAULT 'ENABLE' COMMENT 'X@NAME:设备状态@X,X@VALUES:ENABLE:正常,DISABLE:禁用,MAINTAIN:维护,PENDING:挂起(待审核)@X',
  `private_time`  bigint DEFAULT 0 COMMENT '设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段',
  `screen_info` varchar(32) DEFAULT NULL COMMENT 'X@NAME:设备屏幕信息@X,格式示例:15H1080x960--15(英)寸横屏分辨率1080x960,21V960x1080--21(英)寸横屏分辨率960x1080',
  `fixed_mode`  varchar(8) DEFAULT 'FLOOR' COMMENT '设备X@NAME:安装方式@X,X@VALUES:HANG:悬挂,FLOOR:落地@X',
  `os_arch`     varchar(64) DEFAULT NULL COMMENT 'X@NAME:操作系统平台@X,操作系统名称及版本及硬件架构名称,例如:Windows-x86_64,Linux-x86_64,Android-arm...',
  `network`     varchar(32) DEFAULT NULL COMMENT 'X@NAME:网络连接类型@X:4G,WIFI,ETHERNET',
  `version_info`varchar(32) DEFAULT NULL COMMENT '设备端应用程序的X@NAME:版本@X号,格式由应用层定义',
  `model`       varchar(32) DEFAULT NULL COMMENT 'X@NAME:设备型号@X',
  `vendor`      varchar(32) DEFAULT NULL COMMENT 'X@NAME:设备供应商@X',
  `device_detail` varchar(512) DEFAULT NULL COMMENT '[JSON_STR,obj]X@NAME:设备产品详细信息@X,以JSON格式定义设备详细信息,JSON字段:X@NAMES:device_name:产品名称,manufacturer:制造商,made_date:生产日期@X,应用层可根据需要扩展',
  `props`       text DEFAULT NULL COMMENT '[JSON_STR,obj]JSON格式的扩展字段(最大64KB),用于定义扩展信息,X@NAMES:last_active_time:上次在线时间,disk_capacity:磁盘容量,status_comment:状态变更说明@X',
  `plan_id`     varchar(64) DEFAULT NULL COMMENT 'X@NAME:当前节目ID@X',
  `target_id`   varchar(64) DEFAULT NULL COMMENT 'X@NAME:目标节目ID@X',
  `remark`      varchar(256) DEFAULT NULL COMMENT 'X@NAME:备注@X',
  `create_time` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT 'X@NAME:记录创建时间@X',
  `update_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'X@NAME:记录修改时间@X'
) COMMENT 'X@NAME:前端设备记录@X,前端设备基本信息,X@SHEET:titleFillColor=YELLOW,hideColumns=private_time|props|device_detail@X' DEFAULT CHARSET=utf8;

有了这些标记,sql2java-generator就会为dc_device表生成如下的带有@ExcelSheet,@ExcelColumn注解的Java Bean代码:

/**
 * DeviceBean is a mapping of dc_device Table.
 * <br>Meta Data Information (in progress):
 * <ul>
 *    <li>comments: 前端设备记录,前端设备基本信息, </li>
 * </ul>
 * @author guyadong
*/
@ExcelSheet(sheetName="dc_device",title="前端设备记录",titleFillColor="YELLOW",hideColumns={"private_time","props","device_detail"})
public final class DeviceBean extends BaseRow
    implements Serializable,Constant
{
    private static final long serialVersionUID = -3495281739409382636L;

    /** comments:设备id */
    @ExcelColumn(sort=1,name="设备id")
    private Integer id;

    /** comments:所属设备组id */
    @ExcelColumn(sort=2,name="所属设备组id")
    private Integer groupId;

    /** comments:设备组特性标志,应用层定义 */
    @ExcelColumn(sort=3,name="设备组特性标志")
    private Integer features;

    /** comments:设备名称,用户指定 */
    @ExcelColumn(sort=4,name="设备名称")
    private String name;

    /** comments:设备物理地址,MAC地址,IMEI或其他设备识别码 */
    @ExcelColumn(sort=5,name="物理地址")
    private String physicalAddress;

    /** comments:设备物理地址类型(MAC,IMEI...),默认6字节MAC地址(HEX) */
    @ExcelColumn(sort=6,name="地址类型")
    private String addressType;

    /** comments:设备物联网卡编号,例如联通叫iccid */
    @ExcelColumn(sort=7,name="物联网卡编号")
    private String iotCard;

    /** comments:设备状态,ENABLE:正常,DISABLE:禁用,MAINTAIN:维护,PENDING:挂起(待审核) */
    @ExcelColumn(sort=8,name="设备状态",readConverterExp="ENABLE=正常, DISABLE=禁用, MAINTAIN=维护, PENDING=挂起(待审核)")
    private String status;

    /** comments:设备令牌创建的时间戳(毫秒),每次创建设备令牌都会修改此字段 */
    @ExcelColumn(sort=9)
    private Long privateTime;

    /** comments:设备屏幕信息,格式示例:15H1080x960--15(英)寸横屏分辨率1080x960,21V960x1080--21(英)寸横屏分辨率960x1080 */
    @ExcelColumn(sort=10,name="设备屏幕信息")
    private String screenInfo;

    /** comments:设备安装方式,HANG:悬挂,FLOOR:落地 */
    @ExcelColumn(sort=11,name="安装方式",readConverterExp="HANG=悬挂, FLOOR=落地")
    private String fixedMode;

    /** comments:操作系统平台,操作系统名称及版本及硬件架构名称,例如:Windows-x86_64,Linux-x86_64,Android-arm... */
    @ExcelColumn(sort=12,name="操作系统平台")
    private String osArch;

    /** comments:网络连接类型:4G,WIFI,ETHERNET */
    @ExcelColumn(sort=13,name="网络连接类型")
    private String network;

    /** comments:设备端应用程序的版本号,格式由应用层定义 */
    @ExcelColumn(sort=14,name="版本")
    private String versionInfo;

    /** comments:设备型号 */
    @ExcelColumn(sort=15,name="设备型号")
    private String model;

    /** comments:设备供应商 */
    @ExcelColumn(sort=16,name="设备供应商")
    private String vendor;

    /** comments:设备产品详细信息,以JSON格式定义设备详细信息,JSON字段:device_name:产品名称,manufacturer:制造商,made_date:生产日期,应用层可根据需要扩展 */
    @ExcelColumns({
        @ExcelColumn(sort=17,name="设备产品详细信息"),
        @ExcelColumn(sort=17,columnName="device_detail.device_name",name="产品名称"),
        @ExcelColumn(sort=17,columnName="device_detail.manufacturer",name="制造商"),
        @ExcelColumn(sort=17,columnName="device_detail.made_date",name="生产日期")
    })
    @com.fasterxml.jackson.annotation.JsonRawValue
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.json.RawJsonDeserializer.class)
    private com.alibaba.fastjson.JSONObject deviceDetail;

    /** comments:JSON格式的扩展字段(最大64KB),用于定义扩展信息,last_active_time:上次在线时间,disk_capacity:磁盘容量,status_comment:状态变更说明 */
    @ExcelColumns({
        @ExcelColumn(sort=18),
        @ExcelColumn(sort=18,columnName="props.last_active_time",name="上次在线时间"),
        @ExcelColumn(sort=18,columnName="props.disk_capacity",name="磁盘容量"),
        @ExcelColumn(sort=18,columnName="props.status_comment",name="状态变更说明")
    })
    @com.fasterxml.jackson.annotation.JsonRawValue
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.json.RawJsonDeserializer.class)
    private com.alibaba.fastjson.JSONObject props;

    /** comments:当前节目ID */
    @ExcelColumn(sort=19,name="当前节目ID")
    private String planId;

    /** comments:目标节目ID */
    @ExcelColumn(sort=20,name="目标节目ID")
    private String targetId;

    /** comments:备注 */
    @ExcelColumn(sort=21,name="备注")
    private String remark;

    /** comments:记录创建时间 */
    @ExcelColumn(sort=22,name="记录创建时间")
    private java.util.Date createTime;

    /** comments:记录修改时间 */
    @ExcelColumn(sort=23,name="记录修改时间")
    private java.util.Date updateTime;
    //////////////////////////////
    /////    。。其他代码。。    ////
    //////////////////////////////
}

EXCEL 标记

本节说明说明EXCEL 标记X@...@X的定义方式

NAME tag

X@NAME:xxxx@X 为表/字段名字定义标记,定义表或字段在输出EXCEL数据的标题或列名,当出现在表的注释语句(COMMENT)中时它对应生成@ExcelSheettitle,出现在字段的注释语句(COMMENT)中时它对应生成@ExcelColumnname.

NAMES tag

X@NAMES:a=b,c=d@X为多符号定义标记,定义表或字段在在输出EXCEL数据时,子成员变量的列名.当出现在表的注释语句(COMMENT)中时它对应生成表成员或子成员字段的@ExceColumn注解代码以定义表成员或子成员字段的列名.出现在字段的注释语句(COMMENT)中且该字段被标记为JSON object字段时它对应生成JSON子成员字段的@ExcelColumn注解代码以定义JSON子成员字段的列名.

在上面的示例中,device_detail字段被定义为JSON object字段,且COMMENT中定义了NAMES tag:X@NAMES:device_name:产品名称,manufacturer:制造商,made_date:生产日期@X,相当就定义了该JSON成员中的device_name,device_name,manufacturer,made_date子成员字段在输出到EXCEL时对应的列名.

如果实际该JSON 字段保存的字段不至这三个,还有location字段没有定义列名,输出该字段的列名是什么呢?没定义的情况默认就是locaiton

VALUES tag

X@VALUES:a=b,c=d@X为多值转换定义标记,用于定义在字段的值在输出到EXCEL时实际内容.对应于@ExcelColumnreadConverterExp.

如上示例中dc_device.status字段定义了VALUES tag:X@VALUES:ENABLE:正常,CLOSED:关闭,MAINTAIN:维护,PENDING:挂起(待审核)@X,即代表当月status字段值为ENABLE时,输出到Excel的值为正常,以此类推.

COLUMN tag

X@COLUMN:a=b,c=d@X@ExcelColumn注解全字段定义标记,@ExcelColumn注解定义有数十个可配置的参数字段,name,readConverterExp只是常用的字段,所以定义了专用的NAME tag,VALUES tag,对于其他参数,都可以通COLUMN tag来进行定义.

SHEET tag

X@SHEET:a=b,c=d@X@ExcelSheet注解全字段定义标记,@ExcelSheet注解定义有数十个可配置的参数字段,name只是常用的字段,所以定义了专用的NAME tag,对于其他参数,都可以通SHEET tag来进行定义.

上面的示例中dc_device表的注释(COMMENT)中使用了SHEET tag定义了:@ExcelSheettitleFillColor,hideColumns:X@SHEET:titleFillColor=YELLOW,hideColumns=private_time|props|device_detail@X

注意在这里,@ExcelSheethideColumns的类型是String数组,在SHEET tag中对于数组类型的字段定义多个元素时要用|分割.

专用标记优先于原则

即专用标记优先于COLUMN tag,SHEET tag定义

对于一个字段如果使用COLUMN tag,定义了name,同时也用NAME tag定义了列名,这种情况下优先使用NAME tag定义的值,对于SHEET tag也是一样的逻辑。

Geomerty类型字段支持

CREATE TABLE dc_spot (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '地点名称',
  `spot` point DEFAULT NULL COMMENT '经纬度点'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

从3.18.0版本开始,支持MySQL(above 5.7)的所有空间数据类型(Spatial Data Types)即几何类型(Geomerty)字段自动生成JTScom.vividsolutions.jts.geom.Geometry 类型的成员.

如下为MySQL空间数据类型名与JTS 几何对象的对应表

MySQL空间数据类型名 JTS类
GEOMETRY com.vividsolutions.jts.geom.Geometry
POINT com.vividsolutions.jts.geom.Point
LINESTRING com.vividsolutions.jts.geom.LineString
POLYGON com.vividsolutions.jts.geom.Polygon
MULTIPOINT com.vividsolutions.jts.geom.GeometryCollection
MULTILINESTRING com.vividsolutions.jts.geom.GeometryCollection
MULTIPOLYGON com.vividsolutions.jts.geom.GeometryCollection
GEOMETRYCOLLECTION com.vividsolutions.jts.geom.GeometryCollection

配置参数

为控制生成的代码中对于Geomerty类型字段的getter/setter方法的类型,增加了codewrite.bean.geometry.serial.type参数

以下codewrite.bean.geometry.serial.type参数的说明

  • STRING

【默认值】当codewrite.bean.geometry.serial.type=STRING 时,Geomerty类型字段的getter/setter方法的类型为String,即对外使用WKT字符串来表示几何对象

因为String是简单类型,这种方式可读性好,比较通用,符合常规场景下对Geometry类型的处理

生成代码示例:

	private com.vividsolutions.jts.geom.Point spot;
	/** 将spot转为WKT字符串返回 */
	public String getSpot(){
        return null == spot ? null : spot.toText();
    }
	/** 将WKT字符串转为Point保存到spot */
	public void setSpot(String newVal){
        spot =  (null == newVal || newVal.isEmpty())? null : GeometryDataCodec.DEFAULT_INSTANCE.fromWKTUnchecked(newVal,Point.class);
    }
	/** 返回sport原始对象 */
	public com.vividsolutions.jts.geom.Point readSpot(){
        return spot;
    }
	/** 修改spot原始对象 */
	public void writeSpot(com.vividsolutions.jts.geom.Point newVal){
        spot = newVal;
    }
  • JTS

codewrite.bean.geometry.serial.type=JTS 时,JTS Geomertry 类型直接用于Geomerty类型字段的getter/setter方法的类型。

生成代码示例:

    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.geometry.jackson.GeometryDeserializer.class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = gu.sql2java.geometry.jackson.GeometrySerializer.class) 
     @com.alibaba.fastjson.annotation.JSONField(serializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class,deserializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class) 
    private com.vividsolutions.jts.geom.Point spot;
	/** 返回sport原始对象 */
	public com.vividsolutions.jts.geom.Point getSpot(){
        return spot;
    }
	/** 修改spot原始对象 */
	public void setSpot(com.vividsolutions.jts.geom.Point newVal){
        spot = newVal;
    }

不论codewrite.bean.geometry.serial.type参数如何选择,Geomerty类型字段生成的Java Bean的对应成员类型都为 JTS Geomerty类型。

jackson支持

JTS Geometry对象不是标准的Java Bean不能自动被Jackson执行序列化和反序列化。所以需要为 Geometry对象实现自定义的序列化器和反序列化器。

JTS Geometry类序列化器实现 gu.sql2java.geometry.jackson.GeometryDeserializer

JTS Geometry类反序列化器实现 gu.sql2java.geometry.jackson.GeometrySerializer

如下可以在以使用@JsonDeserialize@JsonSerialize注解定义类成员字段的自定义序列化和反序列化器:

    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.geometry.jackson.GeometryDeserializer.class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = gu.sql2java.geometry.jackson.GeometrySerializer.class)
    private com.vividsolutions.jts.geom.Point spot;

直接引用自定义序列化和反序列化器示例参见:GeometryJacksonTest

fastjson支持

JTS Geometry对象不是标准的Java Bean不能自动被fastjson执行序列化和反序列化。所以需要为 Geometry对象实现自定义的序列化器和反序列化器。

fastjson 为JTS Geometry类型自定义的序列化和反序列化实现的基类为gu.sql2java.geometry.fastjson.GeometryCodec

如下为详细的JTS Geometry类与fastjson自定义序列化反序列化类对应表

JTS Geometry类 fastjson自定义序列化反序列化类
com.vividsolutions.jts.geom.Geometry gu.sql2java.geometry.fastjson.GeometryCodec
com.vividsolutions.jts.geom.Point gu.sql2java.geometry.fastjson.PointCodec
com.vividsolutions.jts.geom.LineString gu.sql2java.geometry.fastjson.LineStringCodec
com.vividsolutions.jts.geom.Polygon gu.sql2java.geometry.fastjson.PolygonCodec
com.vividsolutions.jts.geom.GeometryCollection gu.sql2java.geometry.fastjson.GeometryCollectionCodec

注解引用示例

如下可以在以使用@JSONField注解定义类成员字段的自定义序列化和反序列化器:

  	@com.alibaba.fastjson.annotation.JSONField(
        serializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class,
        deserializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class) 
    private com.vividsolutions.jts.geom.Point spot;

直接引用自定义序列化和反序列化器示例参见:gu.sql2java.GeometryFastjsonTest

GeometryInit

gu.sql2java.geometry.fastjson.GeometryInit 用于为fastjson指定JTS Geometry类型的全局序列化反序列器,即将上述的所有fastjson自定义序列化反序列化器实例设置为fastjson的全局序列化反序列化器

当需要单独对JTS Geometry进行序列化和反序列化时,可以使用此GeometryInit.init()完成全局初始化,以确保fastjson能正确处理JTS Geometry对象

示例如下:

    @Test
    public void test2Fastjson() {
        try {
            GeometryInit.init();
            String wkt = "POINT (1 -1)";
            Point point = GeometryDataCodec.DEFAULT_INSTANCE.fromWKT(wkt,Point.class);
            log("point {}",JSON.toJSONString(point));
            assertTrue(wkt.equals(point.toText()));
        } catch (ParseException e) {
            e.printStackTrace();
            assertTrue(false);
        }
    }

静态字段过滤

不论是Thrift RPC还是SpringWeb服务,服务方法的输入和输出参数都要通过网络在Server/Client之间传输。实现数据对象传输,发送端需要对数据对象进行序列化(JSON或二进制数据流),接收端需要对收到的数据反序列化还原为原始的数据对象。

从3.32.0版本开始,sql2java增加了静态字段过滤功能,是指在生成sql2java的数据库表记录对象类时,允许指定字段的可见度(ColumnVisibility)。

可见度是指字段对数据接收端是否可见,只要控制数据库表对象在序列化/反序列化时忽略不可见字段,数据接收端最终收到数据库对象中就不会包含该字段。

具体实现就是sql2java-generator会根据字段的可见度要求,对于不可见字段,在生成对应字段代码时增加Jackson,Fastjson,Thrift注解(Annotation)指定在表对象序列化/反序列化时忽略该字段。示例参见 **《SCOPE@@EPOSC》**章节

字段可见度定义

sql2java中字段可见度定义对应枚举类型gu.sql2java.ColumnVisibility

枚举变量 JSON是否可见 Thrift是否可见 说明
DEFAULT true true 默认:全可见
LOCAL false false 仅本地可见,与远端(Spring WEB,Thrift RPC)交互时不可见
THRIFT false true Thrift RPC 传输时可见,Thrft RPC 客户端与服务端交互时可见
JSON true false JSON序列化时可见,Spring WEB 客户端与服务端 交互时可见(Spring WEB是基于jackson实现序列化和反序列化的),使用fastjson对数据库对象进行序列化和反序列化时同样有效。

定义可见度

定义字段可见度的方式有两种,一种是在建表语句的字段注释中通过字段注释标记SCOPE@@EPOSC来定义,参见 **《SCOPE@@EPOSC》**章节

另一种是在sql2java参数配置文件(sql2java.properties)中定义,参见 **《参数说明》**章节(6/8)

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/l0km/sql2java.git
git@gitee.com:l0km/sql2java.git
l0km
sql2java
sql2java
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891