IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> IDEA Groovy 生成实体类 -> 正文阅读

[开发工具]IDEA Groovy 生成实体类

先前虽然能实现生成实体,但没有序列化ID,实体太多时手动创建很麻烦,所以这次加上了序列化ID的生成

无serialVersionUID版本

改进

参考jdk的生成方式添加了签名计算,直接上新增的代码

  • 打印调用
/**
 * 输出serialVersionUID
 * @param out 输出流
 * @param fields 字段列表
 * @param className 类名
 */
def outSerialVersionUID(out, fields, className){
  out.println ""
  out.println "\tprivate static final long serialVersionUID = ${calculateSerialId(packageName, className, fields)}L;"
}
  • 计算序列化ID
/**
 * 计算序列化ID
 * @param packageName 包名
 * @param className 类名
 * @param fields 字段列表
 * @return 序列化ID
 */
long calculateSerialId(packageName, className, fields){
  if (fields.size() == 0) return 0L
  ByteArrayOutputStream bout = new ByteArrayOutputStream()
  DataOutputStream dout = new DataOutputStream(bout)
  dout.writeUTF(packageName.substring(0, packageName.length() - 1) + "." + className)
  dout.writeInt(Modifier.PUBLIC)//classMod > public, not interface/abstract/final
  dout.writeUTF("java.io.Serializable")//interfaceName list, has only one : Serializable
  //排序
  def fieldsSigs = getFieldsSignatures(fields)
  fieldsSigs.each(){
    dout.writeUTF(it.name)
    dout.writeInt(Modifier.PRIVATE)//字段都是私有
    dout.writeUTF(it.signature)
  }
  dout.writeUTF("<init>")
  dout.writeInt(Modifier.PUBLIC)//默认只有公共的空构造
  dout.writeUTF("()V")
  def sigs = getMethodSignatures(fields, className)
  sigs.each(){
    dout.writeUTF(it.name)
    dout.writeInt(Modifier.PUBLIC)
    dout.writeUTF(it.signature.replace('/', '.'))
  }
  dout.flush()
  MessageDigest md = MessageDigest.getInstance("SHA")
  byte[] hashBytes = md.digest(bout.toByteArray())
  long hash = 0
  for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
    hash = (hash << 8) | (hashBytes[i] & 0xFF)
  }
  return hash
}
  • 获取字段签名
/**
 * 获取字段的签名
 * @param fields 字段列表
 */
def getFieldsSignatures(fields){
  def sigs = []
  fields.each(){
    sigs.add([name : it.name, signature: getClassSignature(it.type)])
  }
  sigs.sort{a,b->
    return a.name.compareTo(b.name)
  }
  return sigs
}
  • 获取方法签名
/**
 * 获取方法的签名
 * @param fields 字段列表
 * @param className 类名
 */
def getMethodSignatures(fields, className){
  def sigs = []
  //toString 方法签名
  def sig = [ name : "toString", signature : "()" + getClassSignature("String")]
  sigs.add(sig)
  //每个字段 get 方法签名
  fields.each(){
    sig = [name : "get" + it.name.capitalize(), signature : "()" + getClassSignature(it.type)]
    sigs.add(sig)
  }
  //每个字段 set 方法签名
  fields.each(){
    sig = [name : "set" + it.name.capitalize(),
           signature : "(" + getClassSignature(it.type) + ")L"
                   + (packageName.substring(0, packageName.length() - 1)) + "." + className + ";"]
    sigs.add(sig)
  }
  //排序
  sigs.sort{a,b->
    int comp = a.name.compareTo(b.name)
    if (comp == 0) {
      comp = a.signature.compareTo(b.signature)
    }
    return comp
  }
  return sigs
}
  • 获取类型签名
/**
 * Returns JVM type signature for given class.
 */
String getClassSignature(String type) {
  String signature = fillTypeMapping.get(type)
  signature = signature == null ? "L" + packageName.substring(0, packageName.length() - 1) : signature
  signature = signature.replace(".", "/")
  return 'L' + signature + ";"
}

groovy 这个语言不太了解 所以用法上不是最优,可以说是强行拼凑

完整版

import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

import java.lang.reflect.Modifier
import java.lang.reflect.Proxy
import java.security.MessageDigest
import java.text.SimpleDateFormat

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */

packageName = ""
tableComment = ""
hasPrimaryKey = false
typeMapping = [
        (~/(?i)bigint/)                   : "Long",
        (~/(?i)int/)                      : "Integer",
        (~/(?i)float|double|decimal|real/): "Double",
        (~/(?i)datetime|timestamp/)       : "Timestamp",
        (~/(?i)date/)                     : "Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)bit/)                      : "Boolean",
        (~/(?i)/)                         : "String"
]
fillTypeMapping = [
        "Long" : "java/lang/Long",
        "Integer" : "java/lang/Integer",
        "Double" : "java/lang/Double",
        "Boolean" : "java/lang/Boolean",
        "String" : "java/lang/String",
        "Date" : "java/util/Date",
        "java.sql.Time" : "java/sql/Time",
        "Timestamp" : "java/sql/Timestamp"
]

//选择实体类存放路径,用于存放自动生成的文件
FILES.chooseDirectoryAndSave(unicodeToString("\\u9009\\u62e9\\u5b9e\\u4f53\\u7c7b\\u5b58\\u653e\\u8def\\u5f84")
        , unicodeToString("\\u7528\\u4e8e\\u5b58\\u653e\\u81ea\\u52a8\\u751f\\u6210\\u7684\\u6587\\u4ef6")) { dir ->
  SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
}
/**
 * 使用表对象,选择的目录构建
 * @param table 表对象
 * @param dir 目录
 */
def generate(table, dir) {
  def className = javaName(table.getName(), true)
  def fields = calcFields(table)
  packageName = getPackageName(dir)
  // 原始
//    new File(dir, className + ".java").withPrintWriter { out -> generate(out, className, fields) }
  PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(dir, className + ".java")), "UTF-8"))
  printWriter.withPrintWriter {out -> generate(out, className, fields)}
}

// 获取包所在文件夹路径
def getPackageName(dir) {
  return (dir.toString().replaceAll("\\\\", ".").replaceAll("/", ".").replaceAll("^.*src(\\.main\\.java\\.)?", "") + ";")//.substring(1)
}

/**
 * 构建并输出
 * @param out 输出流
 * @param className 类名
 * @param fields 字段列表
 */
def generate(out, className, fields) {
  out.println "package $packageName"
  out.println "import java.io.Serializable;"
  Set types = new HashSet()

  fields.each() {
    types.add(it.type)
  }
  if (types.contains("Timestamp")) {
    out.println "import java.sql.Timestamp;"
  }
  if (types.contains("Date")) {
    out.println "import java.util.Date;"
  }
  out.println "/**"
  Locale.setDefault(Locale.CHINA)
  sdf = new SimpleDateFormat()
  //由Groovy自动生成
  out.println " * ${unicodeToString('\\u7531\\u0047\\u0072\\u006f\\u006f\\u0076\\u0079\\u81ea\\u52a8\\u751f\\u6210')} "
  out.println " * <p>Date: " + sdf.format(new java.util.Date()) + ".</p>"
  out.println " * Description: $tableComment"
  out.println " * @author Mr.Wang"
  out.println " */"
  out.println "public class $className implements Serializable {"
  //输出 serialVersionUID
  outSerialVersionUID(out, fields, className)
  fields.each() {
    out.println ""
    // 输出注释
    out.println "\t/**"
    out.println "\t * ${it.comment}"
    out.println "\t */"
    out.println "\tprivate ${it.type} ${it.name};"
  }
  out.println ""
  out.println "\tpublic $className(){}"
  out.println ""
  fields.each() {
    // 输出注释
    out.println "\t/**"
    out.println "\t * ${unicodeToString('\\u83b7\\u53d6')} ${it.comment}"
    out.println "\t * @return null or ${it.name}"
    out.println "\t */"
    out.println "\tpublic ${it.type} get${it.name.capitalize()}() {"
    out.println "\t  return ${it.name};"
    out.println "\t}"
    out.println ""
    // 输出注释
    out.println "\t/**"
    out.println "\t * ${unicodeToString('\\u8bbe\\u7f6e')} ${it.comment.toString()}"
    out.println "\t * @param ${it.name} ${it.comment}"
    out.println "\t * @return " + unicodeToString("\\u5f53\\u524d\\u5bf9\\u8c61")
    out.println "\t */"
    out.println "\tpublic $className set${it.name.capitalize()}(${it.type} ${it.name}) {"
    out.println "\t  this.${it.name} = ${it.name};"
    out.println "\t  return this;"
    out.println "\t}"
    out.println ""
  }
  //输出 toString()
  outToString(out, className, fields)
  out.println "}"
}

/**
 * 输出 toString() 方法
 * @param out 输出流
 * @param className 类名
 * @param fields 字段集合
 */
def outToString(out, className, fields){
  out.println "\t@Override"
  out.println "\tpublic String toString() {"
  out.print "\t\treturn \"$className ["
  boolean firstOut = false
  fields.each(){
    if(!firstOut){
      out.println "${it.name} = \" + " + it.name
      firstOut = true
    }else out.println "\t\t + \", ${it.name} = \" + " + it.name
  }
  out.println "\t\t + \"]\";"
  out.println "\t}"
}
/**
 * 计算表中的字段 将计算出每个字段的所需的属性
 * @param table 表对象
 * @return 字段列表
 */
def calcFields(table) {
  hasPrimaryKey = DasUtil.getPrimaryKey(table) != null
  tableComment = table.getComment()
  DasUtil.getColumns(table).reduce([]) { fields, col ->
    def spec = Case.LOWER.apply(col.getDataType().getSpecification())
    def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
    fields.add([
            colName : col.getName(),
            name :  javaName(col.getName(), false),
            type : typeStr,
            comment: getComment(col.getComment()),
            isPk : DasUtil.isPrimary(col),
            isFk : DasUtil.isIndexColumn(col)
    ])
    return fields
  }
}

def javaName(str, capitalize) {
  def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
          .collect { Case.LOWER.apply(it).capitalize() }
          .join("")
          .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
  capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

def isNotEmpty(content) {
  return content != null && content.toString().trim().length() > 0
}

//获取注释
def getComment(comment){
  if (isNotEmpty(comment)) {
    return comment.toString()
  }
  return ""
}

/**
 * unicode转字符串
 * 用于 文件注释,由于 groovy 编译器不支持中文
 * @param unicode 编码为Unicode的字符串
 * @return 解码字符串
 */
def unicodeToString(String unicode) {
  StringBuffer sb = new StringBuffer()
  String[] hex = unicode.split("\\\\u")
  for (int i = 1; i < hex.length; i++) {
    int index = Integer.parseInt(hex[i], 16)
    sb.append((char) index)
  }
  return sb.toString()
}

/**
 * 输出serialVersionUID
 * @param out 输出流
 * @param fields 字段列表
 * @param className 类名
 */
def outSerialVersionUID(out, fields, className){
  out.println ""
  out.println "\tprivate static final long serialVersionUID = ${calculateSerialId(packageName, className, fields)}L;"
}

/**
 * 计算序列化ID
 * @param packageName 包名
 * @param className 类名
 * @param fields 字段列表
 * @return 序列化ID
 */
long calculateSerialId(packageName, className, fields){
  if (fields.size() == 0) return 0L
  ByteArrayOutputStream bout = new ByteArrayOutputStream()
  DataOutputStream dout = new DataOutputStream(bout)
  dout.writeUTF(packageName.substring(0, packageName.length() - 1) + "." + className)
  dout.writeInt(Modifier.PUBLIC)//classMod > public, not interface/abstract/final
  dout.writeUTF("java.io.Serializable")//interfaceName list, has only one : Serializable
  //排序
  def fieldsSigs = getFieldsSignatures(fields)
  fieldsSigs.each(){
    dout.writeUTF(it.name)
    dout.writeInt(Modifier.PRIVATE)//字段都是私有
    dout.writeUTF(it.signature)
  }
  dout.writeUTF("<init>")
  dout.writeInt(Modifier.PUBLIC)//默认只有公共的空构造
  dout.writeUTF("()V")
  def sigs = getMethodSignatures(fields, className)
  sigs.each(){
    dout.writeUTF(it.name)
    dout.writeInt(Modifier.PUBLIC)
    dout.writeUTF(it.signature.replace('/', '.'))
  }
  dout.flush()
  MessageDigest md = MessageDigest.getInstance("SHA")
  byte[] hashBytes = md.digest(bout.toByteArray())
  long hash = 0
  for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
    hash = (hash << 8) | (hashBytes[i] & 0xFF)
  }
  return hash
}

/**
 * 获取字段的签名
 * @param fields 字段列表
 */
def getFieldsSignatures(fields){
  def sigs = []
  fields.each(){
    sigs.add([name : it.name, signature: getClassSignature(it.type)])
  }
  sigs.sort{a,b->
    return a.name.compareTo(b.name)
  }
  return sigs
}

/**
 * 获取方法的签名
 * @param fields 字段列表
 * @param className 类名
 */
def getMethodSignatures(fields, className){
  def sigs = []
  //toString 方法签名
  def sig = [ name : "toString", signature : "()" + getClassSignature("String")]
  sigs.add(sig)
  //每个字段 get 方法签名
  fields.each(){
    sig = [name : "get" + it.name.capitalize(), signature : "()" + getClassSignature(it.type)]
    sigs.add(sig)
  }
  //每个字段 set 方法签名
  fields.each(){
    sig = [name : "set" + it.name.capitalize(),
           signature : "(" + getClassSignature(it.type) + ")L"
                   + (packageName.substring(0, packageName.length() - 1)) + "." + className + ";"]
    sigs.add(sig)
  }
  //排序
  sigs.sort{a,b->
    int comp = a.name.compareTo(b.name)
    if (comp == 0) {
      comp = a.signature.compareTo(b.signature)
    }
    return comp
  }
  return sigs
}

/**
 * Returns JVM type signature for given class.
 */
String getClassSignature(String type) {
  String signature = fillTypeMapping.get(type)
  signature = signature == null ? "L" + packageName.substring(0, packageName.length() - 1) : signature
  signature = signature.replace(".", "/")
  return 'L' + signature + ";"
}


  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:17:48  更:2021-08-07 12:17:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 8:30:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码